Symfony inject parameter in repository - php

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

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%'

Autowire Class with Interface as param in Symfony4

Given a class Publisher like this:
<?php
namespace App\Util\Publisher;
use Symfony\Component\Mercure\Update;
use Symfony\Component\Messenger\MessageBusInterface;
class Publisher
{
protected $topic = null;
protected $bus;
/**
* Publisher constructor.
* #param MessageBusInterface $bus
*/
public function __construct(MessageBusInterface $bus)
{
$this->topic = getenv('TOPIC_MAIN_URL');
$this->bus = $bus;
}
...
}
I would like to autowire it in my controllers like this:
/**
* #Route("/_exp/_exp", name="exp")
*/
public function expAction(Publisher $publisher)
{
...
}
and I added this to my services.yaml:
Symfony\Component\Messenger\MessageBusInterface: ~
App\Util\Publisher\Publisher:
autowire: true
arguments: ['#Symfony\Component\Messenger\MessageBusInterface']
But I get an error:
Cannot instantiate interface Symfony\Component\Messenger\MessageBusInterface
Is that related to the MessageBusInterface or am I doing something wrong with the autowiring. I followed The Symfony docs for autowiring and they seem to be the same?
Thank you!
I believe MessageBusInterface service is already declared by Symfony Messenger component.
Try to remove Symfony\Component\Messenger\MessageBusInterface: ~ from your services.yaml, otherwise you are overriding the default definition.
A note for clarification: MessageBusInterface service does not really exists, it in an alias over the "default bus" service. You can declare other buses, cf documentation

symfony 3 Doctrine LIstener service inject token_storage doesnt work

I have a doctrine listener which needs the get the current logged in user.
class DoctrineListener
{
/**
* #var null|TokenInterface
*/
private $token;
/**
* DoctrineListener constructor.
*
* #param TokenStorageInterface $tokenStorage
*/
public function __construct(TokenStorageInterface $tokenStorage)
{
$this->token = $tokenStorage->getToken();
var_dump($this->token);
}
and in my service.yml:
doctrine.listener:
class: AppBundle\EventListener\DoctrineListener
arguments:
- '#security.token_storage'
public: false
tags:
- { name: doctrine.event_listener, event: preFlush, method: preFlush }
The dump always returns me null when I try to use it in this listener.
I inject the token_storage_service in other services and it works well.
I'm under symfony 3.1, with a rest API.
And i send my authorizations header with Postman.
Can someone tell me what's wrong with my code ?
Thanks in advance.
Try to call $tokenStorage->getToken() in you preFlush method not in the constructor.

Symfony2 extension, replaceArgument

I'm working with Symfony2 and I'm trying to setup a service definition overriding.
The extension is correctly loaded but the service definition not changed.
Here is the code:
class AppExtension extends Extension
{
/**
* {#inheritdoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');
$container->setParameter('app.comment.delay_between', $config['comment']['delay_between']);
$def = $container->getDefinition('app.comment.manager')
->replaceArgument(0, $config['comment']);
$container->setDefinition('app.comment.manager2', $def);
}
/**
* {#inheritdoc}
*/
public function getAlias() {
return 'app';
}
}
The service definition:
app.comment.manager:
class: AppBundle\Comment\CommentManager
arguments:
- []
- "#doctrine.orm.entity_manager"
And the constructor of the class CommentManager:
/**
* CommandManager constructor.
* #param array $config
* #param EntityManagerInterface $em
*/
public function __construct(array $config, EntityManagerInterface $em) {
$this->config = $config;
var_dump($config);
$this->em = $em;
}
And in the controller I call:
$this->get('app.comment.manager');
$this->get('app.comment.manager2');
And I get this result:
/home/nathan/Dev/click-tube/src/symfony/src/AppBundle/Comment/CommentManager.php:37:
array (size=0)
empty
/home/nathan/Dev/click-tube/src/symfony/src/AppBundle/Comment/CommentManager.php:37:
array (size=1)
'delay_between' => int 60
As you can see, I can't modify the app.commment.manager service definition (which is what I want to do). But I can reflect the changes on a extension-created service.
What is the solution to apply the changes on app.comment.manager?
Try inject in the service the parameter defined in the extension, as example:
app.comment.manager:
class: AppBundle\Comment\CommentManager
arguments:
- "%app.comment.delay_between%"
- "#doctrine.orm.entity_manager"
Hope this help
I have had the same issue where the replaceArgument call didn't really modify the arguments given to the constructor of my service. The reason was that my services.yml was already imported in my /app/config/config.yml like:
imports:
- { resource: parameters.yml }
- { resource: security.yml }
- { resource: services.yml }
- { resource: "#MyMightyBundle/Resources/config/services.yml" }
This would override the service definition loaded in met bundle extension file. Removing the service.yml import in my config.yml solved my problem.

Get service container from entity in symfony 2.1 (Doctrine)

How to use entity as service in doctrine (Using Symfony 2.1).
Example usage:
<?php
namespace MyNamespace;
class MyEntity
{
protected $container = NULL;
public function __construct($container)
{
$this->container = $container;
}
/**
* #ORM\PrePersist
*/
public function()
{
// Must call to container and get any parameters
// for defaults sets entity parameters
$this->container->get('service.name');
}
}
As a result, I need to get access to the entire container.
EDIT: THIS IS NOT THE PREFERRED WAY, it's the only way to get service container inside an entity, it's not a good practice, it should be avoided, but this just answers the question.
In case you still want the container and/or repository you can extend a base abastractEntity like this:
<?php
namespace Acme\CoreBundle\Entity;
/**
* Abstract Entity
*/
abstract class AbstractEntity
{
/**
* Return the actual entity repository
*
* #return entity repository or null
*/
protected function getRepository()
{
global $kernel;
if ('AppCache' == get_class($kernel)) {
$kernel = $kernel->getKernel();
}
$annotationReader = $kernel->getContainer()->get('annotation_reader');
$object = new \ReflectionObject($this);
if ($configuration = $annotationReader->getClassAnnotation($object, 'Doctrine\ORM\Mapping\Entity')) {
if (!is_null($configuration->repositoryClass)) {
$repository = $kernel->getContainer()->get('doctrine.orm.entity_manager')->getRepository(get_class($this));
return $repository;
}
}
return null;
}
}
An entity is a data model and should only hold data (and not have any dependencies on services). If you want to modify your model in case of a certain event (PrePersist in your case) you should look into making a Doctrine listener for that. You can inject the container when defining the listener:
services:
my.listener:
class: Acme\SearchBundle\Listener\YourListener
arguments: [#your_service_dependency_or_the_container_here]
tags:
- { name: doctrine.event_listener, event: prePersist }

Categories