What does the #param keyword do in symfony routes - php

In annotations for a route what does #param mean?
I can not find any documentation on symfony website regarding this keyword and very confused as to what it's for and does.
I'm asking because I'm trying to figure out how to access parameters in my .yml files for use in the routes but I'd like to still use annotations instead of the YML method of routing.
Showing a code example is probably not the best for this but here is where #param shows up
/**
* League action
*
* #Route("/association/{assoc}/{league}", name="league", requirements={"league" = "\d+"}, defaults={"game" = null})
* #Route("/association/{assoc}/{league}/{game}")
* #Template()
*
* #param $assoc
* #param $league
* #param $game
* #return array
*/
I took that from here (Symfony2 route in annotations with optional parameters)
Any help is appreciated, thanks!

#param and #return are phpDocumentor annotations, and do not actually affect routing.

Related

Laravel vs Symfony | Model Attributes

I'm actually discovering Laravel (I've used symfony for years) and I face a situation where I don't know if I just couldn't find the right information or it is just the way to do in Laravel.
When creating a model in Symfony you put attributes in your model class. Actually these attributes represent the different columns of your table for the ORM.
Now in Laravel I see all people don't put theses attributes in the model class but in the migrations files. So a new developer who should contribute in a new project will have to look on database or migrations files. Which in my opinion is not the rule of an ORM : "let dev think class and not table"
Could somebody, please, put a light on this point?
Thanks
If you use PHPStorm (but it can work with other IDEs as well) there is an interesting composer package that can generate model documentation for you, in order to have autocompletion for attributes ad methods based on your migrations:
https://github.com/barryvdh/laravel-ide-helper
its three main methods:
php artisan ide-helper:generate creates phpDoc for Facades
php artisan ide-helper:model creates phpDoc for your model (you should relaunch it after every new migration)
php artisan ide-helper:meta creates phpstorm meta file
so, if you launch php artisan ide-helper:model it will add something similar to this
/**
* App\User
*
* #property-read \Illuminate\Database\Eloquent\Collection|\Spatie\Permission\Models\Permission[] $permissions
* #property-read \Illuminate\Database\Eloquent\Collection|\Spatie\Permission\Models\Role[] $roles
* #method static \Illuminate\Database\Eloquent\Builder|\App\User permission($permissions)
* #method static \Illuminate\Database\Eloquent\Builder|\App\User role($roles, $guard = null)
* #property int $id
* #property string $name
* #property string $email
* #property \Illuminate\Support\Carbon|null $email_verified_at
* #property string $password
* #property string|null $remember_token
* #property \Illuminate\Support\Carbon|null $created_at
* #property \Illuminate\Support\Carbon|null $updated_at
* #method static \Illuminate\Database\Eloquent\Builder|\App\User whereCreatedAt($value)
* #method static \Illuminate\Database\Eloquent\Builder|\App\User whereEmail($value)
* #method static \Illuminate\Database\Eloquent\Builder|\App\User whereEmailVerifiedAt($value)
* #method static \Illuminate\Database\Eloquent\Builder|\App\User whereId($value)
* #method static \Illuminate\Database\Eloquent\Builder|\App\User whereName($value)
* #method static \Illuminate\Database\Eloquent\Builder|\App\User wherePassword($value)
* #method static \Illuminate\Database\Eloquent\Builder|\App\User whereRememberToken($value)
* #method static \Illuminate\Database\Eloquent\Builder|\App\User whereUpdatedAt($value)
* [...]
*/
So you have a phpDoc
and your IDE should be able to autocomplete your code like this:

PHPDoc to assign #param as a referened #property

I'm trying to define a param for a method as being the ID field from another class. Basically this idea...
/**
* #param \Database\Member::id $memberId
* #return MemberEntity
*/
public function getMember( int $memberId ) : MemberEntity
{
...
}
the #see command doesn't seem to be the right solution for this. Is there something I'm missing here? The PHPDoc website is surprisingly minimal...
thanks!
The #param tag receives the values: type, name and description. Apparently the type of your variable is int. If the \Database\Member::id attribute is not a native type of php or a class, it can not be used that way. So it is not possible to do this type of reference you want in traditional PHPDoc.
Syntax
#param [Type] [name] [<description>]

How to use class constants in #Security annotation using the Symfony Expression Language?

I am using Symfony 3 and I've created a custom Voter class.
I want to access it using the SensioFrameworkExtraBundle #Security tag.
It kind of works.
If I do the following it works perfectly:
/**
* #Rest\Get("organisation/{id}")
* #Security("is_granted('OrgAdmin', id)")
* #param int $id
* #param Request $request
*
* #return View
*/
public function getOrganisationAction($id, Request $request)
{
But I don't like the idea of using magic strings in the application and I would much rather use a class constant for the check.
Something like this:
/**
* #Rest\Get("organisation/{id}")
* #Security("is_granted(AppBundle\OrgRoles::ROLE_ADMIN, id)")
* #param int $id
* #param Request $request
*
* #return View
*/
public function getOrganisationAction($id, Request $request)
{
But when I try that I get the following error message:
Unexpected character \"\\\" around position 20 for expression `is_granted(AppBundle\\OrgRoles::ROLE_ADMIN, id)`.
Which when unescaped, is the following:
Unexpected character "\" around position 20 for expression `is_granted(AppBundle\OrgRoles::ROLE_ADMIN, id)`.
So I'm stumped on this.
Can it be done?
Any suggestions on a better way to do this?
You can use the constant() function available in the Expression Language Component:
#Security("is_granted(constant('\\Full\\Namespace\\To\\OrgRoles::ROLE_ADMIN'), id)")
Doctrine annotation reader has made this even easier for constants in PHP code:
use MyCompany\Annotations\Bar;
use MyCompany\Entity\SomeClass;
/**
* #Foo(PHP_EOL)
* #Bar(Bar::FOO)
*/
This also works just as expected for #Security / #IsGranted.
https://www.doctrine-project.org/projects/doctrine-annotations/en/latest/custom.html#constants

Suggestions for order of annotations in PHP

I currently use such order of annotations:
Code 1:
/**
* sets elements for main (top), secondary (sub1) level and tertiary (sub2) level;
* prevents sharing of content with previous instances
*
* #param string $TopElement
* #param string $SubElement1
* #param string $SubElement2
*
* #return void
*
* #throws MarC_Exception if top element was not set
* #throws MarC_Exception if sub1 element was not set
* #throws MarC_Exception if sub2 element was not set
* #throws MarC_Exception if all elements were set the same
*/
public function __construct($TopElement="", $SubElement1="", $SubElement2="")
{
...
}
Code 2:
/**
* elements used for creation of code
*
* #static
* #var array
*/
protected $Elements = array();
Code 3:
/**
* #package ...
*
* #author ...
* #copyright ...
*
* #license ...
*
* generation of advanced select menu
*/
At this time i don't use all annotations (probably all I use you can see in codes above).
And I wonder if in php is any suggested (preffered) order of annotations - or it is free matter of programmer (and then this question will be useless).
TLDR; It's a free matter
PHP coding standards differ on this. The best I can suggest is to pick a coding standard you like and run PHP CodeSniffer (https://github.com/squizlabs/PHP_CodeSniffer) against it and see what it suggest. Some coding standards require they be in a specific order and a specific spacing to your docblock annotations. Others are more relaxed and make no suggestions about docblock annotations what-so-ever.
To get PHP Code Sniffer:
$ curl -OL https://squizlabs.github.io/PHP_CodeSniffer/phpcs.phar
$ php phpcs.phar -h
$ php phpcs.phar --standard=[STANDARD_CHOICE] /path/to/project
Some coding standards you might want to consider:
http://www.php-fig.org/psr/psr-2/
http://framework.zend.com/manual/1.12/en/coding-standard.coding-style.html
http://pear.php.net/manual/en/rfc.header-comments.php
If you're worried about a document generators (like phpDocumentor) not being able to parse the docblock annotations, you can always check what annotations they support. I've never had a problem with phpDocumentor complaining about the ordering or formatting though.
As for custom annotations being used by libraries such as Doctrine, Symfony and PHPUnit, I've also never noticed the order having an impact on the parsing and processing.

Cache variable in controller in Symfony2

Is it possible to store data in one private variable of a controller (Symfony2)?
One example:
/**
* Class CatsController
*
* #Route("cats")
* #Cache(expires="+600 seconds", public=true)
* #package oTeuGato\AppBundle\Controller
*/
class CatsController extends Controller {
/**
* #var $advertisements Advertisement[]
*/
private $advertisements;
/**
* Index advertisements page
*
* #Route("", name="oTeuGato_Cats")
* #Method("GET")
* #return Response
*/
public function indexAction()
{
$this->advertisements = ....(Use a service for gets advertisements)
}
/**
* Index advertisements by page
*
* #Route("/{id}", requirements={"id" = "\d+"}, defaults={"id" = 1}, name="oTeuGato_Cats_ByPage")
* #Method("GET")
* #return Response
*/
public function indexByPageAction(){
....
}
In this example whenever someone calls the URL: cats/1 in the controller I need them to have all advertisements of the previously called method (/cats).
Is this possible?
Note:
I enabled the cache in the app.php file and app_dev.php.
Thanks for help and sorry for my English ;)
Symfony doesn't provide a mechanism for what you are describing. But any solution that would work for PHP more generally, will work for Symfony.
It depends if you want to remember advertisements for each user or for all users. If you want to remember it for each user, use sessions as Gareth Parker suggested. If you want to remember it for all users, then you would need APC user caching, memcache or another memory-based key-value store.
You may also have luck using Doctrine result cache. See http://doctrine-orm.readthedocs.org/en/latest/reference/caching.html
No, it's not. Not like that, anyway. What you want is to use sessions instead. Sessions are what you use to store variables between requests. Here are some examples

Categories