The controller for URI is not callable symfony2 - php

i get this error
[enter image description here][1]
i have in my project 2 bundles the first one is working just fine the seconde is called DemandeBundle i get the error
namespace DemandeBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
class DefaultController extends Controller
{
/**
* #return \Symfony\Component\HttpFoundation\Response
* #route("/homedemande",name="homedemande")
*/
public function indexAction()
{
return $this->render('#DemandeBundle/Default/index.html.twig');
}
/**
* #return \Symfony\Component\HttpFoundation\Response
* #route("/demande_create",name="demande_create")
*/
public function demande_create()
{
return $this->render('#DemandeBundle/Default/demande_create.html.twig');
}
}
i suspect i have a problem in routing.yml
demande_create:
path: /demande_create
defaults: { _controller: DemandeBundle:Default:demande_create}

your action needs to be suffixed with Action keyword to be callable that is probably the first issue here
function definition should be something like
public function demande_createAction()

Related

How to extend Symfony\Component\HttpFoundation\Request

How to extend Symfony\Component\HttpFoundation\Request and create my own Request correctly?
I tried to create my own request:
class ChangeRequest extends Request
But, when I used it as argument in controller action, I get an error
Argument #1 ($request) must be of type App\Request\ChangeRequest, Symfony\Component\HttpFoundation\Request given
I want to create several requests extends Symfony\Component\HttpFoundation\Request, and use this requests in different controller actions. Every request contains JSON data and has its own validate rules. Now I use ArgumentValueResolverInterface for resolving this requests.
class RequestResolver implements ArgumentValueResolverInterface
{
/**
* #inheritDoc
*/
public function supports(Request $request, ArgumentMetadata $argument): bool
{
$type = $argument->getType();
return class_exists($type) && str_starts_with($type, 'App\Request');
}
/**
* #inheritDoc
*/
public function resolve(Request $request, ArgumentMetadata $argument)
{
yield new ($argument->getType())($request);
}
}
After that I edited services.yaml and the error disappeared:
App\Resolver\RequestResolver:
tags:
- { name: controller.argument_value_resolver, priority: 50 }
Is this the right way?

How to access current placeholder value?

Symfony 3.4.
I have annotations for my controller:
/**
*
* #Route("/{prefix}", requirements={"prefix":"daily_task|event"})
*/
class TaskController extends Controller
and want to access current {prefix} value directly from controller's methods (which aren't routed actions). How to get it's value?
Finally: $this->get('request_stack')->getCurrentRequest()->get('prefix')
Symfony will pass you the variables automatically if you use them as function parameters, like this:
/**
*
* #Route("/{prefix}", requirements={"prefix":"daily_task|event"})
*/
class TaskController extends Controller {
/**
* #Route("/{_locale}/some/path", name="_some_route_name")
*/
public function actualAction($prefix, $_locale) { /* ... */ }
}
Alternatively you can use the whole request like this:
/**
*
* #Route("/{prefix}", requirements={"prefix":"daily_task|event"})
*/
class TaskController extends Controller {
/**
* #Route("/{_locale}/some/path", name="_some_route_name")
*/
public function actualAction(Request $request) {
$prefix = $request->get('prefix');
}
}

Unable to find template in Symfony 3

I know that there are a lot of subject like that however I didn't find the solution
I have this issue
Unable to find template "CoreBundle:index.html.twig" (looked into: /var/www/html/MyProject/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Resources/views/Form).
This is the architecture
This is my controller
<?php
namespace CoreBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
class DefaultController extends Controller
{
/**
* #Route("/", name="index")
*/
public function indexAction(Request $request)
{
return $this->render('CoreBundle:index.html.twig');
}
/**
* #Route("/ma-personnalite", name="ma-personnalite")
*/
public function mapersonnaliteAction(Request $request)
{
return $this->render('CoreBundle:ma_personnalite.html.twig');
}
/**
* #Route("/cv", name="cv")
*/
public function cvAction(Request $request)
{
return $this->render('CoreBundle:cv.html.twig');
}
/**
* #Route("/scolaires", name="scolaires")
*/
public function scolairesAction(Request $request)
{
return $this->render('CoreBundle:scolaires.html.twig');
}
/**
* #Route("/extra-scolaires", name="extra-scolaires")
*/
public function extrascolairesAction(Request $request)
{
return $this->render('CoreBundle:extra_scolaires.html.twig');
}
/**
* #Route("/contact", name="contact")
*/
public function contactAction(Request $request)
{
return $this->render('CoreBundle:contact.html.twig');
}
}
This is the config.yml
#app/config/routing.yml
core:
resource: "#CoreBundle/Controller/"
type: annotation
prefix: /
Thanks for your time
According to the Symfony 3 Docs it's better to use slashes and to not use "Bundle" word.
So, we have as example:
return $this->render('#BloggerBlog/Default/index.html.twig');
try to change this:
return $this->render('CoreBundle:index.html.twig');
to this:
return $this->render('CoreBundle::index.html.twig');
The difference is to use :: instead of :
This helped me in my case:
#Core/index.html.twig

how to reuse symfony route

I want to reuse a route in symfony as I used in Slim framework.
for example: in Slim I could define groups and then I would put the actions inside the group:
$app->group("example",..{
$app->get("/staff"...);
$app->get("test");
$aap->group("books",..{
$app->get("/"..);
$app->delete("/{id}")
})
});
And to access to the action test the url would be like: "domain/example/test", and to access staff: "domain/example/staff";
and to access book would be like: "domain/example/book/";
can I do this in symfony without having to go to every controller and put it manually.
The symfony documentation provide an example on how defines a prefix for all action routes:
/**
* #Route("/example")
*/
class ExampleController extends Controller
{
/**
* #Route("/staff")
*/
public function staffAction()
{
}
/**
* #Route("/test")
*/
public function testAction()
{
}
}
/**
* #Route("/example/books")
*/
class BookController extends Controller
{
/**
* #Route("/")
*/
public function indexAction()
{
}
/**
* #Route("/{id}")
* #Method({"DELETE"})
*/
public function deleteAction($id)
{
}
}

Forward with another template

I'm facing a problem with the forward method of Symfony (v2.3).
Basicly, I have two controllers in two distinct bundles. Let's say DesktopBundle for a desktop version of the app, and MobileBundle for the mobile version.
I want to reuse code of an action of the DesktopBundle into an action of MobileBundle. What I do now is a forward :
DesktopController
namespace Acme\DesktopBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
/**
* #Route("/")
*/
class IndexController extends Controller
{
/**
* #Route("", name="desktopIndex")
* #Template()
*/
public function indexAction()
{
/* some code I don't want to duplicate */
return array(
'some' => 'var'
);
}
}
MobileController
namespace Acme\MobileBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
/**
* #Route("/")
*/
class IndexController extends Controller
{
/**
* #Route("", name="mobileIndex")
* #Template()
*/
public function indexAction()
{
return $this->forward('AcmeDesktopBundle:Index:index');
}
}
Now it works, but obviously the Response object is returned with the rendered template of the desktop version of the indexAction.
What I would like, is to get the variables and then render the template of the mobile version.
What I tried is to pass a variable into the forward method and then render the action conditionally into the desktop version:
return $this->forward(
'acmeDesktopBundle:Index:index',
array('mobile' => true)
);
This would work, but I don't really want to change to code inside the DesktopBundle but only the MobileBundle. Is there a way to achieve this ? I am missing something, or should I go to an entirely different solution ?
Forwarding means to redirect to the given page, but without changing the url on the client. I.e. redirect on the server side. If you want only access the return value of the action, simply call it. With the #Template annotation this is made very easy.
namespace Acme\MobileBundle\Controller;
use Acme\DesktopBundle\Controller\IndexController as DesktopController;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
/**
* #Route("/")
*/
class IndexController extends Controller
{
/**
* #Route("", name="mobileIndex")
* #Template()
*/
public function indexAction()
{
$desktop = new DesktopController();
$desktop->setContainer($this->container);
$values = $desktop->indexAction();
// do something with it
return $values;
}
}

Categories