symfony 4 autowiring false not work for specific service - service

I don't understand this error:
Cannot autowire service "App\Service\PdfLatexManager": argument "$binary" of method "__construct()" has no type-hint, you should configure its value explicitly
service.yaml:
parameters
rubber-pipe: '/usr/bin/rubber-pipe'
services:
_defaults:
autowire: true
autoconfigure: true
public: false
App\Service\PdfLatexManager:
autoconfigure: false
autowire: false
public: true
class: "%pdfLatex_class%"
arguments: ["%rubber-pipe%", "#service_container"]
my service class:
namespace App\Service;
use App\Entity\User;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\DependencyInjection\ContainerInterface;
class PdfLatexManager extends AbstractController
{
/**
* Full system path to rubber-pipe binary
* #var string
*/
protected $binary;
...
public function __construct($binary, ContainerInterface $container)
{
$this->binary = $binary;
$this->container = $container;
}
...
}
Any idea?
Thanks
Cédric

Related

vscode JavaScript - Reference types across files

How can I reference a type that is not exported (like MyClass) from another file in VSCode using JavaScript and CommonJS?
I have tried to use #module as dictated by JSDoc but it does not work. Is this not supported by VSCode?
Let's say I have two files:
myFactory.js:
/**
* #module MyModule
*/
class MyClass {}
const myFactory = {
create() {
return new MyClass();
}
}
module.exports = myFactory;
doSomething.js:
const myFactory = require('./myFactory');
/**
* #param {MyClass} item
*/
function doSomething1(item) {}
/**
* #param {MyModule.MyClass} item
*/
function doSomething2(item) {}
/**
* #param {module:MyModule.MyClass} item
*/
function doSomething3(item) {}
In doSomething.js, VSCode's Intellisence is not aware of MyClass so all 3 function signatures looks like this:
(local function) doSomethingX(item: any): void
Instead of
(local function) doSomethingX(item: MyClass): void
Here is my jsconfig.json:
{
"compilerOptions": {
"target": "es2017"
}
}
Try to move MyClass into separate file and set same #namespace for all files:
MyClass.js:
/** #namespace MyNamespace */
/** This is my class */
class MyClass {}
myFactory.js:
/** #namespace MyNamespace */
const myFactory = require('./MyClass');
const myFactory = {
create() {
return new MyClass();
}
}
module.exports = myFactory
doSomething.js:
/** #namespace MyNamespace */
const myFactory = require('./myFactory');
/** #param {MyClass} item */
function doSomething1(item) {}

symfony 3 - how to add a eventsubscriber as a service in a form

In my application, I created a listener for onPostSubmit event in forms.
I created a new class that implement EventSubscriberInterface.
In the builderForm I added the evnet subscriber like this :
->addEventSubscriber(new MyNewListener())
Everything is working well, but not as I would like...
In my listener, I need the entity manager to query the database.
The first solution I have found is to add the entity manager in the form via the options and pass it to the listener via the constructor. The code is now :
->addEventSubscriber(new MyNewListener($options['entity_manager']))
This solution works but I don't want to use it like this, I prefer to use a service and add the entity manager in the service definition.
Then, my question is: How to declare the listener as a service (and pass the entity manager) and how to call it in the form declaration ?
Thank you for your help.
Just treat your subscriber as a service.
Yml configuration. You can spare autowire:true if you have all classes autowired:
services:
My\Form\Type:
autowire: true
tags:
- { name: form.type }
My\Form\Listener\MyNewListener:
autowire: true
Form class:
...
class MyForm extends AbstractType
{
/**
* #var MyNewListener
*/
private $listener;
/**
* #param MyNewListener $listener
*/
public function __construct(MyNewListener $listener)
{
$this->listener = $listener;
}
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
...
$builder->addEventSubscriber($this->listener);
}
}
You can define your form as a service in the container, like Cerad mentioned in his comment.
Since you are using Symfony 3 you can either choose to configure the service with autowire: true, or manually declare your arguments. Then inside your FormType you can pass those class properties to your Subscriber class. When you define your form as a service, be sure to tag it with form.type. Here is example code below.
Services.yml
services:
your.form.type:
class: EventsBundle\Form\MarketerType
autowire: true # this is not needed if using arguments
arguments: [ '#doctrine.orm.entity_manager' ] # this is not needed if using autowire
tags:
- { name: form.type }
FormType.php
<?php
namespace EventsBundle\Form;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Form\AbstractType;
...
class FormType extends AbstractType
{
/** #var EntityManager */
private $em;
public function __construct(EntityManager $em)
{
$this->em = $em;
}
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
...
$builder->addEventSubscriber(new YourNewListener($this->em));
}
...
Then, to be on the safe side, you'll want to clear the application cache. I hope this helps!

API Platform : No resource found for object of type "AppBundle\Document\article"

i'm using symfony2 API platform to generate an api from my mongodb database but i get this error :
hydra:description: "No resource found for object of type "AppBundle\Document\article"",
i have two mongo db documents user and article and each user has multiple articles so i'm trying to list all the users with all their articles titles so i can get something like this :
{
#id: "/user/53edb6200cf2400d584c2617",
#type: "user",
class: "de.freelancer.mongo.domain.User",
email: "feer#de.com",
displayname: "feer",
withnewsletter: false,
language: "de_DE",
active: true,
admin: false,
articles : ['article1','article2','article3']
}
here is my code :
user Document
<?php
namespace AppBundle\Document;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
use Dunglas\ApiBundle\Annotation\Iri;
use Symfony\Component\Validator\Constraints as Assert;
/**
#MongoDB\Document
#MongoDB\Document(collection="user")
/
class User{
/*
#MongoDB\Id(strategy="AUTO") */
private $id;
/**
#MongoDB\ReferenceMany(targetDocument="articles", mappedBy="user") */
private $articles;
public function __construct()
{
$this->articles = new ArrayCollection();
}
/**
*/
public function getArticles()
{
return $this->articles;
}
}
articles document
<?php
namespace AppBundle\Document;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
use Dunglas\ApiBundle\Annotation\Iri;
use Symfony\Component\Validator\Constraints as Assert;
/**
#MongoDB\Document
#MongoDB\Document(collection="article")
/
class article
{
/*
#MongoDB\Id(strategy="AUTO") */
private $id;
/**
#MongoDB\ReferenceOne(targetDocument="user", inversedBy="articles") */
private $user;
/**
*/
public function setUser(userProfile $user)
{
$this->user = $user;
return $this;
}
/**
*/
public function getUser() {
return $this->user;
}
}
can any one help me to get the list of the user articles
thanks
Every class managed by API Platform needs to be marked with the #ApiPlatform\Core\Annotation\ApiResource annotation (or the equivalent in YAML or XML).
And there is no native MongoDB support yet (but this is a work in progress).
You can still add MongoDB support by yourself using a custom data provider, but if you're a newcomer to API Platform, you should try to use Doctrine ORM and follow the official tutorial first: https://api-platform.com/docs/distribution/

Unable to override Sonata User Bundle registration form

I keep getting an error while trying to override sonata registration template.
I extended Sonata User Bundle with EasyExtendsBundle, so I now have src/Application/Sonata/UserBundle.
EDIT: Symfony 2.7, Sonata Admin 2.3, Sonata User dev-master
I added a field in my User Entity
UserEntity.php
<?php
/**
* This file is part of the <name> project.
*
* (c) <yourname> <youremail>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Application\Sonata\UserBundle\Entity;
use Sonata\UserBundle\Entity\BaseUser as BaseUser;
/**
* This file has been generated by the Sonata EasyExtends bundle ( http://sonata-project.org/bundles/easy-extends )
*
* References :
* working with object : http://www.doctrine-project.org/projects/orm/2.0/docs/reference/working-with-objects/en
*
* #author <yourname> <youremail>
*/
class User extends BaseUser
{
/**
* #var integer $id
*/
protected $id;
/*
* #ORM\Column(type="string", length=255)
*
* #Assert\NotBlank(message="Please enter your name.", groups={"Registration", "Profile"})
*/
protected $age;
/**
* Get id
*
* #return integer $id
*/
public function getId()
{
return $this->id;
}
public function getAge()
{
return $this->age;
}
public function setAge($age)
{
$this->age = $age;
}
}
I then created a new RegisterForm
Application/Sonata/UserBundle/Form/Type/RegisterType.php
<?php
namespace Application\Sonata\UserBundle\Form\Type;
use FOS\UserBundle\Form\Type\RegistrationFormType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class RegisterType extends RegistrationFormType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
$builder
->add('age');
}
public function setDefaultOption(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'validation_groups' => array('Default', 'Register')
));
}
public function getName()
{
return 'front_user_registration';
}
}
I tell sonata_user to use my form
config.yml
sonata_user:
profile:
register:
form:
type: front_user_registration
handler: sonata.user.profile.form.handler.default
name: front_user_registration_form
fos_user:
db_driver: orm # can be orm or odm
firewall_name: main
# if you change the class configuration, please also alter the sonata_user.yml file
user_class: Application\Sonata\UserBundle\Entity\User
group:
group_class: Application\Sonata\UserBundle\Entity\Group
group_manager: sonata.user.orm.group_manager
service:
user_manager: sonata.user.orm.user_manager
registration:
form:
type: front_user_registration
profile:
form:
type: fos_user_profile
handler: fos_user.profile.form.handler.default
name: fos_user_profile_form
validation_groups: [Authentication]
which I declare as a service
services.yml
user.form.register.type:
class: Application\Sonata\UserBundle\Form\Type\RegisterType
parent: fos_user.registration.form.type
tags:
- { name: form.type, alias: front_user_registration }
When I try to display the form, I get the following error :
Catchable Fatal Error: Argument 1 passed to
Sonata\UserBundle\Form\Handler\ProfileFormHandler::process() must
implement interface FOS\UserBundle\Model\UserInterface, boolean given,
called in
/Users/sylv/Sites/generajobs/vendor/sonata-project/user-bundle/Controller/RegistrationFOSUser1Controller.php
on line 49 and defined
Same goes if I add
arguments: [%fos_user.model.user.class%]
into my services.yml configuration.
Am i missing something here ?
That was a pretty stupid mistake, I had to change my "handler" line in config.yml to
handler: sonata.user.registration.form.handler.default
instead of sonata.user.profile.form.handler.default as I saw on several examples on S.O.
The two handlers process() function do not except the same parameters.

MongoDbBundle how to access manager in an arbitray class

in Symfony2 samples I can find how to access mongodb in from the Controller class:
$dm=$this->get('doctrine_mongodb')->getManager();
how to do it in an arbitray class?
You should use Dependency Injection to inject the doctrine_mongodb service into your class like this.
Create your class like this:
use Doctrine\Common\Persistence\ObjectManager;
class MyClass
{
protected $documentManager;
// ObjectManager is the interface used only for type-hinting here
// DocumentManager or EntityManager are the actual implementations
public function __construct(ObjectManager $om)
{
// The property $documentManager is now set to the DocumentManager
$this->documentManager=$om;
}
public function findSomething()
{
// now do something with the DocumentManager
return $this->documentManager->getRepository('YourBundle:SomeDocument')->findBy(array(/* ... */));
// ...
}
Then declare this class as a service:
# app/config/config.yml
services:
your_service_name:
class: Namespace\Your\SomeClass
arguments: ['#doctrine.odm.mongodb.document_manager']
In order to access your class from a controller it's service name to get it from the container (the DocumentManager will then be injected automatically into the constructor)
// Vendor/YourBundle/Controller/SomeController.php
public function doWhatever()
{
$myClassService = $this->get('your_service_name');
$something = $myClassService->findSomething();
}