Getting the current logged user in Symfony ParamConverter annotation expression? - symfony

Symfony ParamConverter allow to pass an expression which uses the expression language feature:
/**
* #ParamConverter("order", class=Order::class, options={
* "expr": "repository.findByUser(user)"
* })
*/
public function getOneAction()
{
}
However, this wil throw an error about the user variable not being available:
Error parsing expression -- "repository.findByUser(user)" -- (Variable "user" is not valid around position 23 for expression repository.findByUser(user).).
Does anyone knows how to access it?

Related

Symfony 2 - could not able to insert json_array type variable

json_array type variable is not able to include to the database. The populated exception is as follow
(Symfony\Component\Debug\Exception\ContextErrorException(code: 0): Warning: implode(): Invalid arguments passed at /var/www/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/SimpleArrayType.php:51)"}
My entity class has this part for json_array type paramter.
/**
*
* #ORM\Column(name="street", type="json_array")
*/
private $street;
also I include to the db using entity manager.
$entityName->setStreet(
array(
'street_1' => $queueItem->street_1,
'street_2' => $queueItem->street_2));
if($this->em->getUnitOfWork()->getEntityState($entityName)) {
$this->em->flush();
}
I think you should use type="text" or a own entity for multiple streets
http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/types.html#text
Because:
type="json_array" is deprecated use type="json" http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/types.html#json-array
this type want a string that could be encoded, not an array

Consistency in arg routes in symfony2

I'm a beginner in Symfony2 and I'm just wondering if the consistency of args has to be done myself in the controller or if there is a mechanism i don't know of
let's take a example:
i have a route like /company/id/user/id to display some information for the user
i have tried manually to change id for either company or user and there is no error if the user is not from the company ?!
Do i have to check in the controller displayUserAction if user and company are bound ?
/**
* #Route("/company/{company_id}/user/{site_id}")
* #ParamConverter("company", class="MyModel\Company", options={"mapping": {"company_id": "id"}})
* #ParamConverter("site", class="MyModel\User", options={"mapping": {"site_id": "id"}})
*/
public function displayUserAction(Company $company, User $user)
{
..
}
routing.yml
user_info:
path: /company/{company_id}/user/{site_id}
defaults: { _controller: UserBundle:Default:displayUser }
Edit:
I've found another way : map using several criteria
/**
* #Route("/company/{company_id}/user/{site_id}")
* #ParamConverter("company", class="MyModel\Company", options={"mapping": {"company_id": "id"}})
* #ParamConverter("site", class="MyModel\User", options={"mapping": {"site_id": "id", "company_id":"company"}})
*/
public function displayUserAction(Company $company, User $user)
{
..
}
You can re-order the arguments in the Action all you like. Symfony is smart enough to match the arguments - but you should keep the naming somewhat consistent - which you have done anyway. Symfony will match {company_id} in your route to $company in your Action for example no matter the order you place them in.
In your route, both arguments are required for the route to match. So the route will only match work if both arguments are bound.
In your Action, you would need to check the User belongs to the Company. The architecture of the Route and the Action don't care if the 2 entities are related, they only care that a value has been supplied.

Symfony2 JMSSecurityBundle #secure pass object obtained with #ParamConverter

Is possible pass a object obtained with paramconvert in #secure annotation ?
This is my code:
/**
* #ParamConverter("construction", class="CliConsCoreBundle:Construction", options={"repository_method" = "findWithJoins"})
* #Secure(roles="ROLE_EXTRANET", options={"construction"})
* #Template
*/
public function showAction(Request $request, Construction $construction)
{ ... }
I want have $construction in security voter, is possible?
If I do without annotations then works.
Thanks
The #Secure annotation receives an array of strings that represents the roles that the active user has to have for the controller to be executed.
What do you exactly want to do? I can't understand the intention of your code

Getting multiple rows using ParamConverter

Hi Im trying to use ParamConverter to get multiple rows from DB but profiler show query with limi 1. Is it possible to get it like that
/**
* #Route("/localization/{code}", name="pkt-index")
* #ParamConverter("localizations", class="PriceBundle:Localization")
*/
after entering localization/0003 I should get more than 100 rows.
EDIT:
I have used repository_method option
and
/*
* #Route("/localization/{id}", name="pkt-index")
* #ParamConverter("localizations", class="PriceBundle:Localization", options={
* "repository_method": "getByLocalizationCode"
* })
*/
but funny thing is that when I change {id} in route it does not work it throws and exception
SQLSTATE[HY093]: Invalid parameter number: parameter was not defined
even if variable exists in entity class, if variable dont exist it throws
Unable to guess how to get a Doctrine instance from the request information.
EXPLANATION
when I change {id} in route it does not work it throws and exception
SQLSTATE[HY093]: Invalid parameter number: parameter was not defined
Here I think symfony treads id like primary key and as parameter to repository method it pass string when I changed this id to something else it pass array
Example
/**
* #Route("/localization/{id}", name="pkt-index")
*/
pass string to method
/**
* #Route("/localization/{code}/{name}", name="pkt-index")
*/
pass array to method
array(
'code' => 003
'name' => localization_name
)
and last
/**
* #Route("/localization/{id}/{name}", name="pkt-index")
*/
will pass string id omit the name
Hope this sounds reasonable.
forgottenbas's answer isn't completely right. #ParamConverter will first try to find one entity by id ...
... then try to match the route variables against db columns to find an entity ...
but essentially it will only convert one entity at a time.
If you would still like to use a paramconverter you would need to write a custom one.
or just use a one-liner inside your controller action:
/**
* #Route("/localization/{code}", name="pkt-index")
*/
public function yourAction($code)
{
$localizations = $this->getDoctrine()->getRepository("YourBundle:Localization")->findBy(array("code" => $code));
// ...
ParamConverter currently can only extract id from request and find one entity from db. Look at
DoctrineParamConverter code. But you can specify your own param converter with some extra logic.

Using convention over configuration in Symfony2 controllers/views

I have the following Symfony controller:
/**
* Says thanks to the user for signing up.
*
* #Route("/thanks", name="user")
* #Template()
*/
public function thanksAction()
{
return $this->render('VNNPressboxBundle:User:thanks.html.twig');
}
If I don't include the return statement, I get an error saying the controller must return a response. It's interesting that I have to manually specify which template my action needs to use, considering Symfony could easily figure that out based on my controller and action. Plus that's how Symfony 1.x worked.
I have to imagine that I'm missing something. It doesn't seem like they would apply the convention over configuration concept in Symfony 1.x and then abandon it in Symfony >= 2.0.
Is it possible to tell Symfony to figure out which template to use based on my controller and action, and if so, how?
You have to return something. You're using #Template annotation so you don't have to render the response but you still have to return an array of parameters for the template (in your case empty):
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
/**
* Says thanks to the user for signing up.
*
* #Route("/thanks", name="user")
* #Template()
*/
public function thanksAction()
{
return array();
}
Read more on #Template annotation in the docs: http://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/view.html
P.S. Don't compare symfony 1.x to Symfony 2.x. These are two different frameworks. Symfony 2 favors being explicit over magic.
Return an array. In your case it'll be an empty array, but normally you would fill it with variables you want to pass to a template.

Resources