Symfony #Paramconverter works over autowiring - symfony

I am working on upgrade Symfony 3.3 to 4.4 and almost done with it, but I have one last issue.
I enabled autowiring with default config, but whole project uses lots of #ParamConverter conversions without annotation.
Problem: ParamConverter with auto_convert tries to convert services and classes that are mentioned to controller by typehinting for autowiring (not entities).
Controller:
/**
* #Route("/report", name="report_page")
*/
public function report(
Request $request,
FileManager $fileManager
): Response {
// code
}
Error:
The class 'App\Service\FileManager' was not found in the chain configured namespaces App\Entity.
Service 'App\Service\FileManager' exists and works correctly.
ParamConverter config (by default 'request: {converters: true, auto_convert: true}'):
sensio_framework_extra:
router:
annotations: false
Doctrine config:
doctrine:
dbal:
default_connection: default
connections:
default:
# config
orm:
auto_generate_proxy_classes: '%kernel.debug%'
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
auto_mapping: true
mappings:
Base:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity'
prefix: App\Entity
Controller setting (services.yaml):
services:
_defaults:
autowire: true
autoconfigure: true
public: false
App\:
resource: '../src/*'
exclude: '../src/{DataFixtures,Entity,Objects,Repository,Utils}'
App\Controller\:
resource: '../src/Controller'
tags: ['controller.service_arguments']
I understand that I can set 'sensio_framework_extra.request.auto_convert' to false and use #ParamConverter annotation everywhere in controllers, but there are too many places with this conversion and I try to get default behavior, so additional #ParamConverter annotations would be extra.
Just in case: I tried to disable auto_convert and everything worked correctly (services were autowired and entities were passed to controllers).
Also I checked that I installed last available versions of packages and bundles.
Need some hints on it. Probably I missed something. I tried to find exact way how ParamConverter works by default and how it checks that class is entity or not, but it is too complicated and I decided that I dug too deep.
EDIT:
Probably I have some issue with autowiring's config and not paramconverter. But I checked php bin/console debug:autowiring and got all needed services as available via autowiring.

It looks like symfony is trying to convert the fileManager like an entity.
Try moving the injected service(s) into the __construct method of the controller (and add the property to the controller) like:
private $fileManager;
...
public function __construct(FileManager $fileManager) {
$this->fileManager = $fileManager;
}
and then access it in the report method:
$this->fileManager

Related

Multiple entity manager: The target entity specified on is unknown or not an entity

I have 2 entity managers, each for one of my databases DATABASE_URL and DATABASE_URL_SAGE:
# config/packages/doctrine.yaml
doctrine:
dbal:
default_connection: site
connections:
site:
url: '%env(resolve:DATABASE_URL)%'
driver: 'pdo_sqlsrv'
# ...
sage:
url: '%env(resolve:DATABASE_URL_SAGE)%'
driver: 'pdo_sqlsrv'
# ...
orm:
auto_generate_proxy_classes: true
default_entity_manager: site
entity_managers:
site:
connection: site
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
mappings:
Site:
is_bundle: false
type: attribute
dir: '%kernel.project_dir%/src/Entity/Site'
prefix: 'App\Entity\Site'
alias: Site
sage:
connection: sage
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
mappings:
Sage:
is_bundle: false
type: attribute
dir: '%kernel.project_dir%/src/Entity/Sage'
prefix: 'App\Entity\Sage'
alias: Sage
I would like to create an entity which:
has a ManyToOne relation with another entity managed by the same entity manager (site)
has another ManyToOne relation with another entity managed by the sage entity manager
Something like this:
// src/Entity/Site/CategoryFArticle.php
namespace App\Entity\Site;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
class CategoryFArticle
{
#[ORM\ManyToOne(targetEntity: 'App\Entity\Site\Category')]
private $category;
#[ORM\ManyToOne(targetEntity: 'App\Entity\Sage\FArticle')]
private $fArticle;
}
The problem is when I do that I got the error:
Mapping
-------
[FAIL] The entity-class App\Entity\Site\CategoryFArticle mapping is invalid:
* The target entity 'App\Entity\Sage\FArticle' specified on App\Entity\Site\CategoryFArticle#fArticle is unknown or not an entity.
Database
--------
In MappingException.php line 23:
The class 'App\Entity\Sage\FArticle' was not found in the chain configured namespaces App\Entity\Site
Questions
Is doctrine able to manage this kind of mapping (with entities managed by differents entity managers) ?
If so, how can I configure my current code to work ?
Thank you

Symfony 3.3 autoconfigure services and usage

I updated my project to Symfony 3.3. I want to use the new autoconfigure feature for services. I tried to get rid of $this->get() but I have errors in Controllers and Commands.
With the code sample below in a Controller, I have this error:
recapitulatifCollesAction() requires that you provide a value for the "$checkGele" argument. Either the argument is nullable and no null value has been provided, no default value has been provided or because there is a non optional argument after this one.
In commands, I don't know how to get rid of $container->get() at all.
Do you have an idea how I can get this to work ?
Controller:
public function recapitulatifCollesAction($estEnCours, CheckGeleService $checkGele)
{
// ...
$checkGele->getGeleAutorisation($colle);
// ...
}
My config:
services:
_defaults:
autowire: true
autoconfigure: true
public: false
Edit : new error after modifying config.yml
For controllers you need also add the service argument resolver to autowire service in "actions" methods. This's all about default autowiring in 3.3:
services:
_defaults:
autowire: true
autoconfigure: true
public: false
AppBundle\:
resource: '../../src/AppBundle/*'
exclude: '../../src/AppBundle/{Controller, Entity, Repository}'
AppBundle\Controller\:
resource: '../../src/AppBundle/Controller'
public: true
tags: [ controller.service_arguments ]

SonataAdmin Install issue

I trying to install SonataAdmin on my Symfony Project but at the end of the part-2 of the documention when i'm trying to go on "http://localhost:8000/admin/" I have a error : "You have requested a non-existent service "admin.category" in . (which is being imported from "C:\wamp64\www\Sonata/app/config\routing.yml"). Make sure there is a loader supporting the "sonata_admin" type."
I have no idea why, i give give my all my parameters code maybe it's can help you to understand my problem.
parameters:
#parameter_name: value
services:
# default configuration for services in *this* file
_defaults:
# automatically injects dependencies in your services
autowire: true
# automatically registers your services as commands, event subscribers, etc.
autoconfigure: true
# this means you cannot fetch services directly from the container via $container->get()
# if you need to do this, you can override this setting on individual services
public: false
admin.category:
class: AppBundle\Admin\CategoryAdmin
arguments: [~, AppBundle\Entity\Category, ~]
tags:
- { name: sonata.admin, manager_type: orm, label: Category }
# makes classes in src/AppBundle available to be used as services
# this creates a service per class whose id is the fully-qualified class name
AppBundle\:
resource: '../../src/AppBundle/*'
# you can exclude directories or files
# but if a service is unused, it's removed anyway
exclude: '../../src/AppBundle/{Entity,Repository,Tests}'
# controllers are imported separately to make sure they're public
# and have a tag that allows actions to type-hint services
AppBundle\Controller\:
resource: '../../src/AppBundle/Controller'
public: true
tags: ['controller.service_arguments']
# add more services, or override services that need manual wiring
# AppBundle\Service\ExampleService:
# arguments:
# $someArgument: 'some_value'
`
The indentation is going wrong i add you a picture of this file. Service code
The sonata admin services must be public. In your config, you have default as public: false and that is why you get this error.
So you have 2 options:
Specify public: true for your admin service (in your example file)
Or the better way: create a new services file (eg admin.yml) where you dont use these defaults (the _defaults key with public: false). Public is true by default, so you don't have to specify that by _defaults. In this case you must import your new file in config.yml to work:
Top of app/config.yml
imports:
- { resource: parameters.yml }
- { resource: security.yml }
- { resource: services.yml }
- { resource: admin.yml }
app/admin.yml content:
services:
admin.category:
class: AppBundle\Admin\CategoryAdmin
arguments: [~, AppBundle\Entity\Category, ~]
tags:
- { name: sonata.admin, manager_type: orm, label: Category }
I think you did a mistake by writing your category.admin service in: Sonata/app/config/routing.yml,
instead of Sonata/src/YourAdminBundle/Resources/config/services.yml
Run this command on terminal. Because You might have missed installing
php composer.phar require sonata-project/doctrine-orm-admin-bundle
After This Add this code below to your AppKernel.php
// app/AppKernel.php
public function registerBundles()
{
return array(
// ...
// set up basic sonata requirements
// ...
new Sonata\DoctrineORMAdminBundle\SonataDoctrineORMAdminBundle(),
// ...
);
}

How to use JMSSerializerBundle with Gedmo Timestampable

I am using JMSSerializerBundle with Symfony3. I am using TimestampableEntity trait. What I want to achieve is to receive that trait with JMSSerializer.
use Gedmo\SoftDeleteable\Traits\SoftDeleteableEntity;
use Gedmo\Timestampable\Traits\TimestampableEntity;
class Thread
{
use TimestampableEntity;
use SoftDeleteableEntity;
(...)
}
I have added metadata to the jms_serializer config like this:
config.yml
jms_serializer:
enable_short_alias: false # controls if "serializer" service is aliased to jms_serializer.serializer s
metadata:
directories:
- { path: "%kernel.root_dir%/Resources/Gedmo/serializer", namespace_prefix: 'Gedmo\Timestampable\Traits' }
\app\Reources:
Gedmo\Timestampable\Traits\TimestampableEntity:
exclusion_policy: ALL
properties:
created_at:
expose: true
But it is not working.
I know that I can configure it to use my Thread class and expose all necessary fields but I wonder if it is possible for traits.

MappingException when I set my entity for provider section

I got this error
MappingException: The class 'Telnet\IPBBridgeBundle\Entity\Member' was not found in the chain configured namespaces Telnet\CSSBundle\Entity
I have 2 bundles with entities and several connections into doctrine config
orm:
default_entity_manager: site
entity_managers:
site:
connection: siteConfig
mappings:
CSSBundle: ~
forum:
connection: forumConfig
mappings:
IPBBridgeBundle: ~
and this into provider
providers:
main:
entity: { class: Telnet\IPBBridgeBundle\Entity\Member, property: username }
What I'm doing wrong?
SecurityBundle use default Entity Manager, and Entity, that implements UserInterface must be handled by default Entity Manager.

Resources