Symfony failed to load some dependencies - php

I have a few problems loading use_cases in my project using symfony dependency injection.
The following code belongs to RegisterUserController class.
<?php
namespace App\Infrastructure\Controller\User;
use App\Application\UseCase\User\RegisterUserUseCase;
use Symfony\Component\HttpFoundation\Request;
/**
* Class RegisterUserController
*
* #package App\Infrastructure\Controller\User
* #author Ismael Moral <jastertdc#gmail.com>
*/
final class RegisterUserController
{
/**
* #var RegisterUserUseCase
*/
protected $registerUserUseCase;
/**
* RegisterUserController constructor.
*
* #param RegisterUserUseCase $registerUserUseCase
*/
public function __construct(
RegisterUserUseCase $registerUserUseCase
) {
$this->registerUserUseCase = $registerUserUseCase;
}
}
This is my services.yml where I have defined all the services in my project.
parameters:
databaseWriterDsn: '%env(DB_WRITER_DSN)%'
databaseWriterUsername: '%env(DB_WRITER_USERNAME)%'
databaseWriterPassword: '%env(DB_WRITER_PASSWORD)%'
services:
_defaults:
autowire: false # Automatically injects dependencies in your services.
autoconfigure: false # Automatically registers your services as commands, event subscribers, etc.
PdoWriter:
class: PDO
arguments: ['%databaseWriterDsn%', '%databaseWriterUsername%', '%databaseWriterPassword%']
MysqlPdoUserWriterRepository:
class: App\Infrastructure\Repository\User\MysqlPdoUserWriterRepository
arguments: ['#PdoWriter']
PasswordFactory:
class: App\Infrastructure\Factory\User\PasswordFactory
arguments: []
UsernameFactory:
class: App\Infrastructure\Factory\User\UsernameFactory
arguments: []
UuidFactory:
class: App\Shared\Infrastructure\UuidFactory
arguments: []
UserFactory:
class: App\Infrastructure\Factory\User\UserFactory
arguments: ['#UuidFactory', '#UsernameFactory', '#PasswordFactory']
RegisterUserUseCase:
class: App\Application\UseCase\User\RegisterUserUseCase
arguments: ['#MysqlPdoUserWriterRepository', '#UserFactory']
RegisterUserController:
class: App\Infrastructure\Controller\User\RegisterUserController
arguments: ['#RegisterUserUseCase']
tags: ['controller.service_arguments']
This is the error I get when I'm trying to do a curl request to /user/register/.
Controller "App\Infrastructure\Controller\User\RegisterUserController" has required constructor arguments and does not exist in the container. Did you forget to define such a service?
If I changed the controller definition using this, I can get it to work. So I have to specificate fullnamespace for controller definition.
App\Infrastructure\Controller\User\RegisterUserController:
class: App\Infrastructure\Controller\User\RegisterUserController
arguments: ['#RegisterUserUseCase']
tags: ['controller.service_arguments']

Related

Symfony 4 error: Unused binding "$projectDir" in service

While updating from Symfony 3.4 to 4.1, when I php bin/console, I got the following error.
I want to take parameters in a url reference way.
What is the cause?
https://symfony.com/blog/new-in-symfony-4-1-getting-container-parameters-as-a-service
Error code
Unused binding "$projectDir" in service "common.parameterService".
config/services.yaml
parameters:
parameter_name: XXX
services:
_defaults:
autowire: false
autoconfigure: false
public: false
bind:
$projectDir: '%kernel.project_dir%'
common.parameterService:
class: AppBundle\Model\Service\ParameterService
arguments: [ "#service_container" ]
AppBundle/Model/Service/ParameterService.php
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use AppBundle\Model\Service\BaseService;
/**
*
*/
class ParameterService extends BaseService
{
private $params;
public function __construct(ParameterBagInterface $params)
{
$this->params = $params;
}
/**
*
* #param string
* #return mixed
*/
public function getParameter()
{
return $this->params->get('parameter_name');
}
It means you have declared this:
bind:
$projectDir: '%kernel.project_dir%'
but have not injected the $projectDir in the ParameterService nor in any other services in that file.
You can delete these two lines:
bind:
$projectDir: '%kernel.project_dir%'

Symfony 5.1 creating extension with services

I'm trying to create a config for an extension which will give me 1 service with all dependencies injected but so far I was unable to do it. My steps were this to follow those steps in this web page https://symfony.com/doc/current/bundles/extension.html but I still get an error that I don't have service
Cannot autowire service "App\Command\ParserConfigAutoCreationCommand": argument "$nominatimGeocode" of method "__construct()" references class "XYZ\Service\NominatimGeocode" but no such service exists.
my services.yml file:
services:
# default configuration for services in *this* file
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
bind:
Geocoder\Provider\Provider $nominatimProvider: '#bazinga_geocoder.provider.nominatim'
Geocoder\Provider\Provider $googleProvider: '#bazinga_geocoder.provider.google'
XYZ\Service\NominatimGeocode:
arguments: [ '#bazinga_geocoder.provider.nominatim' ]
and my GeoCodeExtension.php file:
<?php
declare(strict_types=1);
namespace XYZ\DependencyInjection;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
/**
* This is the class that loads and manages your bundle configuration.
*
* To learn more see {#link http://symfony.com/doc/current/cookbook/bundles/extension.html}
*/
class GeoCodeExtension extends Extension
{
/**
* {#inheritdoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
// $configuration = new Configuration();
// $config = $this->processConfiguration($configuration, $configs);
$loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');
}
}
do I need to add additional files or something?
EDIT:
class NominatimGeocode
{
/**
* #var \Geocoder\Provider\Provider
*/
private $nominatimProvider;
private $checkPostCode = false;
/**
* Geo Nominatim constructor.
*
* #param \Geocoder\Provider\Provider $nominatimProvider
*/
public function __construct(Provider $nominatimProvider)
{
$this->nominatimProvider = $nominatimProvider;
}
.
.
.
so I'm injecting it with right param name.
Your class should inject the Geocoder\Provider\Provider $nominatimProvider dependency if you want type binding to work.
Mind the variable's name must match the one in the bind section too.
Your is totally different:
XYZ\Service\NominatimGeocode $nominatimGeocode

Symfony Flex - How to create a database mysql connection

I am a beginner on Symfony.
I am trying to create a class to use my database (mysql). But I can not succeed. Can you help me ?
Here is my current class:
<?php
namespace App\Database;
use Doctrine;
use Doctrine\DBAL\Connection;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class DatabaseApi extends AbstractController
{
/**
* #var Connection
*/
protected $database = null;
protected static $instance = null;
/**
* DatabaseApi constructor.
*/
protected function __construct()
{
$database = $this->container->get('database');
$this->database = $database;
}
public static function getInstance()
{
self::$instance = new self();
return self::$instance;
}
private function __clone()
{
}
/**
* #param $authentication_key
* #return mixed
* #throws Doctrine\DBAL\DBALException
*/
public function select_authentication_key($authentication_key)
{
$auth_key_query = $this->database->prepare('CALL Verify_authentication_key(:authentication_key)');
$auth_key_query->bindValue('authentication_key', $authentication_key);
$auth_key_query->execute();
$results = $auth_key_query->fetchAll(\PDO::FETCH_ASSOC);
return $results[0];
}
}
I tried to create it with everything I could find on the Internet. Unfortunately, I get an error "Call to a member function get() on null".
There is my services.yaml file :
parameters:
database_connection: default
services:
# default configuration for services in *this* file
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
public: false # Allows optimizing the container by removing unused services; this also means
# fetching services directly from the container via $container->get() won't work.
# The best practice is to be explicit about your dependencies anyway.
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: '../src/*'
exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
# controllers are imported separately to make sure services can be injected
# as action arguments even if you don't extend any base controller class
App\Controller\:
resource: '../src/Controller'
tags: ['controller.service_arguments']
# add more service definitions when explicit configuration is needed
# please note that last definitions always *replace* previous ones
database:
alias: doctrine.dbal.%database_connection%_connection
And is is how I try to call the fonction :
$database = DatabaseApi::getInstance();
$result = null;
try{
$result = $database->select_authentication_key("1111-1111-1111-1111");
}catch (Exception $e){
print($e);
}
print_r($result);

__construct() must implement interface error

I use symfony2 and SonataAdminBundle, SonataMediaBundle and SonataClassificationBundle
Now I want custmize setting for admin panel, but I have this error.
[Symfony\Component\Config\Exception\FileLoaderLoadException]
Catchable Fatal Error: Argument 5 passed to Sonata\MediaBundle\Admin\BaseMe
diaAdmin::__construct() must implement interface Sonata\ClassificationBundl
e\Model\CategoryManagerInterface, none given, called in /Users/whitebear/Codin
gWorks/httproot/myapp/app/cache/de_/appDevDebugProjectContaine_.php on l
ine 9494 and defined in . (which is being imported from "/Users/whitebear/Codi
ngWorks/httproot/myapp/app/config/routing.yml").
What I have done is two things.
made DependencyInjection file
Application/Sonata/MediaBundle/DependencyInjection/ApplicationSonataMediaExtension.php
<?php
namespace Application\Sonata\MediaBundle\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;
/**
* This is the class that loads and manages your bundle configuration
*
* To learn more see {#link http://symfony.com/doc/current/cookbook/bundles/extension.html}
*/
class ApplicationSonataMediaExtension extends Extension
{
/**
* {#inheritDoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');
}
}
then made services.yml for admin
Application/Sonata/MediaBundle/Resources/config/services.yml
#Disable gallery & media menu from admin panel
services:
sonata.media.admin.media:
class: %sonata.media.admin.media.class%
tags:
- { name: sonata.admin, manager_type: orm, show_in_dashboard: false, label_catalogue: %sonata.media.admin.media.translation_domain% , label_translator_strategy: sonata.admin.label.strategy.underscore }
arguments:
- ~
- %sonata.media.admin.media.entity%
- %sonata.media.admin.media.controller%
- "#sonata.media.pool"
- %sonata.classification.manager.category% # add here.
calls:
- [setModelManager, ["#sonata.media.admin.media.manager"]]
- [setTranslationDomain, [%sonata.media.admin.media.translation_domain%]]
- [setTemplates, [{ inner_list_row: SonataMediaBundle:MediaAdmin:inner_row_media.html.twig , base_list_field: SonataAdminBundle:CRUD:base_list_flat_field.html.twig , list: SonataMediaBundle:MediaAdmin:list.html.twig , edit: SonataMediaBundle:MediaAdmin:edit.html.twig }]]
sonata.media.admin.gallery:
class: %sonata.media.admin.gallery.class%
tags:
- { name: sonata.admin, manager_type: orm, show_in_dashboard: false, label_catalogue: %sonata.media.admin.media.translation_domain% , label_translator_strategy: sonata.admin.label.strategy.underscore }
arguments:
- ~
- %sonata.media.admin.gallery.entity%
- %sonata.media.admin.gallery.controller%
- "#sonata.media.pool"
calls:
- [setTranslationDomain, [%sonata.media.admin.media.translation_domain%]]
- [setTemplates, [{ list: SonataMediaBundle:GalleryAdmin:list.html.twig }]]
in Sonata\MediaBundle\Admin\BaseMediaAdmin
abstract class BaseMediaAdmin extends AbstractAdmin
{
/**
* #var Pool
*/
protected $pool;
/**
* #var CategoryManagerInterface
*/
protected $categoryManager;
/**
* #param string $code
* #param string $class
* #param string $baseControllerName
* #param Pool $pool
* #param CategoryManagerInterface $categoryManager
*/
public function __construct($code, $class, $baseControllerName, Pool $pool, CategoryManagerInterface $categoryManager)
{
parent::__construct($code, $class, $baseControllerName);
$this->pool = $pool;
$this->categoryManager = $categoryManager;
}
Thanks to #mdma
I figured out I must path 5th parameters as CategoryManagerInterface to BaseMediaAdmin constructor.
then I updated the service.yml but I have error like this.
[Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException]
The service "sonata.media.admin.media" has a dependency on a non-existent p
arameter "sonata.classification.manager.category". Did you mean one of thes
e: "sonata.classification.manager.category.class", "sonata.classification.m
anager.tag.class", "sonata.classification.manager.context.class", "sonata.c
lassification.manager.tag.entity", "sonata.classification.manager.category.
entity", "sonata.classification.manager.context.entity", "sonata.classifica
tion.admin.category.class"?
It solved.
I changed this sentence inservices.yml
- %sonata.classification.manager.category% to "#sonata.classification.manager.category"
The error say : Argument 5 doesn't exist in Sonata\MediaBundle\Admin\BaseMediaAdmin::__construct()
So, look at arguments in you sonata.media.admin.media service configuration. There are only 4 arguments. You need to add the 5th.
In bundle config (https://github.com/sonata-project/SonataMediaBundle/blob/master/Resources/config/doctrine_orm_admin.xml), there are 5 arguments :
<argument/>
<argument>%sonata.media.admin.media.entity%</argument>
<argument>%sonata.media.admin.media.controller%</argument>
<argument type="service" id="sonata.media.pool"/>
<argument type="service" id="sonata.media.manager.category" on-invalid="null"/>
So, I think you can add #sonata.media.manager.category as 5th argument.

Symfony inject parameter in repository

I need inject parameter in repository, I try add calls to service repo but my call function not call when I call some function from my repo
app.repository.file:
class: "%app.repository.file.class%"
factory_service: doctrine.orm.default_entity_manager
factory_method: getRepository
arguments:
- "%app.entity.file.class%"
calls:
- [setParam,['%md5_suffix%']]
setParam not call
private $param;
public function setParam($param)
{
$this->param = $param;
}
param have null
and I try use JMSDiExtraBundle
/**
* #DI\InjectParams({
* "param" = #DI\Inject("%md5_suffix%"),
* })
*/
public function setParam($param)
{
$this->param = $param;
}
but have in property %md5_suffix% like string, not property from parameters.yml :)
how to inject parameter from parameters yml in repo ?
Factory_service is deprecated in 2.8. Instead, try using something like:
app.repository.file:
class: Doctrine\ORM\EntityRepository
factory: ['#doctrine.orm.entity_manager', getRepository]
arguments:
- "%app.entity.file.class%"
calls:
- [setParam,['%md5_suffix%']]
I create another service
economy.param_helper:
class: "%economy.param_helper.class%"
arguments:
- "%md5_suffix%"
and inject this service in repo like this
/**
* #var ParamHelper
*/
private $param;
/**
* #DI\InjectParams({
* "param" = #DI\Inject("economy.param_helper"),
* })
*/
public function setParam(ParamHelper $param)
{
$this->param = $param;
}
and call $md5Suffix = $this->param->getMd5Suffix();
But I'am not sure this is right way

Categories