Override Symfony getter and setter generator method - php

I have to code on an existing project where the getter and setter in entity files are in Pascal Case (more commonly known as Upper Camel Case where the first letter of the first word is capitalized).
e.g. public function GetId(..., public function SetId(...
The project follows strictly Pascal Case naming style even for functions.
When the entities were generated, the getters and setters were renamed manually by the developers.
Symfony make:entity generates getters and setters in camel case.
I would like to know where the getter and setter generators are located in symfony and if it is possible to override/extend the classes in order to make them generate in pascal case so that I or another developer does not hav to update the new getters and setter to pascal case manually
Maybe it only need to be set in a config file but I am not sure

You can change the MakeEntity class code, the line that is responsible for the formation of style methods is 618 (https://github.com/symfony/maker-bundle/blob/main/src/Maker/MakeEntity.php)
Or create your own class, the only difference will be a different format of method name (https://symfony.com/bundles/SymfonyMakerBundle/current/index.html).

Related

phpspec force method-returned value

I am trying to test a class method that gets its data from another method.
So I did this :
function it_should_return_json_file_as_array()
{
$this->exist()->willReturn(true);
$this->read()->willReturn("{\"key\":\"value\"}");
$this->getContent()->shouldHaveKeyWithValue('key', 'value');
}
But when I launched phpspec run, I got this:
[InvalidArgumentException]
String "" is not a valid classname.
Please see reference document: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
What is going on?
It is not possible to stub methods of a class you are specifying, and it is not possible on purpose.
PhpSpec is trying to tell you there's a problem with the way you decided to design.
See My top ten favourite PhpSpec limitations - Limitation #2:
This limitation can become very visible in the case of using inheritance to extend behaviour. We inherit a class and want to add a new method that internally delegates some behaviour to a parent class method. We cannot mock or stub that method. This has lead me again and again to favour composition over inheritance, which is a golden principle in OO design. In the few cases in which inheritance is justified, we can isolate the reusable behaviour into a separate object and use composition in the parent object, allowing us to replace the collaborator with a double.
Also read Partial Mocking.

phpdoc for inherited method

I have class A with some method that returns bool value. I made phpdoc for that method.
I made another class B which extends class A and overrides method. New method returns string.
(I understand that in common case change the return type is not a good idea, but in my case it's a good way.)
I want to make phpdoc for new method. I could use {#inheritDoc}, but it takes full phpdoc from old method. I want to take from old phpdoc general method description and specification of arguments, but change description of return value.
How could I do it?
Based on the phpDocumentor manual for inheritance methods will inherit without the need for an inline {#inheritDoc} tag and you can override tags as you see fit.
Inheritance for methods functions similar to classes and interfaces.
When a superclass of the current class contains a method with the same
name (hence, this method is re-defined) then the following information
is inherited from that overridden method:
Summary
Description
The following tags:
author
copyright
version
param
return
throws
As with classes, each of the above will only be inherited if the
redefined method’s DocBlock does not have the element that is to be
inherited. So, for example, if the DocBlock of the redefined method
has a summary then it will not receive the overridden method’s
summary.
However from experience IDE's handle parsing this data in their own way and hence results may vary. For example, in IntelliJ/PHPStorm the parent method docs will be inherited but you can either override everything or nothing.

Mock frameworks returns class with different name and type

I'm trying to create a mock to satisfy a typehint with this code (Mockery):
return \Mockery::mock('\Contracts\Helpers\iFileSystemWrapper');
or this (PHPUnit):
return $this->getMock('\Contracts\Helpers\iFileSystemWrapper');
But the mock returned is called Mockery\Mock Object or Mock_iFileSystemWrapper_a5f91049. How am I supposed to type check this when it isn't an instance of what I need at all with either framework?
Why exactly is the mock framework trying to load the real class? If I wanted the real class I would include the real class.
This problem has slowed me down so many times when writing tests I'm about to just toss type hinting out the window and check class names instead, or simply use production objects as mocks are a pain to use.
I just experimented with an existing test of my own, and by changing the interface namespace name from one that exists to one that doesn't exist, I got exactly the same as what you describe (using phpunit). My mock object had the class name Mock_ViewInterface_c755461e. When I change it back to the correct interface name, it works fine.
Therefore I would say that either:
You are trying to use an interface name that doesn't exist (e.g. a typo or missing namespace component).
Your library code isn't being loaded for some reason, e.g. autoloading is not setup correctly in your unit test bootstrap.
You need use a special function to check base class.
Somthing like this:
$mock = $this->getMock('MyClass');
$this->assertInstanceOf('MyClass', $mock);

PHP workaround to extend classes of the same name?

I know extending a class with the same name is not possible, but I was curious if anyone knew of a way to load a class then rename it, so i can later extend it with the original name. Hopefully like something below:
<?php
//function to load and rename Class1 to Class2: does something like this exist?
load_and_rename_class('Class1', 'Class2');
//now i can extend the renamed class and use the original name:
class Class1 extends Class2{
}
?>
EDIT:
Well, I understand that this would be terrible practice in a basic OOP environment where there are large libraries of class files. But i'm using the CakePHP MVC framework and it would make great sense to be able to extend plugin classes in this way since the framework follows a well established naming convention (Model names, view names, controller names, url routes (http://site.com/users), etc).
As of now, to extend a CakePHP plugin (eg: Users plugin) you have to extend all the model, view, and controller classes each with different names by adding a prefix (like AppUsers) then do some more coding to rename the variable names, then you have to code the renamed url routes, etc. etc. to ultimately get back to a 'Users' name convention.
Since the MVC framework code is well organized it would easily make sense in the code if something like the above is able to be implemented.
I'm trying to work out why this would be necessary. I can only think of the following example:
In a context that you have no control over, an object is initialised:
// A class you can't change
class ImmutableClass {
private function __construct() {
$this->myObject = new AnotherImmutableClass();
}
}
$immutable = new ImmutableClass();
// And now you want to call a custom, currently non existing method on myObject
// Because for some reason you need the context that this instance provides
$immutable->myObject->yourCustomMethod();
And so now you want to add methods to AnotherImmutableClass without editing either Immutable class.
This is absolutely impossible.
All you can do from that context is to wrap that object in a decorator, or run a helper function, passing the object.
// Helper function
doSomethingToMyObject($immutable->myObject);
// Or decorator method
$myDecoratedObject = new objectDecorator($immutable->myObject);
$myDecoratedObject->doSomethingToMyObject();
Sorry if I got the wrong end of the stick.
For more information on decorators see this question:
how to implement a decorator in PHP?.
I happen to understand why you would want to do this, and have come up with a way to accomplish what the end goal is. For everyone else, this is an example of what the author may be dealing with...
Through out a CakePHP application you may have references to helper classes (as an example > $this->Form->input();)
Then at some point you may want to add something to that input() function, but still use the Form class name, because it is through out your application. At the same time though you don't want to rewrite the entire Form class, and instead just update small pieces of it. So given that requirement, the way to accomplish it is this...
You do have to copy the existing class out of the Cake core, but you do NOT make any changes to it, and then when ever you upgrade cake you simply make an exact copy to this new directory. (For example copy lib/Cake/View/Helper/FormHelper.php to app/View/Helper/CakeFormHelper.php)
You can then add a new file called app/View/Helper/FormHelper.php and have that FormHelper extend CakeFormHelper, ie.
App::uses('CakeFormHelper', 'View/Helper');
FormHelper extends CakeFormHelper {
// over write the individual pieces of the class here
}

Naming abstract classes

Do you think it's a good practice to differentiate abstract from non-abstract classes by giving their name a prefix or a suffix? What are the most common practices when it comes to that?
Here are a few "formats" I've been thinking about:
Foo_Base
Foo_Abstract
Abstract_Foo
Base_Foo
The use of underscores and letter case is irrelevant.
Edit: It seems like the Zend Framework uses a "Abstract" suffix (source).
Do you think it's a good practice to differentiate abstract from non-abstract classes by giving their name a prefix or a suffix?
Unless you're following some convention, I would suggest not to attach this type of meta-data to your class names. Basically it clutters the code with information available elsewhere. To me it resembles hungarian notation which is loathed by many programmers.
Here are a few "formats" I've been thinking about...
If I had to choose, I'd go with AbstractFoo.
According to these PHP Coding Standard you should really avoid _:
Class Names
Use upper case letters as word separators, lower case for the rest of a word
First character in a name is upper case
No underbars ('_')
Justification
Of all the different naming strategies many people found this one the best compromise.
Example
class NameOneTwo
class Name
Probably not with a direct reference to a (1) derived class...
In a real situation there usually is a domain-specific collective name available.
But when there isn't I usually go with something like BaseViewModel
Foo_Abstract or Abstract_Foo is a bad idea if you plan to use namespaces, as you will have Foo\Abstract, which is invalid.
I think it is bad practice to name variables/functions/classes based on the type that it represents. int myInt is good for coding a quick example (perhaps in a classroom setting) but thats about it.
abstract class AbstractClass is too redundant and annoying to read. Let your programs/code say a lot in a concise way, and speak for themselves. From reading the definition I know its an abstract class I shouldn't need to be reminded in the name of the class. Focus on what purpose the class has in reference to the problem instead of what type of class it is.
This is the gist of things I got from Clean Code
If you describe the project I can suggest good names that aren't redundant.
Why don't you actually want to specify a class to be abstract then you should use the abstract keyword in PHP
abstract class MyClass
{
//**
}
If you want a way to check for abstract classes such as logical checks then you should create an interface like so:
interface IAbstract
{
}
and then declare the class with it
abstract class MyClass implements IAbstract
{
//**
}
and then you can check like so:
if(MyClass instanceof IAbstract)
{
//Abstract
}
This way you don't need to change your class names to suit the object types.

Categories