symfony2 phpStorm autocomplete code, comments, best practices - symfony

i may have little be too general questions and if there are i am sorry for duplicates. (did not found the answer i was looking for).
First of all i am using symfony2 framework for developing and i am thinking about purchasing phpStorm. Its not a cheap program and i dont want to waste money. But i like it to now so i would like to ask if its a good step to future?
And my second and the main question
Sometimes happens i dont see auto-completed suggestions of methods of some objects...
Is there any way or some good practises i can do to help phpStorm understand with what object i am dealing with?
I have on my mind things like i saw in the code of someone else:
public function updateSomething(User $user
Or...
/**
* Draws an arc on a starting at a given x, y coordinates under a given
* start and end angles
*
* #param Imagine\Image\PointInterface $center
* #param Imagine\Image\BoxInterface $size
* #param integer $start
* #param integer $end
* #param Imagine\Image\Color $color
* #param integer $thickness
*
* #throws Imagine\Exception\RuntimeException
*
* #return DrawerInterface
*/
Do these things help and I should write them or there are just for better "user-read ability"?

Your first question is of a type that normally belongs outside of StackOverflow as its very subjective, there isn't really an answer, only people's opinions. For what it's worth, in my opinion PHPStorm is worth every penny compared to either a) using no IDE / a text editor, b) using the free Aptana IDE (eclipse based) which are the alternatives I tried before PHPStorm. For me there there are numerous productivity savings but one invaluable feature is the debugger which just works (once you have XDebug configured with PHP).
To answer your second question about the auto-completion of methods of some objects - Yes, both the examples you gave help and those along with additional use of PHPDoc comments should enable the PHPStorm method auto-completion to work in almost all cases. This should also have the side-effect of clearing out most of the spurious PHPStorm yellow highlights of undefined method calls so that genuine errors are more visible.
The least you can do to maximise method auto-completion:
1. Always provide type hints for method parameters where possible / appropriate - see PHP Type Hinting for more details e.g.
public function createUser (UserDetails $userDetails, array $roles)
2. Always give methods that have a return value PHPDoc comments (beginning /**) which at least define the #return type for the method (if not mixed) and the content type of any array parameters (if not mixed). e.g.
/**
* #param UserDetails $userDetails
* #param Role[] $roles
* #return User
*/
3. Use PHPDoc comments with #var to define the type of class member variables and local variables e.g.
class UserManager
{
/**
* #var EntityManager
*/
private $entityManager
...
public function doSomething()
{
...
/** #var User $user */
foreach($users as $user)
{
...
}
...
It is good practice generally to use PHP type hinting and to make appropriate use of PHPDoc.

Related

Doctrine: Allow extending STI entities from within 3rd party code

Background
I've got an entity A with single table inheritance set up and class Foo extending it like so:
/**
* #ORM\Entity()
* #ORM\InheritanceType("SINGLE_TABLE")
* #ORM\DiscriminatorColumn(name="type", type="string")
* #ORM\DiscriminatorMap(
* "foo" = Foo
* )
*/
abstract class A
{
// ...
}
/**
* #ORM\Entity()
*/
class Foo extends A
{
// ...
}
This works with no problems. However, I need to be able to let 3rd party code extend A as well. Problem: I don't know the discriminator mappings that would be needed to wire this up beforehand as this is a property of the base class.
My current solution
I'm in Symfony land, so I can make use of the dependency injection container and decorate the annotation_reader* (that processes the discriminator map class annotations) with my own one.
This reader delegates most of the calls to the original one but can extend found discriminator map annotations. It does so based on an 'extension registry' which itself is filled by a compiler pass looking for a special service tag. Anyone wanting to extend the core entity A with Bar can now tag Bar with this service tag (that also includes the identifier for the mapping; the column type in this example).
*) this will probably also work within the loadClassMetadata event - which would be preferable instead of decorating the reader
/**
* #ORM\Entity()
* #DiscriminatorMapExtension("bar")
*/
class Bar extends A
{
// ...
}
(I'm using service annotations in the above example to be able to write the tags directly beneath the entity annotation. But how exactly the classes will be registered in the end doesn't matter right now. I'm more interested in the general concept.)
So if it's working, what's the problem?
I'd really love to hear some feedback from experienced Doctrine devs on this approach, especially:
Is there a better way to achieve a 'shared entity' across bundles?
Why could this pattern be a problem?
Thanks a lot in advance!

Symfony2: How to have a form for an entity but with field not the same has properties

I have a Duo entity containing two persons. During the creation, the creator submits the email address partner and decides whether he is the captain or not of the new Duo. If he decides that he isn't (he choose the be the assistant) then, automatically, the second person is assigned captain. My Duo entity is as follows:
/**
* #ORM\Table()
* #ORM\Entity()
*/
class Duo{
/**
* #Assert\NotNull()
* #ORM\OneToOne(targetEntity="User")
* #ORM\JoinColumn(name="captain_id", referencedColumnName="id")
*/
private $captain;
/**
* #Assert\NotNull()
* #ORM\OneToOne(targetEntity="User")
* #ORM\JoinColumn(name="assistant_id", referencedColumnName="id")
*/
private $assistant;
I wonder how to organize my form so that there is only an email address that is submitted designating the partner. When I call $form->isValid(), I want my Duo entity to be valid. I do not want to use a form without entity because I do not want to have to assign data manually and handle errors outside of the form. Also, I would like to verify if one of the two users aren't involved in another Duo. If yes, how to pass the error message to the form in a clean way.
What should I do? Is there a way to do it using the Form Callbacks or Event or something like that?
Data transfers can do everything you want:
http://symfony.com/doc/current/cookbook/form/data_transformers.html
I suggest reading this very carefully, because it got very confusing the first time I did. There is a perfect example here that explains how to build issue id to Issue, basically same is your case.
As for the errors, I think your best option is to use Callback in combination with form constraints attribute:
http://knpuniversity.com/screencast/question-answer-day/custom-validation-property-path#creating-a-proper-custom-validation-constraint
You should probably read the whole article as there is not only "proper" way but "quick and dirty" as well.
Hope this helps.

How to auto complete methods from Symfony 2 DI in netbeans

I am starting to develop with symfony 2 and it uses a lot dependency injection. I would like to know if is there any way that makes netbeans detect the type of object based on the string and auto complete with their methods?
For example, $this->container->get('doctrine') returns a Doctrine\Bundle\DoctrineBundle\Registry instance. In the container, the key doctrine corresponds to Doctrine\Bundle\DoctrineBundle\Registry.
Something like it, could be useful for zendframework 2 also.
I don't want to create new methods in the controller and nor use /* #var $var Symfony...*/, I would automatic detection.
As far as I know, there's no way for an IDE to detect the type of the object your container returns. My solution is to wrap those calls to the container into private getter functions. IMHO this improves code readability as well – especially, if you do this call more than once per class.
/**
* #return \Doctrine\Bundle\DoctrineBundle\Registry
*/
private function getDoctrine()
{
return $this->container->get('doctrine');
}
The IDE "PhpStorm" permits to suggest "use" declarations.
And this IDE propose specific features for Symfony2 and Drupal !
edited by JetBrains : http://www.jetbrains.com/phpstorm/
Not free but power full enough to reduce time developpement time (and time is money...)
Enjoy : )
phpStorm:
$foobar= $this->get('foobar'); //returns mixed
/* #var \MyNamespace\FooBar $foobar*/
or
$foobar= $this->get('foobar'); //returns mixed
/* #var FooBar $foobar*/
You can do this with eclipse PDT:
$foobar= $this->get('foobar'); //returns mixed
/* #var $foobar \MyNamespace\FooBar*/
( Walk around ) When comes to Symfony services:
Instead of
$doctrine = $this->container->get('doctrine');
use
$doctrine = $this->getDoctrine();
As you can see, Symfony allows you to access most of it services directly from $this variable. NetBeans will know what auto completion to use.
Lets have a look why this works (inside Controller class)
It is possible because Controller class imports Registry class with USE statement,
use Doctrine\Bundle\DoctrineBundle\Registry;
and then in method comment annotation it declares the returning object type with
/*
* #return Registry
*/
If you call $this->container->get('doctrine'); directly then auto completion will be get omitted and you will have to use whats below.
( Answer ) No magic auto completion works so far. Use Php Storm (it does what you request). For those who pick to stick with NetBeans you need to use manual annotation like in example below:
We can point NetBeans to a class it should be using for auto completion.
1) In terminal from project directory search for service you want to import:
php bin/console debug:container
If you know what you looking for use this instead:
php bin/console d:container | grep doctrine
...
doctrine --------------------------------------------------------
Doctrine\Bundle\DoctrineBundle\Registry
...
2) If this is not a service use get_class() PHP build in function to get class name of the object it particular variable. Or use reflection class. It's up to you.
3) Once you know the class name declare USE statement for better readability
use Doctrine\Bundle\DoctrineBundle\Registry;
4) Now wen we know what is the class name of the object instance in particular variable we are ready to inform NetBeans about what we know by using comment annotations so that it can enable auto completion.
/**
* #var $doctrine Registry
*/
$doctrine = $this->container->get('doctrine');
Now auto completion is enabled. Type
$doctrine->|
then press Ctrl+Space. See the image below:

Generating getters and setters in Doctrine without comments

I'm using Symfony2 and Doctrine, so to create getters and setters methods I do:
php app/console doctrine:generate:entities org/StoreBundle/Entity/Product
That works fine, but I would like to generate the getters and setters without comments. I think they are too obvious and redundant, for example:
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
Five lines !
Is there any option to do that?
Looking at the source for the Doctrine GenerateEntitiesCommand, it doesn't look like there is any way to do that: https://github.com/doctrine/DoctrineBundle/blob/master/Command/GenerateEntitiesDoctrineCommand.php
However, why would you want to remove the comments? It's not like there is a line limit in PHP, and it is barely a blip on your compiling in terms of a performance hit for comments (the different is so small, there is no way you could actually measure it on your computer).
Also, if you use PHPDoc to generate documentation for your code, that #return string is more useful than you might thing, because you'd then know the return types for each of your getters (which isn't always very obvious).
You may generate getter/setter using Netbeans IDE instead of Doctrine command line.

What purpose does #param annotation does in symfony2 class file

In the symfony2 and doctrine 2. I have this
/**
* Find a user by its username.
*
* #param string $username
* #return UserInterface or null if user does not exist
*/
function findUserByUsername($username);
Now i want to know that does it solve nay purpose or does it do anything in database with those #param and #return annotation or they just for documentation
#param is explained in the phpDocumentor docs. It has nothing to do with Symfony2.
The link is outdated.
Here is a link to a good address at this present moment.
https://www.phpdoc.org/docs/latest/references/phpdoc/tags/param.html
Below, the first lines of the explanation in any case...
The #param tag is used to document a single argument of a function or method.
With the #param tag it is possible to document the type and function of a single argument of a function or method. When provided it MUST contain a Type to indicate what is expected; the description on the other hand is OPTIONAL yet RECOMMENDED in case of complicated structures, such as associative arrays.

Resources