Service Uploader Missing Argument Exception - symfony

I created an upload service to use it in different controllers in my code.
But i get an exception now like this when i want to access to the page for add a new gig :
Controller
"Booking\RoosterBundle\Controller\ArtistController::addGigAction()"
requires that you provide a value for the "$fileUploader" argument.
Why i'm getting this ? the value should be $file but i need to access to my form first and submit the file ... hope someone could help me. thanks a lot in advance
here is my service :
<?php
namespace Booking\RoosterBundle\Uploader;
use Symfony\Component\HttpFoundation\File\UploadedFile;
class FileUploader
{
private $targetDir;
public function __construct($targetDir)
{
$this->targetDir = $targetDir;
}
public function upload(UploadedFile $file)
{
$fileName = md5(uniqid()).'.'.$file->guessExtension();
$file->move($this->getTargetDir(), $fileName);
return $fileName;
}
public function getTargetDir()
{
return $this->targetDir;
}
}
Here my controller :
public function addGigAction(Request $request , $id , FileUploader $fileUploader ){
...
$gig = new Gig();
$form = $this->createForm(GigType::class, $gig);
if ($request->isMethod('POST') && $form->handleRequest($request)->isValid()) {
$file = $gig->getFlyer();
$fileName = $fileUploader->upload($file);
$gig->setFlyer($fileName);
$em->persist($gig);
$em->flush();
...
}
And here my service declaration in my bundle
booking_rooster.uploader:
class: Booking\RoosterBundle\Uploader\FileUploader
arguments:
$targetDir: '%upload_directory%'

This is not how you call a service !
Don't pass it as argument , call it like this :
$container->get('booking_rooster.uploader');

Related

Call to a member function get() on a non-object Symfony2

Hi I want to render a form in symFony2 with dynamic fields added to it.
So I have wrote code in controller as:
public function getDataAction(){
$handler = new AnotherClass();
$object = $handler->getForm($getAdditionalData);
}
and "AnotherClass" defined as following:
class AnotherClass extends Controller implements requiredInterface{
public function getForm($formData){
//Here i want to write Logic to render a dynamic form with dynamic fields
$form = $this->createFormBuilder($formData)
->setAction($this->generateUrl('me_route_go'))
// Set form field of additional data
foreach ($formData as $k => $v) {
$form->add($k, 'text');
}
//Create form and submit button
$form = $form->add('submit', 'submit')->add('Cancel', 'reset')->getForm();
$form = $form->getForm();
}
}
}
But here I am getting following error:
Error: Call to a member function get() on a non-object.
return $this->container->get('form.factory')->createBuilder($type, $data, $options);
Please suggest what could be the issue.
thanks in advance..
Your controller AnotherClass requires the Dependency Injection Container since you are extending the base Controller class, you have to set it after you instantiate it :
public function getDataAction(){
$handler = new AnotherClass();
$handler->setContainer($this->container);
$object = $handler->getForm($getAdditionalData);
}
You can also create it as a service :
services.yml
name.of.your.service:
class: Path\To\AnotherClass
calls:
- [setContainer, [ "#service_container" ]]
And then :
public function getDataAction(){
$handler = $this->get('name.of.your.service');
$object = $handler->getForm($getAdditionalData);
}

Get symfony route from controller action annotations

I have a controller action like this:
/**
* #Route("/post/delete/{id}", name="delete_post_modal")
*/
public function deleteAction(Post $post)
{
// ...
}
The annotation #Route tells symfony to execute method deleteAction when route matches delete_post_modal.
All of this works fine.
Question: Is there a way to reverse this functionality and get the route name from method name?
From the example above:
I have: PostController::deleteAction() (or self::deleteAction)
I need to get: delete_post_modal
thanks!
try this
update
$router = $this->container->get('router');
foreach ($router->getRouteCollection()->all() as $route => $params)
{
$defaults = $params->getDefaults();
if ( strpos($defaults['_controller'],'PostController::deleteAction') ) {
$myroute = $route;
break;
}
}

Doctrine2 Filter Parameter empty value twig extensions

In my application a company has their own subdomain. Im listening to kernel request event and setting the Company Filter(Doctrine Filter) parameter based on the company matching the subdomain.
public function setCompanyFilter($companyId)
{
/** #var EntityManager $entityManager */
$entityManager = $this->container->get('doctrine')->getManager();
$filters = $entityManager->getFilters();
$companyFilter = $filters->isEnabled('company_filter')
? $filters->getFilter('company_filter')
: $filters->enable('company_filter');
$companyFilter->setParameter('company', $companyId);
}
The issue im having is that on twig extensions(filter/functions) the parameter is not setted. If i set the value before execute a filter/function everything works as expected.
Is there any way to execute some code before every twig filter/function/tag? Like listening to an twig event? Or how can i solve this issue without calling the setCompanyFilter on every twig filter/function/tag.
Thanks
Why not set the custom value in the same event (i.e. kernel.request) that you are already listening to?
I assume you are using a custom twig extension. If not extend the filter/function you are already using and do the same:
<?php
// src/AppBundle/Twig/AppExtension.php
namespace AppBundle\Twig;
class AppExtension extends \Twig_Extension
{
private $customParameter;
public function getFilters()
{
return array(
new \Twig_SimpleFilter('price', array($this, 'priceFilter')),
);
}
public function priceFilter($number, $decimals = 0, $decPoint = '.', $thousandsSep = ',')
{
$price = number_format($number, $decimals, $decPoint, $thousandsSep);
$price = '$'.$price;
return $price;
}
public function getName()
{
return 'app_extension';
}
public function setCustomParameter($parameter)
{
$this->customParameter = $parameter;
}
}
Inject the twig extension into your current listener and then call the method setCustomParameter, inject your custom parameter for use later in the request lifecycle, and then just call the filter/function as your normally would in your existing twig template.

Symfony 2.3: missing _controller attribute in request object of rendered controller

I have a custom TemplatingProvider Service which I use in my controllers to output the view.
namespace Acme\FrontEndBundle\Templating;
class TemplatingProvider
{
private $templating;
private $request;
function __construct($templating, $request)
{
$this->templating = $templating;
$this->request = $request;
}
function getTemplate($name)
{
$controller = $this->request->attributes->get('_controller');
preg_match('/Controller\\\([a-zA-Z]*)Controller/', $controller, $matches);
$controller = 'AcmeFrontEndBundle:' . $matches[1] . ':';
$template = $controller . $name;
// ...
On a normal request this works fine, but not on subrequest like when I render a controller in a template with twigs render(controller(...)) function.
It seems that $this->request->attributes->get('_controller') is NULL. I understand that for _route since the controller isn't accessed through one but why is _controller not set and how can I get around that?
I know that the use of render(path(...)) in twig would solve this, but this is no option for me, I really need render(controller(...)).
Thanks in advance for any advices.
UPDATE:
Thanks to Vadim Ashikhmans answer I found the solution:
Inject `#service_container into the service and then use the container to get the request and there you have it. But with a little obstacle which i solved in a helper function:
function getController()
{
$controller = $this->container->get('request')->get('_controller');
// on mainrequest (calling the controller through its route)
// $controller follows the namespacelike schema: Vendor\Bundle\Controller\ControllerController:actionAction
preg_match('/Controller\\\([a-zA-Z]*)Controller/', $controller, $matches);
if (isset($matches[1]))
{
$controller = 'AcmeFrontEndBundle:' . $matches[1] . ':';
}
else
{
// on subrequests (e.g. render(controller(...)) in a template)
// $controller looks like Bundle:Controller:action
preg_match('/:([a-zA-Z]*):/', $controller, $matches);
$controller = 'AcmeFrontEndBundle:' . $matches[1] . ':';
}
return $controller;
}
Thanks you very much! :)
I suppose _controller attribute is empty because for every sub requests current request object is duplicated, so in subrequest TemplateProvider tries to operate on old data.
You could try to pass the container to TemplateProvider constructor and retrieve request object in getTemplate method.

Symfony2 access Doctrine Entity Manager in custom class

UPDATE:
In case you need to work with Entity Manager in a custom class, you could go this way:
put this code in your bundle:
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\HttpFoundation\Request;
require_once DIR . '/../../../app/bootstrap.php.cache';
require_once DIR . '/../../../app/AppKernel.php';
class ApplicationBoot {
private static $kernel;
public static function getContainer() {
if(self::$kernel instanceof \AppKernel) {
if(!self::$kernel->getContainer() instanceof Container){
self::$kernel->boot();
}
return self::$kernel->getContainer();
}
$environment = 'prod';
if (!array_key_exists('REMOTE_ADDR', $_SERVER) || in_array(#$_SERVER['REMOTE_ADDR'], array('127.0.0.1', '::1', 'localhost'))) {
$environment = 'dev';
}
self::$kernel = new \AppKernel($environment, false);
self::$kernel->boot();
return self::$kernel->getContainer();
}
public static function shutDown() {
self::$kernel->shutdown();
}}
So now you can access EntityManager:
$container = ApplicationBoot::getContainer();
$entityManager = $container->get('doctrine')->getEntityManager();
I have not seen a service file like this:
arguments:
entityManager: "#doctrine.orm.entity_manager"
Probably should be:
arguments: [#doctrine.orm.entity_manager]
UPDATE:
Based on some comments it appears that you are trying to do:
$job = new PostJob();
And expecting that entity manager will somehow be passed. And that is just not the way things work. You need to do:
$job = $this->get('postjob.service.id');
In order to have the Symfony 2 dependency injection work. Review the chapter in the manual on services. It might seem a bit over whelming at first but once you get a few services working then it becomes second nature.
To load the services.yml from your bundle, you need to provide an extension class:
// src/Vendor/YourBundle/DedendencyInjection/VendorYourBundleExtension.php
namespace Vendor\YourBundle\DependencyInjection;
use Symfony\Component\HttpKernel\DependencyInjection\Extension,
Symfony\Component\DependencyInjection\ContainerBuilder,
Symfony\Component\DependencyInjection\Loader\YamlFileLoader,
Symfony\Component\Config\FileLocator;
class VendorYourBundleExtension extends Extension
{
public function load(array $configs, ContainerBuilder $container)
{
$loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');
}
}

Resources