I made a command that automatically writes in routing.yml.
My problem is that when I try to browse one of the routes
api:
resource: "."
type: "api"
prefix: /api
I get this exception
Cannot load resource "."
I tried to add a cache:clear to my command but I get the same exception.
I added a cache warmup that runs after the command termination that way Symfony dumps routes into generated code .
class TerminateListener {
public function onConsoleTerminate(ConsoleTerminateEvent $event) {
if ($event->getCommand()->getName() == ('my:command')) {
$app = new Application();
$cache_clear_command = $event->getCommand()->getApplication()->find('cache:warmup');
$cache_clear_command->setApplication($app);
$event->getOutput()->setVerbosity('VERBOSITY_QUIET');
$cache_clear_command->run($event->getInput(), $event->getOutput());
}
}
}
services:
warmup.listener:
class:TerminateListener
tags:
- { name: kernel.event_listener, event: console.terminate , method: onConsoleTerminate }
Related
Why I am getting errors for the route?
Other APIs for the CRUD operation are working fine.
I have added a new controller code for my new API and I am getting a route error.
What could be the mistake?
While I have already written my route in routing.yml
creat:
path: /create
defaults: { _controller: AcmeDemoBundle:DemoController:create }
methods: [GET]
Products:
path: /recentProducts/{id}
defaults: { _controller: AcmeDemoBundle:DemoController:recentProducts }
methods: [GET]
Update:
path: /updateProduct/{id}
defaults: { _controller: AcmeDemoBundle:DemoController:update }
methods: [POST]
Delete:
path: /deleteProduct/{id}
defaults: { _controller: AcmeDemoBundle:DemoController:delete }
methods: [DELETE]
referenceCreation:
path: /koco/create
defaults: { _controller: AcmeDemoBundle:DemoController:createReference }
methods: [GET]
My api is
http://localhost/koco1/web/app_dev.php/demo/koco/create
My Controller is
/**
* #Route("/koco/create", name="referenceCreation")
* #Template()
*/
public function createReferenceAction()
{
$organization = new Organization();
$organization->setName('Sensio Lab');
$user = new User();
$user->setName("Jonathan H. Wage");
$user->setOrganization($organization);
$dm = $this->get('doctrine_mongodb')->getManager();
$dm->persist($organization);
$dm->persist($user);
$dm->flush();
return new Response('Created product id ');
// $response = new Response('Hello Huzaifa ');
// return $response;
}
What is wrong here?
Kindly let me know.
Thanks
Your routing is off.
Also you are creating routes through yaml and through annotations. Should stick to one.
Also server setup looks off too, http://localhost/koco1/web/app_dev.php/demo/koco/create should be more like http://localhost/koco1/web/koco/create, you can try running php server. Going to /public and running php -S localhost:8000 you can read more here: https://www.php.net/manual/en/features.commandline.webserver.php
or symfony cli server https://symfony.com/download
Your routes does not match /demo/koco/create is not equal to /koco/create, you should first of all set up correctly, then it will be easier to debug.
I hope someone could help me to use Api-platorm with Nelmio.
I use Api-plaform and Nelmio. I need to hide the Api-platform docs from Nelmio.
I need to have 3 routes:
/internal -> API-Platform Docs
/external -> NELMIO-Docs
/admin -> NELMIO-Docs
My config of Nelmio:
# config/packages/nelmio_api_doc.yaml
nelmio_api_doc:
documentation:
info:
title: ...
description: ...
version: 0.2.0
areas: # to filter documented areas
default:
path_patterns: [ ^/external ]
external:
path_patterns: [ ^/external ]
admin:
path_patterns: [ ^/admin ]
My config of Nelmio (routes):
# config/routes/nelmio_api_doc.yaml
app.swagger:
path: /{area}/json
methods: GET
defaults: { _controller: nelmio_api_doc.controller.swagger, area: default }
app.swagger_ui:
path: /{area}
methods: GET
defaults: { _controller: nelmio_api_doc.controller.swagger_ui, area: default }
My config of API-Platform:
# config/routes/api_platform.yaml
api_platform:
resource: .
type: api_platform
prefix: /internal/
But if I go to http://localhost/external or http://localhost/admin I see always not only needed routes, but also the routes from API-Platform:
I know this question is old by now, but I am facing the same situation and I found a workaround that may help some one, so I am posting it.
API Platform lets you decorate Swagger so you can customize the final documentation output. I took advantage of this to get rid of the entire api platform documentation when not asking for it.
<?php
namespace App\Swagger;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
final class SwaggerDecorator implements NormalizerInterface
{
private $decorated;
private $requestStack;
public function __construct(NormalizerInterface $decorated, RequestStack $requestStack)
{
$this->decorated = $decorated;
$this->requestStack = $requestStack;
}
public function normalize($object, $format = null, array $context = [])
{
if ('/internal/docs' !== $this->requestStack->getCurrentRequest()->getPathInfo()) {
// request is not for internal docs (maybe it is for external or admin one) so get rid of api platform docs
return null;
}
$docs = $this->decorated->normalize($object, $format, $context);
// here you can customize documentation
return $docs;
}
public function supportsNormalization($data, $format = null)
{
return $this->decorated->supportsNormalization($data, $format);
}
}
I hope this helps someone, happy coding!
UPDATE
In order to enable that decorator, you must declare it as so in your services file:
App\Swagger\SwaggerDecorator:
decorates: 'api_platform.swagger.normalizer.api_gateway'
arguments: [ '#App\Swagger\SwaggerDecorator.inner' ]
autoconfigure: false
Then, in the class itself, replace '/internal/docs' with the actual URL you are using for your API Platform documentation.
Hope this helps.
On your nelmio configuration yaml file, use a regex to exclude the docs. For instance, for excluding the /external/doc you should:
external:
path_patterns: [ ^/external(?!/doc$) ]
I got defined routes in routing.yml file
one route is:
Profile_user_profile:
path: /profile/{id}
defaults: { _controller: ProfileBundle:Users:profile }
methods: [get]
and second is:
Profile_accept_connection_proposal:
path: /profile/acceptProposal
defaults: { _controller:ProfileBundle:Users:acceptConnectionProposal }
methods: [put]
First route without methods: [get] listen also and [put] request and catch second url before it get to route definition. Is there way to define checking for parameter only if url is numeric.
Just add the requirements parameter to accept only digits for a determined route like this:
Profile_user_profile:
path: /profile/{id}
defaults: { _controller: ProfileBundle:Users:profile }
methods: [get]
requirements: <--- ADDED PARAMETER
id: \d+
For more infos read the Symfony book about Routing. There you can find more advanced example on how to use route parameters.
You can now do this with Annotations in your controller like so:
class UserController extends AbstractController
{
/**
* #Route("/profile/{id}", name="user_profile", requirements={"id"="\d+"})
*/
public function profile($id)
{
// ...
}
}
More info on Symfony's docs
Specifically defining routing requirements
Symfony 2.8.7 I have a simple alias definition in my services.yml:
h4cc_alice_fixtures:
alias: h4cc_alice_fixtures.manager
This works perfectly in DEV because in my AppKernel h4cc is registered:
public function registerBundles()
{
$bundles = [
//...
];
if (in_array($this->getEnvironment(), array('dev', 'test'))) {
$bundles[] = new h4cc\AliceFixturesBundle\h4ccAliceFixturesBundle();
}
return $bundles;
}
In PROD now I get an dependency injection error because of course h4cc_alice_fixtures.manager cannot be resolved.
I want to have h4ccAliceFixturesBundle only in DEV and TEST but currently I have only one services.yml.
Is there a way to define the alias only for DEV and TEST?
UPDATE:
As there is something like:
my_service:
class: Acme\AcmeBundle\Services\MyService
arguments: [ '#tenant_user_service', '#?debug.stopwatch' ]
which is only injecting Stopwatch when App is in debug-mode...
I thought there might be existing something similar for Alias, too.
You can have separate services.yml similar what you have already with your routing_dev.yml. In the imports section of your config_dev.yml and config_test.yml you can replace the existing line:
imports:
- { resource: config.yml }
with following entry:
imports:
- { resource: parameters.yml }
- { resource: security.yml }
- { resource: services_dev.yml }
like you have it in your global config.yml already. Just add your suffix to the files.
I am working on a Symfony 2 web app and I would like to inject a Monolog logger using a specific channel to a service:
The Config:
monolog:
handlers:
main:
type: stream
path: %kernel.root_dir%/%kernel.environment%.log
level: error
#channels: [!alert]
alert:
type: stream
path: %kernel.root_dir%/%kernel.environment%.alert.log
level: info
channels: [alert]
Service Config:
services:
some_service:
class: Some\Service
arguments: [#logger]
tags:
- { name: monolog.logger, channel: alert }
The Service:
class SomeService {
protected $logger;
public function __construct($logger) {
$this->logger = $logger;
$this->logger->info('Log this!');
}
The prod.log file:
[2016-03-28 11:25:47] alert.INFO: Log this!
The Problem: Although I specifically inject the logger using the alert channel, the message is handled by the main handler. Thus the messages are logged into the prod.log file instead of the prod.alert.log file.
When I leave the line channels: [!alert] as comment, the message is logged to prod.log. When I activate this line by removing the comment, the message is not logged at all (main handler ignores the channel correctly).
What have I to to, in order to use a specific handler to target a specific log file, mailer, etc? Messages to alert channel should be handled by the alert handler while all other handlers are ignored.
Use special service created for Monolog handler:
services:
some_service:
class: Namespace\Some\Service
arguments: ["#monolog.logger.alert"]