Symfony 4 - Convert XML to YAML - symfony

I'm trying to install FosMessageBundle, without FosUserBundle.
For that, in the doc, we have to create a new service and use it into our services.yaml file
But in the doc, their declaration is in XML, and I can't translate him to YAML:
<!-- app/config/services.xml -->
<service id="app.user_to_username_transformer" class="AppBundle\Form\DataTransformer\UserToUsernameTransformer">
<argument type="service" id="doctrine" />
</service>
<service id="fos_user.user_to_username_transformer" alias="app.user_to_username_transformer" />
I tried this :
app.user_to_username_transformer:
class: 'App\Form\DataTransformer\UserToUsernameTransformer'
arguments:
type: "service"
id: "doctrine"
fos_user.user_to_username_transformer:
alias: "app.user_to_username_transformer"
But I don't know if it's good

in yaml a service type="service" is prefixed with #. So your xml definition translates to
app.user_to_username_transformer:
class: App\Form\DataTransformer\UserToUsernameTransformer
arguments:
- '#doctrine'
fos_user.user_to_username_transformer:
alias: "#app.user_to_username_transformer"
More details in the docs
But if you have autowire configured and your argument is typehinted properly with Doctrine\Bundle\DoctrineBundle\Registry all you need is to alias your transformer
fos_user.user_to_username_transformer:
alias: "#App\Form\DataTransformer\UserToUsernameTransformer"

Related

Inject entity repository as dependency in Symfony

I have a Symfony project where I want to inject an entity repository into a service. The service definition is in XML format.
<service id="vendorname_shop.checkout_data_manager" class="Vendorname\ShopBundle\Checkout\CheckoutDataManager">
<argument type="service" id="security.token_storage" />
<argument type="service" id="session" />
<argument type="service" id="vendorname_shop.repository.pickup_point" />
<argument type="service" id="vendorname_shop.repository.order_payment_method" />
<argument type="service" id="vendorname_shop.repository.billing_address" />
</service>
I'd like to make vendorname_shop.repository.billing_address service to be a simple entity repository (not a custom class that I wrote, but the result of
EntityManager->getRepository(Vendorname\ShopBundle\Entity\BillingAddress::class)
method call), so I used the factory syntax in the xml, but I keep recieving error messages when Symfony tries to evaluate the argument:
<service id="vendorname_shop.repository.billing_address" class="Doctrine\ORM\EntityRepository">
<factory service="doctrine.orm.entity_manager" method="getRepository" />
<argument type="expression">Vendorname\ShopBundle\Entity\BillingAddress::class</argument>
</service>
The code above gives me Unexpected character "\" around position 11.
You can try something like this:
services:
my_service_name:
class: AppBundle\Controller\MyServiceName
arguments: ["#=service('doctrine.orm.entity_manager').getRepository('AppBundle:MyEntity')"]
Then you have build a service for your repository.
public function __construct(MyEntityRepository $repository) {
$this->repository = $repository;
}
But i think there are a lot more possibilities.
http://www.zuellich.de/blog/2016/03/symfony-3-inject-entity-repository-into-service-controller.html
here is another solution. I've replaced my answer with some of that solution it is a bit better.
As Cerad said, if I use a fully qualified name, the ::class is totally useless!
In addition changing the argument type to string solved the problem!
<argument type="string">Vendorname\ShopBundle\Entity\BillingAddresss</argument>

Symfony Dependency Injection XML to YAML

How i can define service look like this in YAML pattern?
XML:
<service id="my_service" class="MyClass">
<!-- XML FORMAT NO NEED TO DEFINE THIS ARGUMENT IN OTHER SERVICE -->
<argument type="service">
<service class="OtherFacotryServiceClass" factory-service="other_facoty_service" factory-method="get">
<argument>other_service_param</argument>
</service>
</argument>
</service>
This will output in PHP: (in a container dump)
protected function getMYServiceService()
{
return $this->services['my_service'] = new \MyClass($this->get('other_facoty_service')->get('other_service_param'));
}
EDITED: Full (long) yaml definition.
services:
an_other_service:
public: false
class: OtherFacotryServiceClass
factory_service: other_facoty_service
factory_method: get
arguments: [other_service_param]
my_service:
class: MyClass
arguments: [#an_other_service]
How i can define similar XML like:
services:
# THIS'S WRONG FORMAT!!
my_service:
class: MyClass
arguments:
-
class: OtherFacotryServiceClass
factory_service: other_facoty_service
factory_method: get
arguments: [other_service_param]
In your services.yml
services:
my_service_factory:
class: OtherFactoryServiceClass
my_service:
class: MyClass
factory_service: my_service_factory
factory_method: get
arguments: [other_service_param] # arguments are injected in "OtherFactoryServiceClass::get"
Source

Symfony ~2.4 composer update swiftmailer.mailer.default.transport.real dependency exception

After composer update, i started getting error message:
The service "swiftmailer.mailer.default.transport.real" has a dependency on a non-existent service "swiftmailer.transport.buffer"
After bit of research i found solutions:
http://error.bengtuo.com/page/13489.html
Symfony2 Monolog to Email Errors why swiftmailer.transport.real is non-existent service
Basically what they offer is to set swiftmail parameter spool: {type: memory} or create service description manually
I've added sppol to all configs: config.yml, config_test.yml, config_dev.yml but that did not helped. Then i've added entries in one of my bundles services.yml
swiftmailer.transport.simplemailinvoker:
class: Swift_Transport_SimpleMailInvoker
swiftmailer.transport.eventdispatcher:
class: Swift_Events_SimpleEventDispatcher
swiftmailer.transport.real:
class: Swift_Transport_MailTransport
arguments: [#swiftmailer.transport.simplemailinvoker, #swiftmailer.transport.eventdispatcher]
but that did not solved my problem ether.
My composer file looks like this:
http://pastebin.com/Wsfx22Lg
Any advice how to fix this?
Try my variant, it works for me:
swiftmailer.transport.simplemailinvoker:
class: Swift_Transport_SimpleMailInvoker
swiftmailer.transport.eventdispatcher:
class: Swift_Events_SimpleEventDispatcher
swiftmailer.replacementfactory:
class: Swift_StreamFilters_StringReplacementFilterFactory
swiftmailer.transport.buffer:
class: Swift_Transport_StreamBuffer
arguments: [#swiftmailer.replacementfactory]
swiftmailer.transport.real:
class: Swift_Transport_MailTransport
arguments: [#swiftmailer.transport.simplemailinvoker, #swiftmailer.transport.eventdispatcher]
Try adding this in your service.yml: worked for me
swiftmailer.transport.simplemailinvoker:
class: Swift_Transport_SimpleMailInvoker
swiftmailer.transport.eventdispatcher:
class: Swift_Events_SimpleEventDispatcher
swiftmailer.transport.buffer:
class: Swift_Transport_StreamBuffer
swiftmailer.transport.real:
class: Swift_Transport_MailTransport
arguments: [#swiftmailer.transport.simplemailinvoker, #swiftmailer.transport.eventdispatcher]
I used part of the previous answer and worked it. Hope this will work for you
The xml version of #Yury Pliashkou's answer:
<?xml version="1.0" encoding="UTF-8"?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="swiftmailer.transport.simplemailinvoker" class="Swift_Transport_SimpleMailInvoker" />
<service id="swiftmailer.transport.eventdispatcher" class="Swift_Events_SimpleEventDispatcher" />
<service id="swiftmailer.replacementfactory" class="Swift_StreamFilters_StringReplacementFilterFactory" />
<service id="swiftmailer.transport.buffer" class="Swift_Transport_StreamBuffer">
<argument type="service" id="swiftmailer.replacementfactory"></argument>
</service>
<service id="swiftmailer.transport.real" class="Swift_Transport_MailTransport">
<argument type="service" id="swiftmailer.transport.simplemailinvoker"></argument>
<argument type="service" id="swiftmailer.transport.eventdispatcher"></argument>
</service>
</services>
</container>

How do I override the first argument of a parent service in yaml?

From monolog.xml:
<service id="monolog.logger" parent="monolog.logger_prototype" public="false">
<argument index="0">app</argument>
</service>
<service id="logger" alias="monolog.logger" />
<service id="monolog.logger_prototype" class="%monolog.logger.class%" abstract="true">
<argument /><!-- Channel -->
</service>
How do I accomplish the same overriding of the 0th argument in Yaml?
My colleague created a bundle that allows you to easily convert from XML to YML and it came up with:
services:
monolog.logger:
public: false
arguments: { index_0: app }
monolog.logger_prototype:
class: %monolog.logger.class%
arguments: ['']
logger: #monolog.logger
Never would have guessed that.
One of defining logger with custom channel as service way:
# app/config/config.yml
monolog:
channels: [custom_channel]
When in a controller:
$logger = $this->get('monolog.logger.custom_channel');
or when defining a service:
services:
app.logger.custom_channel:
parent: monolog.logger.custom_channel

Inject SwiftMailer into symfony2 service

I have a service which extends UserManager, so when I do:
$message = \Swift_Message::newInstance()
->setSubject('~')
->setFrom('~')
->setTo('~')
->setBody('~', 'text/html');
$this->get('mailer')->send($message);
I get the error:
Fatal error: Call to undefined method My\MyBundle\Service\ServiceClass::get()
I know this is because I need to inject the swiftmailer into here, but how?
(usually the service class extends 'Generic' so the swift mailer is included.)
Depending on what kind of service file you are using you need to inject it into your service directly like you said.
XML:
<services>
<service id="sample.service" class="%sample.service.class%">
<argument type="service" id="mailer" />
</service>
</services>
YAML:
services:
sample.service:
class: %sample.service.class%
arguments: [#mailer]
You can simply grab the service in your constructor like this.
Or if you really want, you can inject the service_container. But that's really dirty, since you can just inject the services you need.
Injection the service_container is only needed if you need a dynamic service call.
In services.yml (symfony 4 example)
mailer:
class: \Swift_Mailer
myClass:
class: x\x
arguments:
- "#mailer"

Resources