So, the goal is to make the custom annotation that could also insert the parameter into a method. So after hours of looking for a solution and trying to make it work, I never found a complete one, so I put together a few of what i could found, and my code looks like this:
public function onKernelController(FilterControllerEvent $event)
{
if (!is_array($controller = $event->getController())){
return;
}
$request = $event->getRequest();
$content = $request->getContent();
$data = json_decode($content,true);
$reflectionObject = new \ReflectionObject($controller[0]);
$reflectionMethod = $reflectionObject->getMethod($controller[1]);
$methodAnnotation = $this->reader->getMethodAnnotation($reflectionMethod, CheckRequest::class);
if(!$methodAnnotation){
return;
}
$propertyName = $methodAnnotation->getName();
try{
if ($request->getContentType() !== 'json' ) {
throw new ControlerNotAvailableException();
}
if(empty($content)){
throw new ControlerNotAvailableException();
}
if(empty($data) || !array_key_exists('type', $data)) {
throw new ControlerNotAvailableException();
}
}catch(ControlerNotAvailableException $e){
}
foreach($reflectionMethod->getParameters() as $param){
if($param->getName() !== $propertyName){
continue;
}
if($request->attributes->has($propertyName)){
return;
}
$request->attributes->set($propertyName, $data);
}
}
And my annotation class looks like this:
class CheckRequest
{
private $name;
public function __construct($options)
{
if(isset($options['value'])){
$options['name'] = $options['value'];
unset($options['value']);
}
foreach ($options as $key => $value){
if(!property_exists($this, $key)){
throw new \InvalidArgumentException(sprintf('Property %s does not exist', $key));
}
$this->$key = $value;
}
}
/**
* @return mixed
*/
public function getName()
{
return $this->name;
}
/**
* @param mixed $name
*/
public function setName($name)
{
$this->name = $name;
}
}
So to make this thing little more clear. I have a listener event which listens to kernel.controller event. In that listener i'm running some small chacks, like if the content-type is json, etc...Also, ControllerNotAvailableEception is the custom exception i made, so don't let that confuse you. We then get to the part where my question lies, and that is the following:
foreach($reflectionMethod->getParameters() as $param){
if($param->getName() !== $propertyName){
continue;
}
if($request->attributes->has($propertyName)){
return;
}
$request->attributes->set($propertyName, $data);
}
Now, just to clarify things, this works, and injects the value in method parameters properly, so in my controller if i put something like this:
/**
*@CheckRequest(name = "data")
*/
public function createAction(array $data){
}
This works, and the $data parameter is populated.
Finally when i explained all this, i can now ask my question.
Is this the right way to do this, or are there some 'standardized' way of injecting the parameters value through annotations and could you give me the example? I know that the @ParamConverter annotation does theese kind of things, but i couldn't figure out how it binds value to parameter under the hood.
Thank you in advance for your answers!