How to disable Nelmio UI in production? - symfony

Is there a way to turn off all of the Nelmio Swagger UI docs? In production I want the outside world to see nothing at the following URLs, but in dev they should display useful docs & sandbox as normal:
http://ourserver.com/api/doc
http://ourserver.com/api-docs
http://ourserver.com/api-docs/*
Seems like there should be an easy switch for this in the Nelmio config, but I haven't found it. My company is using the Nelmio API Doc bundle in Symfony to develop APIs for a non-public API. The API server is exposed to the public, but we're not interested in publishing its usage to the world.

#gp_sflover's comment got me on the right track, but there's more to it than just disabling NelmioApiDocBundle on prod in AppKernel.php. Configs & routes that refer to Nelmio will generate errors until you move them into dev-specific files. The following change in app/AppKernel.php was the first step:
public function registerBundles()
{
$bundles = [
new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
...
// new Nelmio\ApiDocBundle\NelmioApiDocBundle(), // <-- REMOVED FROM HERE
new Nelmio\CorsBundle\NelmioCorsBundle(),
new AppBundle\AppBundle(),
];
if (in_array($this->getEnvironment(), ['dev', 'test'], true)) {
$bundles[] = new Nelmio\ApiDocBundle\NelmioApiDocBundle(); // <-- ADDED HERE
$bundles[] = new Symfony\Bundle\DebugBundle\DebugBundle();
...
To eliminate the config errors, I had to move the following stuff out of app/config/config.yml and into config_dev.yml:
# nelmio Configuration
nelmio_api_doc:
sandbox:
enabled: true
name: 'DLAP API Bridge'
swagger:
...
cache:
enabled: false
Likewise, the following stuff came out of app/config/routing.yml and moved to routing_dev.yml:
NelmioApiDocBundle:
resource: "#NelmioApiDocBundle/Resources/config/routing.yml"
prefix: /api/doc
nelmio_api_swagger:
resource: "#NelmioApiDocBundle/Resources/config/swagger_routing.yml"
resource: null
prefix: /api-docs

Now with symfony4 and flex you can install the bundle normally
composer require nelmio/api-doc-bundle
(So it won't be set as a require-dev depandency in your composer.json)
Now you change the setting in the project/config/bundles.php to:
Nelmio\ApiDocBundle\NelmioApiDocBundle::class => ['dev' => true]
So you don't get errors (eg from annotations), but it wont be loaded from Kernel.php

For disabling the Nelmio api-doc-bundle on specific environment, after some investigation, I ended up doing the following:
only enable the bundle on your target environment, i.e. on project/config/bundles.php have:
Nelmio\ApiDocBundle\NelmioApiDocBundle::class => ['dev' => true]
put the config annotation on env specific (put nelmio_api_doc.yaml inside ./config/packages/dev/)
put the route file nelmio_api_doc.yaml inside ./config/routes/dev (instead of being in the ./config/routes), otherwise, if you call the route for another environment which doens't have the bundle loaded, instead of 404, you will see 500)

not loading the bundle in config/bundles.php throws an exception in Symfony 4.3 with NelmioApiDocBundle Version 3:
There is no extension able to load the configuration for "nelmio_api_doc"
I ended up disabling the route for the api docs with a redirect in the environment, which needed to be disabled (prod):
#config/routes/prod/nelmio_api_doc.yaml
app.swagger:
path: /api/doc.json
methods: GET
defaults:
_controller: FrameworkBundle:Redirect:urlRedirect
path: /
permanent: true
app.swagger_ui:
path: /api/doc
methods: GET
defaults:
_controller: FrameworkBundle:Redirect:urlRedirect
path: /
permanent: true

Related

How to Install Swagger on Symfony 4?

I started to install like this:
https://symfony.com/doc/4.x/bundles/NelmioApiDocBundle/index.html
Step 1.
`composer require nelmio/api-doc-bundle` - Thats OK
Step 2.
class AppKernel extends Kernel
{
public function registerBundles()
{
$bundles = [
new Nelmio\ApiDocBundle\NelmioApiDocBundle(),
];
}
}
But I have no AppKernel extends Kernel. I **just have Kernel** with
`$contents = require $this->getProjectDir().'/config/bundles.php';`
So I added into **/config/bundles.php**
Nelmio\ApiDocBundle\NelmioApiDocBundle::class => ['all' => true],
Step 3.
I added into config/routes.yaml
# config/routes.yaml
app.swagger_ui:
path: /api/doc
methods: GET
defaults: { _controller: nelmio_api_doc.controller.swagger_ui }
Step 4.
I created config/packages/nelmio_api_doc.yaml with
nelmio_api_doc:
areas:
path_patterns: # an array of regexps
- ^/api(?!/doc$)
host_patterns:
- ^api\.
After that I should see Swagger's page at mysite/api/doc
But i see only white page with link 'NelmioApiDocBundle' at github
What I did wrong?
I ran:
bin/console assets:install --symlink
and it's now working.
You need to specify areas in your nelmio_api_doc
nelmio_api_doc:
documentation:
info:
title: My App
description: This is an awesome app!
version: 1.0.0
areas: # to filter documented areas
path_patterns:
- ^/api(?!/doc$) # Accepts routes under /api except /api/doc
- ^/secured/project(?!/doc$) # Accepts routes under /api except /api/doc

Kayue\WordpressBundle with Symfony 4.4.1: The class XXX was not found in the chain configured namespaces App\Entity

I'm trying to work with kayue/KayueWordpressBundle installed with composer as composer require kayue/kayue-wordpress-bundle in my Symfony 4.4.1 project but I'm unable to.
This is what I'm trying to do:
<?php
namespace App\Service\WordPress;
use Doctrine\ORM\EntityManagerInterface;
use Kayue\WordpressBundle\Entity\Post;
class PostCollection
{
protected $postRepository;
public function __construct(EntityManagerInterface $entityManager)
{
$this->postRepository = $entityManager->getRepository(Post::class);
}
}
The error I get:
The class 'Kayue\WordpressBundle\Entity\Post' was not found in the chain configured namespaces App\Entity
At first I blamed my dual-database configuration (Symfony is on a different DB from Wordpress) but then I put the DBs together and the issue persists:
doctrine:
dbal:
url: '%env(resolve:DATABASE_URL)%'
# Only needed for MySQL (ignored otherwise)
charset: utf8mb4
default_table_options:
collate: utf8mb4_unicode_ci
orm:
auto_generate_proxy_classes: true
naming_strategy: doctrine.orm.naming_strategy.underscore
auto_mapping: true
mappings:
App:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity'
prefix: 'App\Entity'
alias: App
I've been fiddling for the past 2hrs, but now I'm fresh out of ideas. I wonder if ANYONE actually got this to work with Symfony 4.
Thanks!
Edit: other tries:
Direct post injection:
use Kayue\WordpressBundle\Entity\Post;
public function index(Post $post){}
Result:
Cannot autowire argument $post of "App\Controller\IndexController::index()": it references class "Kayue\WordpressBundle\Entity\Post" but no such service exists.
As per documentation: outdated Symfony 2 way
$repo = $this->get('kayue_wordpress')->getManager()->getRepository('KayueWordpressBundle:Post');
Result:
Service "kayue_wordpress" not found: even though it exists in the app's container, the container inside "App\Controller\IndexController" is a smaller service locator that only knows about the "doctrine", "form.factory", "http_kernel", "parameter_bag", "request_stack", "router", "security.authorization_checker", "security.csrf.token_manager", "security.token_storage", "serializer", "session" and "twig" services. Try using dependency injection instead.
The "best way" to do this would actually be:
public function index(EntityManagerInterface $entityManager)
{
$entityManager->getRepository('KayueWordpressBundle:Post');
}
Result:
The class 'Kayue\WordpressBundle\Entity\Post' was not found in the chain configured namespaces App\Entity
Although you found a solution to this, there is a chain of issues I would like to explain.
The error
The class 'Kayue\WordpressBundle\Entity\Post' was not found in the chain configured namespaces App\Entity
means that in the entity manager provided, whose config is defined at:
orm:
...
mappings:
App:
...
dir: '%kernel.project_dir%/src/Entity'
prefix: 'App\Entity'
alias: App
the entity type Kayue\WordpressBundle\Entity\Post was not found.
Usually this type of error is solved by:
include the path Kayue\WordpressBundle\Entity in the entity manager or
use another entity manager which includes this path
In your case the default entity manager is autowired, based on the service alias of Doctrine\ORM\EntityManagerInterface as explained here. The alias is defined in the doctrine bundle `s config which points to the default doctrine entity manager.
You want to use Kayue\WordpressBundle `s entity manager, not the default one.
Solution
To solve this you can
1) Bind Arguments By type, as you find out, creating an alias of Kayue\WordpressBundle\Wordpress\ManagerRegistry to the service kayue_wordpress, as:
services:
# pass this service for any ManagerRegistry type-hint for any
# service that's defined in this file
Kayue\WordpressBundle\Wordpress\ManagerRegistry: '#kayue_wordpress'
or
2) use Binding Arguments by Name, in this case the "$wpManagerRegistry", as:
services:
# default configuration for services in *this* file
_defaults:
...
bind:
$wpManagerRegistry: '#kayue_wordpress'
and then
public function index($wpManagerRegistry)
{
$postRepository = $wpManagerRegistry->getManager()->getRepository('KayueWordpressBundle:Post');
so that any argument with name "$wpManagerRegistry" is autowired to this service.
References
The Symfony 3.3 DI Container Changes Explained (autowiring, _defaults, etc)
My collegue found a solution. You must configure the autowire like this:
// config/packages/kayue_wordpress.yaml
services:
Kayue\WordpressBundle\Wordpress\ManagerRegistry: '#kayue_wordpress'
After that, you can autowire:
use Kayue\WordpressBundle\Wordpress\ManagerRegistry;
public function __construct(ManagerRegistry $wpManagerRegistry)
{
$this->wpPostRepository = $wpManagerRegistry->getManager()->getRepository('KayueWordpressBundle:Post');
}
public function getPosts()
{
$post = $this->wpPostRepository->findOneBy(array(
'slug' => 'hello-world',
'type' => 'post',
'status' => 'publish',
));
}

Using custom Repository in Sylius Resource grid

I have generated a Grid with CRUD actions for my Labellisation entity on Sylius.
The grid is displayed well, but I would like to get associated elements too (the defaultAdresse of the -> customer of the -> current labellisation), so I need to use a custom repository method.
I tried to do this with this conf :
labellisation_grid:
resource: |
alias: grid.label
criteria:
valide: true
except: ['create', 'delete', 'update']
grid: public_labels
templates: LabelBundle:public/Crud
type: sylius.resource
defaults:
_sylius:
repository:
method: findAllValides
(adding all the defaults block), but I have an error because the method findAllValides is not defined. I do have a findAllValides method in my LabellisationRepository.
Debugging the ResourcesResolver, I saw in the getResource that the $repository passed to this function has a customRepositoryClassName = LabelBundle\Repository\LabellisationRepository (this path is the good one to my LabellisationRepository).
Is there something wrong with my code ?

Symfony - Cache (Memcache) in a controller

How do you using caching directly in a controller without queries (orm cache drivers)?
http://symfony.com/doc/current/reference/configuration/doctrine.html#caching-drivers
The documents only mention caching with doctrine but there are times it's needed without doctrine. They don't appear to mention anything on this or is it one of the view things Symfony doesn't have a wrapper for?
Install and use DoctrineCacheBundle:
Add this bundle to your project as a composer dependency:
composer require doctrine/doctrine-cache-bundle
Add this bundle in your application kernel:
// app/AppKernel.php
public function registerBundles()
{
// ...
$bundles[] = new \Doctrine\Bundle\DoctrineCacheBundle\DoctrineCacheBundle();
return $bundles;
}
Configure it:
# app/config/config.yml
doctrine_cache:
providers:
my_apc_metadata_cache:
type: apc
namespace: metadata_cache_ns
my_apc_query_cache:
namespace: query_cache_ns
apc: ~
memcache:
servers:
memcache01: 11211
Use it:
$apcCache = $this->container->get('doctrine_cache.providers.my_apc_cache');
$memcacheCache = $this->container->get('doctrine_cache.providers.memcache');
Read more: https://symfony.com/doc/current/bundles/DoctrineCacheBundle/usage.html
Full providers reference: http://symfony.com/doc/current/bundles/DoctrineCacheBundle/reference.html

symfony2 Unable to find controller

I am trying to start on Symfony2 but ran into a problem right away following the Symfony 2 "the book" part "Creating pages in Symfony 2":
I did this:
Created the bundle
php app/console init:bundle "Acme\StudyBundle" src
*Added the namespace in app/autoload.php *
$loader->registerNamespaces(array(
'Acme' => __DIR__.'/../src',
));
Initialized the bundle
// app/AppKernel.php
public function registerBundles()
{
$bundles = array(
// ...
new Acme\StudyBundle\AcmeStudyBundle(),
);
// ...
return $bundles;
}
Created the routes in app/config.routing.yml and src/Acme/StudyBundle/Resources/config/routing.yml
# app/config/routing.yml
homepage:
pattern: /
defaults: { _controller: FrameworkBundle:Default:index }
hello:
resource: "#AcmeStudyBundle/Resources/config/routing.yml"
# src/Acme/StudyBundle/Resources/config/routing.yml
hello:
pattern: /hello/{name}
defaults: { _controller: AcmeStudyBundle:Hello:index }
Created the controller
// src/Acme/StudyBundle/Controller/HelloController.php
namespace Acme\StudyBundle\Controller;
use Symfony\Component\HttpFoundation\Response;
class HelloController
{
public function indexAction($name)
{
return new Response('<html><body>Hello '.$name.'!</body></html>');
}
}
When I load the page: http://localhost/app_dev.php/hello/Ryan Symfony gives me an exception:
Unable to find controller "AcmeStudyBundle:Hello" - class "Acme\StudyBundle\Controller\HelloController" does not exist.
I got over the code several times but cannot find anything wrong.
just add
<?php
in the beginning of your controller file : src/Acme/StudyBundle/Controller/HelloController.php
it's solved the problem to me.
Afaik there is a discussion going on within the Symfony 2.0 dev guys in what places they should keep the "Bundles" extension.
I've just grabbed the latest version of Symfony via Git and followed your code 1:1.
I got various error messages too but when I changed...
in src/Acme/StudyBundle/Resources/config/routing.yml
defaults: { _controller: AcmeStudyBundle:Hello:index }
to
defaults: { _controller: AcmeStudy:Hello:index }
app/config/routing.xml
resource: "#AcmeStudyBundle/Resources/config/routing.yml"
to
resource: "#AcmeStudy/Resources/config/routing.yml"
...i got a pretty "Hello Ryan" in the browser.
Hope this helps!
You are probably running PR9. Update to PR11(latest), and I would bet this gets resolved. Symfony devs removed the 'Bundle' suffix in PR9, but added it back again shortly there after.
Also, Symfony devs keep an Update log that I find extremely helpful.

Resources