I'm trying to split one big service.yaml to few smaller files. In origin service.yaml I had
services:
_defaults:
autowire: true
autoconfigure: true
public: false
App\Domain\Country\Infrastructure\Repository\CountryRepository:
public: true
class: App\Domain\Country\Infrastructure\Repository\CountryRepository
factory: ["#doctrine.orm.default_entity_manager", getRepository]
arguments: [App\Domain\Country\Entity\Country]
Then I added import at the begining service.yam
imports:
- {resource: services/repositories.yaml}
repositories.yaml
services:
_defaults:
autowire: true
autoconfigure: true
public: true
App\Domain\Country\Infrastructure\Repository\CountryRepository:
factory: ["#doctrine.orm.default_entity_manager", getRepository]
arguments: [App\Domain\Country\Entity\Country]
After that I started to get error
Cannot autowire service "App\Domain\Country\Infrastructure\Repository\Count
ryRepository": argument "$class" of method "Doctrine\ORM\EntityRepository::
__construct()" references class "Doctrine\ORM\Mapping\ClassMetadata" but no
such service exists.
What's wrong there?
https://pastebin.com/Uy85YJmc (service.yaml)
https://pastebin.com/ZesAw3sD (repositories.yaml)
You should not need to define the repository for the purposes of autowiring.
services.yaml:
services:
_defaults:
autowire: true
autoconfigure: true
public: false
App\:
resource: '../src/*'
exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
App\Controller\:
resource: '../src/Controller'
tags: ['controller.service_arguments']
Entity\Country:
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="App\Repository\CountryRepository")
*/
class Country
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $name;
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
}
Repository\CountryRepository:
<?php
namespace App\Repository;
use App\Entity\Country;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Symfony\Bridge\Doctrine\RegistryInterface;
/**
* #method Country|null find($id, $lockMode = null, $lockVersion = null)
* #method Country|null findOneBy(array $criteria, array $orderBy = null)
* #method Country[] findAll()
* #method Country[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class CountryRepository extends ServiceEntityRepository
{
public function __construct(RegistryInterface $registry)
{
parent::__construct($registry, Country::class);
}
}
And finally, your service:
<?php
namespace App\Service;
use App\Repository\CountryRepository;
class ExampleService
{
/**
* #var CountryRepository
*/
private $repository;
/**
* #param CountryRepository $repository
*/
public function __construct(CountryRepository $repository)
{
$this->repository = $repository;
}
}
The autowiring will see that you've injected that CountryRepository into the ExampleService constructor and handle the rest.
Use named arguments instead :
repositories.yaml
services:
App\Domain\Country\Infrastructure\Repository\CountryRepository:
factory: ["#doctrine.orm.default_entity_manager", getRepository]
arguments:
$class: '#App\Domain\Country\Entity\Country'
Related
I've got two services, those get Doctrine injected via the constructor. When loading an entity in an EventListener and giving it ot service the entity is detached.
When im providing the DoctrineEntityManager from an EventListener to service, the entity is still managed.
class Listener implements EventSubscriberInterface
{
/** #var EntityManagerInterface */
private $em;
/** #var Service */
private $service;
/** #var EventDispatcherInterface */
private $eventDispatcher;
public function __construct(
EntityManagerInterface $em,
Service $service,
EventDispatcherInterface $eventDispatcher
) {
$this->em = $em;
$this->eventDispatcher = $eventDispatcher;
$this->service = $service;
}
public function listenerFunction(Event $event)
{
$user = $event->getEntity()->getUser();
var_dump($this->em->contains($user)); // true
$this->service->func($this->em, $user);
}
}
class Service
{
/** #var EventDispatcherInterface */
private $eventDispatcher;
public function __construct(EntityManagerInterface $em, EventDispatcherInterface $eventDispatcher)
{
$this->em = $em;
$this->eventDispatcher = $eventDispatcher;
}
public function func($em, $user)
{
var_dump($this->em->contains($user)); // false
var_dump($em->contains($user)); // true
}
}
the services yaml
services:
_defaults:
autowire: true
autoconfigure: true
public: true
App\Payment\Command\:
resource: "%kernel.project_dir%/src/Payment/Command/*"
tags:
- { name: console.command }
App\Payment\Service\:
resource: "%kernel.project_dir%/src/Payment/Service/*"
App\Payment\Controller\:
resource: "%kernel.project_dir%/src/Payment/Controller/*"
App\Payment\EventSubscriber\:
resource: "%kernel.project_dir%/src/Payment/EventSubscriber/*"
tags:
- { name: kernel.event_subscriber }
The EntityManager in the service should contain the $user entity. Im thinking symfony is creating a second instance of the entitymanagerinterface here, but the says there is only one instance of each item (https://symfony.com/doc/current/service_container/shared.html)
Fixed by updating all packages (composer update) yay ;D
I have problem with my code. I have EventSubscriber:
<?php
namespace App\EventSubscriber;
use App\Service\PostService;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
class NewPostSubscriber implements EventSubscriberInterface
{
/**
* #var PostService $postService
*/
private $postService;
/**
* #param PostService $postService
*/
public function constructor($postService)
{
$this->postService = $postService;
}
public static function getSubscribedEvents()
{
return [
KernelEvents::REQUEST => 'postNotification'
];
}
public function postNotification(RequestEvent $event)
{
$request = $event->getRequest();
if ('app_post_createpost' != $request->get('_route')) {
return;
}
$post = $this->postService->deletePost(3);
}
}
and i inject for him PostService, but when i send request to post endpoint then i receive exception witj code 500 and text
Call to a member function deletePost() on null
In my services.yaml i have
services:
# default configuration for services in *this* file
_defaults:
autowire: true
autoconfigure: true
App\:
resource: '../src/*'
exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
App\Controller\:
resource: '../src/Controller'
tags: ['controller.service_arguments']
app.post_service:
class: App\Service\PostService
arguments: ['#doctrine.orm.entity_manager']
autowire: true
app.new_post_subscriber:
class: App\EventSubscriber\NewPostSubscriber
arguments: ['#app.post_service']
autowire: false
tags:
- { name: kernel.event_subscriber }
I have method deletePost in my PostService. I don't know what is wrong, i have service and deletePost method, service is inject to subscriber but still not working.
In symfony 4 you don't need declare your services in services.yaml. You can do like this
private $postService;
/**
* #param PostService $postService
*/
public function __construct(PostService $postService)
{
$this->postService = $postService;
}
And in your PostService
private $em;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
}
Also you have wrong name of your constructor constructor must be __construct
I'm trying to translate a custom constraint message:
<?php
namespace App\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Translation\TranslatorInterface;
/**
* #Annotation
*/
class YoutubeLink extends Constraint
{
public $message = '"{{ string }}" is not a valid Youtube link';
/**
* #var TranslatorInterface
*/
private $translator;
public function __construct($translator)
{
$this->translator = $translator;
}
}
I'm injecting the translator:
services:
App\Validator\Constraints\YoutubeLink:
arguments: [ "#translator" ]
tags:
- { name: validator.constraint_validator, alias: validator.youtube_link }
But how to translate the message now with the argument?
Just put the translation key in the entity since $message is public:
/**
* #var string
*
* #ORM\Column(type="string")
* #AppAssert\YoutubeLink(
* message = "link.invalid_youtube"
* )
*/
protected $url;
I have upgraded the symfony 2.8 project to symfony 3.4. After fixing some issue I am getting the above issue when loading the page which has form with filters.
The app_filter attribute is configured in my form.yml file inside the bundle/resources/config directory and it looks like the below,
parameters:
app.abstract_filter.form.type.class: AppBundle\Form\Type\Filter\FilterType
services:
app.abstract_filter.form.type:
class: '%app.abstract_filter.form.type.class%'
arguments:
- '#translator.default'
- '#doctrine.orm.entity_manager'
tags:
- { name: form.type, alias: app_filter}
app.abstract_filter.form:
class: Symfony\Component\Form\Form
factory: ['#form.factory', createNamed]
arguments:
- 'app_filter'
- '%app.abstract_filter.form.type.class%'
app_abstract_fitler_form_type class:
namespace AppBundle\Form\Type\Filter;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Translation\Translator;
class FilterType extends AbstractType
{
/** #var Translator */
protected $translator;
/** #var EntityManager */
protected $entityManager;
public function __construct(Translator $translator, EntityManager $entityManager)
{
$this->translator = $translator;
$this->entityManager = $entityManager;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
}
public function getName()
{
return 'app_filter';
}
}
I try to use softdelete in my application, but it doesn't work. When I delete an entity, it's also deleted from the database.
I installed "stof/doctrine-extensions-bundle": "1.2.*#dev" and added it to the Kernel.
My Configuration:
stof_doctrine_extensions:
orm:
default:
...
softdeleteable: true
doctrine:
...
orm:
filters:
softdeleteable:
class: Gedmo\SoftDeleteable\Filter\SoftDeleteableFilter
enabled: true
My YML-Definition:
...\Entity\Person:
type: entity
table: person
id:
id:
...
fields:
salutation:
type: string
length: 255
...
deletedAt:
type: datetime
nullable: true
My Entity:
<?php
namespace ...\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* Person
* #Gedmo\SoftDeleteable(fieldName="deletedAt")
*/
class Person
{
...
/**
* #var \DateTime
*/
private $deletedAt;
...
/**
* Set deletedAt
*
* #param \DateTime $deletedAt
* #return NaturalPerson
*/
public function setDeletedAt($deletedAt)
{
$this->deletedAt = $deletedAt;
return $this;
}
/**
* Get deletedAt
*
* #return \DateTime
*/
public function getDeletedAt()
{
return $this->deletedAt;
}
}