Entity manager symfony 2 - symfony

I'm still trying to use the cart bundle from sylius,
i'm getting this error
Catchable Fatal Error: Argument 1 passed to myproject\Cart\ItemResolver::__construct() must be an instance of Doctrine\ORM\EntityManager, none given, called in myproject\cache\dev\appDevDebugProjectContainer.php on line 3625 and defined in myproject\Cart\ItemResolver.php line 19
500 Internal Server Error - ContextErrorException
in fact i have seen this in the debug stack trace
at ItemResolver ->__construct ()
protected function getcompany_CartItemResolverService()
{
return $this->services['company_item_resolver'] = new \myproject\Cart\ItemResolver();
}
i suppose there is a problem with my config.
my service.yml looks like that
company.cart_item_resolver:
class: myproject\Cart\ItemResolver
argument: ['#doctrine.orm.entity_manager']
and my config.yml for doctrine looks like:
orm:
auto_generate_proxy_classes: "%kernel.debug%"
entity_managers:
default:
mappings:
ApplicationSonataUserBundle: ~
SonataUserBundle: ~
FOSUserBundle: ~
companyBundle: ~
ApplicationSonataMediaBundle: ~
SonataMediaBundle: ~
SonataNotificationBundle: ~
ApplicationSonataNotificationBundle: ~
SyliusCartBundle: ~
I don't have automapping enabled, i suppose my argument in services.yml should be false, but i don't manage to have it right.
Could you help me?

Try this code in your service.yml:
company.cart_item_resolver:
class: myproject\Cart\ItemResolver
arguments: ['#doctrine.orm.entity_manager']
It should fix your issue. More info about Injecting Services: http://symfony.com/doc/current/book/service_container.html#referencing-injecting-services

Related

Symfony #Paramconverter works over autowiring

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

FOSElasticaBundle: Root mapping definition has unsupported parameters:

I get the following error when populating elastic search:
Root mapping definition has unsupported parameters: [product : {dynamic_date_formats=[], _meta={model=App\Entity\Product}, properties={name={type=text}, description={type=text}}}] [reason: Failed to parse mapping [_doc]: Root mapping definition has unsupported parameters: [product : {
dynamic_date_formats=[], _meta={model=App\Entity\Product}, properties={name={type=text}, description={type=text}}}]]
Basically, I followed only the documentation ( https://github.com/FriendsOfSymfony/FOSElasticaBundle/blob/master/doc/setup.md ) and changed userto product and the corresponding fields in my App\Entity\Product.
fos_elastica.yaml:
fos_elastica:
clients:
default: { host: localhost, port: 9200 }
indexes:
app:
types:
product:
properties:
name: ~
description: ~
persistence:
driver: orm
model: App\Entity\Product
provider: ~
finder: ~
Are you using Elasticsearch version 7? I had the same problem today and think that it is related to the Elasticsearch version you are using.
If I install Elasticsearch version 6, everything is working fine.
I'm not an Elasticsearch expert, but there are probably some breaking changes in version 7 with which FOSElasticaBundle is not yet compatible.

Multiple entity managers in Symfony 3.3 seams to not work as service arguments

I have configured two connections to the database. One connection is called user and other is called client. This is the configuration in the config.yml file:
doctrine:
dbal:
default_connection: client
connections:
client:
driver: pdo_mysql
host: '%client_database_host%'
port: '%client_database_port%'
dbname: '%client_database_name%'
user: '%client_database_user%'
password: '%client_database_password%'
charset: UTF8
mapping_types:
enum: string
user:
driver: pdo_mysql
host: '%user_database_host%'
port: '%user_database_port%'
dbname: '%user_database_name%'
user: '%user_database_user%'
password: '%user_database_password%'
charset: UTF8
mapping_types:
enum: string
orm:
auto_generate_proxy_classes: '%kernel.debug%'
default_entity_manager: ~
entity_managers:
client:
naming_strategy: doctrine.orm.naming_strategy.underscore
mappings:
ProjectModelBundle: ~
connection: client
user:
naming_strategy: doctrine.orm.naming_strategy.underscore
mappings:
BaseModelBundle: ~
ProjectModelBundle: ~
connection: user
But I am always getting the first entity manager no matter what. This is how I am using entity manager's in services:
# BASE
htec.project_model_bundle.repository.database.client_base:
class: Project\BaseModelBundle\Repository\Database\DatabaseRepository
arguments: ['#service_container', '#doctrine.orm.client_entity_manager', '#form.factory']
htec.project_model_bundle.repository.database.user_base:
class: Project\BaseModelBundle\Repository\Database\DatabaseRepository
arguments: ['#service_container', '#doctrine.orm.user_entity_manager', '#form.factory']
But no matter what I do, I always get the first entity manager that I have defined under orm->entity_managers settings. For example if configure orm like this:
orm:
auto_generate_proxy_classes: '%kernel.debug%'
default_entity_manager: ~
entity_managers:
client:
naming_strategy: doctrine.orm.naming_strategy.underscore
mappings:
ProjectModelBundle: ~
connection: client
user:
naming_strategy: doctrine.orm.naming_strategy.underscore
mappings:
BaseModelBundle: ~
ProjectModelBundle: ~
connection: user
I will always get the client entity manager even if I supply '#doctrine.orm.user_entity_manager' as service argument.
If I configure orm like this:
orm:
auto_generate_proxy_classes: '%kernel.debug%'
default_entity_manager: ~
entity_managers:
user:
naming_strategy: doctrine.orm.naming_strategy.underscore
mappings:
BaseModelBundle: ~
ProjectModelBundle: ~
connection: user
client:
naming_strategy: doctrine.orm.naming_strategy.underscore
mappings:
ProjectModelBundle: ~
connection: client
I will always get the user entity manager even if I supply '#doctrine.orm.client_entity_manager' as service argument.
What am I doing wrong here?
Recently I had a similar issue. The comment of #dbrumann gave me a good clue for resolve it. I used the next approach:
If you use the console command debug:autowiring you will see there is a service aliased as doctrine.
Doctrine\Common\Persistence\ManagerRegistry alias to doctrine
You can get access to that service in your target class by type-hinting, put the name of the service class (or interface) as argument in the constructor of your target class.
Now you can access all the methods of the service in your target class, by using the method getManager() you will get any of your managers:
use Doctrine\Common\Persistence\ManagerRegistry;
$protected $managerRegistry;
public function __construct(ManagerRegistry $managerRegistry)
{
$this->managerRegistry = $managerRegistry;
}
public function foo()
{
// asuming your managers names are default and second
$firstManager = $this->managerRegistry->getManager('default');
$secondManager = $this->managerRegistry->getManager('second');
}
So you defined a service named DatabaseRepository that exists in two variations. At one point it receives the 'client' entity manager, and at another point it receives 'user' entity manager?
I think it always returns you the 'client' manager most probably because that is the first time the service has been defined for the service container. It does not matter what you define it afterwards in the same .yml code.
Now, there is a big "why" rhetoric question for you. Why didn't you define two service classes, each for particular manager? If you really had to do it that way, that indicates some serious design problems in the remaining code of your Project.
Another suggestion: Do name your classes somewhat more descriptive. An entity manager and repository class certainly do something about a database. Naming classes, properties, variables in a proper way I find to be one of the most challenging part of the work, but it makes our lives easier.
Btw. Avoid passing entire container as service parameter:
arguments: ['#service_container',
because it's too expensive resources wise.

FOSElasticaBundle & Propel

I have installed FOSElasticaBundle "friendsofsymfony/elastica-bundle": "^3.2"
(with symfony 2.8.8) and tried to define this simple configuration
fos_elastica:
clients:
default: { host: %elastic_host%, port: %elastic_port% }
indexes:
project:
types:
item:
mappings:
id: { type: integer }
itemno: { type: string }
persistence:
driver: propel
model: Model\Item\Item
provider: ~
Unfortunately I'm getting following error
The parent definition "fos_elastica.listener.prototype.propel" defined
for definition "fos_elastica.listener.project.item" does not
exist.
As I read through the documentation, there is no "listener" available for propel - that's why I'm a little bit confused about the error message. I already tried to define the missing definition, but with no result.
Is it necessary to define any class/service as provider for the type? In the documentation I couldn't find anything about that?
Thanks.

FosElasticaBundle: how to dump the actual JSON passed to ElasticSearch?

I am using FosElasticaBundle in a Symfony project. I configured my mappings but I get exception "expected a simple value for field [_id] but found [START_OBJECT]]".
I'd like to see the actual JSON created by FosElasticaBundle so I can directly test it against my ElasticSearch server, and understand more about the exception.
According to FosElastica documentation, everything should be logged when debug mode is enabled (i.e. in DEV environment) but I can't see this happening; I only see Doctrine queries, but no JSON.
How can I dump the JSON created by FosElasticaBundle?
Update: mappings
# FOSElasticaBundle
fos_elastica:
clients:
default: { host: %elasticsearch_host%, port: %elasticsearch_port%, logger: false }
indexes:
app:
types:
user:
mappings:
name: ~
surname: ~
persistence:
driver: orm
model: AppBundle\Entity\User
provider: ~
listener: ~
finder: ~
I think you should only set your logger to true instead of false
fos_elastica:
clients:
default:
host: %elasticsearch_host%
port: %elasticsearch_port%
logger: true <---- set true here
...

Resources