Symfony\Component\HttpKernel\Exception\ NotFoundHttpException - symfony

I am following the openclassrooms tutorial on symfony. I am now currently at the chapter "Les controleurs avec Symfony".
I try to open http://localhost/Symfony/web/app_dev.php and get this error
NotFoundHttpException
I suspect the error to come from AdvertController.php.
But I compared it with the given code at the tutorial. And it is exactly the same. I tried then to delete the cache but it does not function. I will open another question for that.
Here is the AdvertController.php code:
<?php
//src/Neo/PlatformBundle/Controller/AdvertController.php
namespace Neo\PlatformBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
//use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
class AdvertController extends Controller
{
public function indexAction()
{
$url= $this->get('router')->generate(
'neo_platform_view', //first argument : path name
array('id' => 5)
);
return new Response("The url of the announcement is:".$url);
}
public function viewAction($id)
{
return new Response("Desplay of the announcment with id:".$id);
}
public function viewSlugAction($slug, $year, $_format)
{
return new Response(
"We could desplay the announcment conrresponding the the slug
'".$slug."', created in ".$year." and with the format ".$_format."."
);
}
}
?>
If you would like me to post other parts of code, please let me know.
I have no idea, where to look at.
Thank you very much!

You can try to dump your routes with the command php bin/console debug:router or app/console for symfony <3.0 to see if there is a route your your desired path.
If you have the prefix /platform, your paths inside your controller are now /platform/path instead of /path.
You need a default route for your root path.

The message error is very explicit, there are not routes for "/". Try to verify your routing.yml

Related

Cannot autowire argument $article : Symfony 5

I'am currenty face to this error when i try to get my article page : Cannot autowire argument $article of "App\Controller\HomeController::show()": it references class "App\Entity\Article" but no such service exists.
I just created a very new small symfony 5 application :
The code in my controller is :
/**
* #Route("/show/{id}", name="show")
*/
public function show(Article $article): Response
{
if(!$article) {
return $this->redirectToRoute('home');
}
return $this->render('show/index.html.twig', [
'article' => $article,
]);
}
I'am following a tutorial on Udemy and i guess that i did the same thing than the former. Maybe version difference ?
Thanks in advance for your helps.
Thierry
The error you have is saying that it cannot find the auto-wire path to your entity. Using the Symfony installer will automatically configure parts like this for you.
The main part which auto-wires the Entity to the Dependency Injection layer is through Doctrine configuration and the Symfony ParamConverter found as part of the SensioFrameworkExtraBundle.
The ParamConverter has a lot of options to be able to convert parameters inside of the #Route into an Entity. Using your example above we see that Symfony will internally call ArticleRepository->findOneById($id) and return the result to your controller.
EDIT: Removed all mentions of Doctrine configurations. The errors that are displayed when Doctrine is not auto-wiring are different.
Same problem here (with attributs instead of annotations) on Symfony 5
I have even tried to explicite ParamConverter and Entity:
#[Route('/article/{id}/editer', name: 'edit_article', requirements: ["id" => "\d+"], methods: ['GET','POST'])]
#[ParamConverter('id', options: ['mapping' => ['id' => 'id']])]
#[Entity('article', expr: 'repository.findOneBySlug(id)')]
public function editArticle(Article $article, Request $request,
CategoryRepository $categoryRepository, EntityManagerInterface $manager): Response
{
dump($article); die;
}
but i have got the error message:
Cannot autowire argument $id of "App\Controller\DefaultController::editArticle()":
it references class "App\Entity\Article" but no such service exists.
Although there is:
use App\Entity\Article;
And the solution like #nico-haase said is to install this bundle
composer require sensio/framework-extra-bundle

Symfony2 Route prefix querystring dynamic

My symfony2 project is setup with normal YAML routes to any normal project.
Routes are setup with annotation and final URLs are
http://examplecom/artices/{id}
http://example.com/comments/{id}
I want to add prefix querystring to all the path, only if there is querystring called preview
So If I access http://example.com/?preview=something - I want this querystring to append to all the routes, so it continue to pass on every page and if this does not exist, then it will continue to be used as normally.
How can I accomplish this?
service.yml
parameters:
router.options.generator_base_class: "Acme\\DemoBundle\\Routing\\Generator\\UrlGenerator"
UrlGenerator.php
<?php
namespace Acme\DemoBundle\Routing\Generator;
use Symfony\Component\Routing\Generator\UrlGenerator as BaseUrlGenerator;
class UrlGenerator extends BaseUrlGenerator
{
protected function doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $referenceType, $hostTokens)
{
return parent::doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $referenceType, $hostTokens).'?preview=something';
}
}
reference: http://h4cc.tumblr.com/post/56874277802/generate-external-urls-from-a-symfony2-route

Symfony Routing "_locale" parameter not accepted

I have a problem with the symfony routing.
For an multilanguage projekt I render a Twig template via a job queue for mailing. In this template is a link to a route that requires the "_locale" parameter with "de" or "en" for example. I use the function "{{ url('route', {'_locale': 'de'}) }}" to generate the url.
By rendering the template, I got the following error message:
[Twig_Error_Runtime]
An exception has been thrown during the rendering of a template ("Some mandatory parameters are missing ("_locale") to generate a URL for route "Route".") in "TemplatePath" at line 5.
Whats my mistake?
Thanks for help
When you are generating URL route, via CLI, the Symfony kernel is missing a HTTP Request, and a Routing->RequestContext.
Thats why, the URL generator cannot find _locale parameter.
To fix it, you must manually create a RequestContext, so, in your command:
$this->getContainer()->get('router')
->setContext(
(new RequestContext())
->setParameter('_locale', 'fr')
);
class BaseCommand extends ContainerAwareCommand
{
protected function getLocale()
{
return $this->getContainer()->get('translator')->getLocale();
}
protected function render($view, $data)
{
return $this->getContainer()->get('templating')->render($view, $data);
}
}
in command
class SomeCommand extends BaseCommand
{
...
$this->render($view, array_merge($data, ['_locale' => $this->getLocale()])
}
in view
{{url('any', {param: 'foo'}|merge(_locale is defined ? {'_locale': _locale } : {}))}}
It's necro time :)
I'm just guessing here, but there's a couple things you can try.
Can you set the locale in your command?
Set the locale for the translator bundle:
$this->getContainer()->get('translator')->setLocale('de');
Set the locale for this session:
$this->getContainer()->get('session')->setLocale('de);
Internationalized routing for Symfony 4.1 and higher
If this applies to you, try this:
url('route.de', {'_locale': 'de'}) }}"
Does your route have 'de' and 'en' set as a requirement?
/**
* Matches /route
* #Route(
* "/route/{_locale}",
* requirements={
* '_locale': 'en|de'
* },
* name="route"
* )
*/
It's an old question but this might help someone out.

Access Service from Controller and/or Twig template

Disclaimer: I'm slowly starting to get into Symfony and still have some problems understanding how the architecture works.
Currently I set up different Bundles (Services, right?) that should deliver different output for different routes. So far I got around adding a simple Twig template that loads stylesheets and scripts via Assetics and Twig-blocks. Now I added another Bundle that queries data via Buzz from a remote location, which worked fine as a standalone script, but I don't get around printing output in a Twig template.
The architecture of the original script is like the following (names made more generic):
Vendors - abstract class that serves as base for all remote request Bundles.
ServiceABC - abstract class that extends Vendors and defines Error handling and output preparation for the ABC service.
ClientXYZ - final class that extends Service_ABC, defines output parsing and normalization of the returned data.
This Bundle got a services.yml file:
# ~/MyApp/Bundle/ServiceABCBundle/Resources/config/services.yml
parameters:
service_abc_manager.class: MyApp\Bundle\ServiceABCBundle\Models\Service_ABC
location_manager.class: MyApp\Bundle\ServiceABCBundle\Models\Clients\ClientLocation
monitor_manager.class: MyApp\Bundle\ServiceABCBundle\Models\Clients\ClientMonitor
services:
service_abc_manager:
abstract: true
location_manager:
class: %location_manager.class%
parent: service_abc_manager
monitor_manager:
class: %monitor_manager.class%
parent: service_abc_manager
Names changed for easier reference - Typos by accident possible.
Now my problem/question is, that I don't really get behind the Symfony2 concept of how to get the output into the template.
namespace MyApp\Bundle\ServiceABCBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use MyApp\Bundle\ServiceABCBundle\Models\Clients\ClientLocation;
class DefaultController extends Controller
{
public function indexAction()
{
$services = array();
$services[] = $this->container->has('service_abc_manager');
$services[] = $this->container->has('location_manager');
$services[] = $this->container->has('client_location');
$services[] = $this->container->has('ClientLocation');
var_dump( $services );
$client = new ClientLocation();
var_dump( $client );
$response = $this->render(
'Service_ABC:Default:index.html.twig'
);
# $response->setCharset( 'utf-8' );
# $response->headers->set( 'Content-Type', 'text/html' );
return $response;
}
}
The output of the first array() named $services is always false and the $client = new ClientLocation(); throws an Exception that the class name wasn't found.
How can I access those Services/Bundle(parts)/Classes? And how would I render the output to a template?
Update
After I added the complete tree definition to Configuration()->getConfigTreeBuilder(), I'm able to see the definitions in the CLI:
class Configuration implements ConfigurationInterface
{
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root( 'myapp_service_abc' );
$rootNode
->children()
->scalarNode('service_abc_manager')->end()
->scalarNode('location_manager')->end()
->scalarNode('monitor_manager')->end()
->end()
;
return $treeBuilder;
}
}
The CLI command php app/console config:dump-reference myapp_service_abc now gives me the following output:
myapp_service_abc:
service_abc_manager: ~
location_manager: ~
monitor_manager: ~
I can as well see that the config data was loaded, when I var_dump( $loader ); inside MyAppServiceABCExtension right after $loader->load( 'services.yml' ); was called.
The output is the following:
object(Symfony\Component\DependencyInjection\Loader\YamlFileLoader)
protected 'container' =>
object(Symfony\Component\DependencyInjection\ContainerBuilder)
private 'definitions' =>
array
'service_abc_manager' =>
object(Symfony\Component\DependencyInjection\Definition)
'location_manager' =>
object(Symfony\Component\DependencyInjection\DefinitionDecorator)
private 'parent' => string 'service_abc_manager'
// etc.
The problem itself remains: There's still a FALSE return value inside DefaultController()->indexAction() when I var_dump( $this->container->has( 'service_abc_manager' );. I as well tried var_dump( $this->container->has( 'location_manager' ); and var_dump( $this->container->has( 'myapp.service_abc_manager' ); with the same result.
You should not call your services from the twig file, but from the controller.
The role of the controller is to :
validate your forms if there were a form posted
call your services to get some stuffs to display in a view
initialize forms if there is a form to display
return a Response that typically contains a rendered twig view
Do not call your services using something like $client = new ClientLocation();, but call it using the service container. This will allow you to take the whole power of the dependancy injection offered by Symfony2.
Your controller will look like :
<?php
namespace MyApp\Bundle\ServiceABCBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class DefaultController extends Controller
{
public function indexAction()
{
$locationService = $this->container->get('location_manager');
$someStuffs = $locationService->someMethod();
$response = $this->render(
'ServiceABCBundle:Default:index.html.twig', array('stuffs' => $someStuffs)
);
return $response;
}
}
From your twig file, you'll be able to use the stuffs variable :
{{ stuffs }} if your variable is a terminal ( a string, a number... )
{{ stuffs.attribute }} if your variable is an object or an array
About your services file, I am a bit confused, because your architecture does not look to be the standard Symfony2's one :
# ~/MyApp/Bundle/ServiceABCBundle/Resources/config/services.yml
Why your services.yml file isn't in the src/MyApp/SomethingBundle/Resources/config/ directory?
If you didn't already read it, I suggest you to have a look to the Symfony2 : The Big Picture documentation, which is the best way to start with Symfony2.

Symfony2 custom console command not working

I created a new Class in src/MaintenanceBundle/Command, named it GreetCommand.php and put the following code in it:
<?php
namespace SK2\MaintenanceBundle\Command;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
class GreetCommand extends ContainerAwareCommand
{
protected function configure()
{
$this
->setName('maintenance:greet')
->setDescription('Greet someone')
->addArgument('name', InputArgument::OPTIONAL, 'Who do you want to greet?')
->addOption('yell', null, InputOption::VALUE_NONE, 'If set, the task will yell in uppercase letters')
;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$name = $input->getArgument('name');
if ($name) {
$text = 'Hello '.$name;
} else {
$text = 'Hello';
}
if ($input->getOption('yell')) {
$text = strtoupper($text);
}
$output->writeln($text);
}
}
?>
And tried to call it via
app/console maintenance:greet Fabien
But i always get the following error:
[InvalidArgumentException]
There are no commands defined in the "maintenance" namespace.
Any ideas?
I had this problem, and it was because the name of my PHP class and file didn't end with Command.
Symfony will automatically register commands which end with Command and are in the Command directory of a bundle. If you'd like to manually register your command, this cookbook entry may help: http://symfony.com/doc/current/cookbook/console/commands_as_services.html
I had a similar problem and figured out another possible solution:
If you override the default __construct method the Command will not be auto-registered by Symfony, so you have to either take the service approach as mentioned earlier or remove the __construct override and make that init step in the execute method or in the configure method.
Does actually anyone know a good best practice how to do init "stuff" in Symfony commands?
It took me a moment to figure this out.
I figured out why it was not working: I simply forgot to register the Bundle in the AppKernel.php. However, the other proposed answers are relevant and might be helpful to resolve other situations!
By convention: the commands files need to reside in a bundle's command directory and have a name ending with Command.
in AppKernel.php
public function registerBundles()
{
$bundles = [
...
new MaintenanceBundle\MaintenanceBundle(),
];
return $bundles;
}
In addition to MonocroM's answer, I had the same issue with my command and was silently ignored by Symfony only because my command's constructor had 1 required argument.
I just removed it and call the parent __construct() method (Symfony 2.7) and it worked well ;)
If you are over-riding the command constructor and are using lazy-loading/autowiring, then your commands will not be automatically registered. To fix this you can add a $defaultName variable:
class SunshineCommand extends Command
{
protected static $defaultName = 'app:sunshine';
// ...
}
Link to the Symfony docs.
I think you have to call parent::configure() in your configure method
I had this same error when I tried to test my command execution with PHPUnit.
This was due to a wrong class import :
use Symfony\Component\Console\Application;
should be
use Symfony\Bundle\FrameworkBundle\Console\Application;
cf. Other stack thread
In my case it was complaining about the "workflow" namespace although the WorkflowDumpCommand was correctly provided by the framework.
However, it was not available to run because I have not defined any workflows so the isEnabled() method of the command returned false.
I tried to use a service passed via constructor inside the configure method:
class SomeCommand extends Command {
private $service;
public function __construct(SomeService $service) {
$this->service = $service;
}
protected function configure(): void {
$this->service->doSomething(); // DOES NOT WORK
}
}
Symfony uses Autoconfiguration that automatically inject dependencies into your services and register your services as Command, event,....
So first just make sure that you have services.yaml in your config folder. with autoconfigure:true.
this is the default setting
Then Make sure That All your files are exactly the same name as Your Class.
so if you have SimpleClass your file must be SimpleClass.php
If you have a problem because of a __constructor,
go to services.yml and add something like this:
app.email_handler_command:
class: AppBundle\Command\EmailHandlerCommand
arguments:
- '#doctrine.orm.entity_manager'
- '#app.email_handler_service'
tags:
- { name: console.command }
For newer Symfony-Version (5+) commands must be registered as services.
What I do frequently forget while setting it up, is to tag it properly:
<service id="someServiceCommand">
<tag name="console.command"/>
</service>
Without this litte adaptation, your command name will not be displayed and therefore not accessible.

Resources