I tried to follow Sonata UserBundle group and row deletion method which is explained here : Official Doc Sonata
However if I do that nothing happens so I searched a bit on the internet but I did not find anything about it. I tried to add this :
sonata_user:
security_acl: true
manager_type: orm
admin:
user:
class: Application\Sonata\UserBundle\Admin\UserAdmin
controller: SonataAdminBundle:CRUD
But then I come out with a big error:
The autoloader expected class "Application\Sonata\UserBundle\Admin\UserAdmin" to be defined in file "C:\wamp64\www\WebBundle\vendor\composer/../../src\Application\Sonata\UserBundle\Admin\UserAdmin.php". The file was found but the class was not in it, the class name or namespace probably has a typo.
I also tried to put file in AppBundle but I find myself with the same error, without putting admin : user: in the config.yml file:
The autoloader expected class "AppBundle\Admin\UserAdmin" to be defined in file "C:\wamp64\www\WebBundle\vendor\composer/../../src\AppBundle\Admin\UserAdmin.php". The file was found but the class was not in it, the class name or namespace probably has a typo in C:\wamp64\www\WebBundle\app/config\services.yml (which is being imported from "C:\wamp64\www\WebBundle\app/config\config.yml").
My only suggestion would be, where you have:
sonata_user:
security_acl: true
manager_type: orm
admin:
user:
class: Application\Sonata\UserBundle\Admin\UserAdmin
controller: SonataAdminBundle:CRUD
Try the following:
sonata_user:
security_acl: true
manager_type: orm
class: # Entity Classes
user: Application\Sonata\UserBundle\Entity\User
group: Application\Sonata\UserBundle\Entity\Group
admin: # Admin Classes
user:
class: Sonata\UserBundle\Admin\Entity\UserAdmin
controller: SonataAdminBundle:CRUD
translation: SonataUserBundle
As described in the official docs
I think i found a solution of that problem for the Master Version, you can go in Vendor/sonata-project/user-bundle/Admin/Model/UserAdmin and directly modify the file so you don't have to use the solution recommended in the documentation.
I hope that will help some people.
Related
In my application, I use Symfony 4. I want Symfony to search for controllers in two directories: A and B. I found something like this:
controllers:
resource: '../src/DirectoryA/Controller/'
type: annotation
, but it only works for one directory. How can I have Symfony to search for controllers in two directories?
Regards
In your config/services.yaml
App\DirectoryA\Controller\: # assuming you have namespace like that
resource: '../src/DirectoryA/Controller'
tags: ['controller.service_arguments']
App\DirectoryB\Controller\: # assuming you have namespace like that
resource: '../src/DirectoryB/Controller'
tags: ['controller.service_arguments']
This will add next directory for service arguments. Thats answers your questions based In directory, what you have posted is routing file, in there would be similiar
controllers_a:
resource: '../src/DirectoryA/Controller/'
type: annotation
controllers_b:
resource: '../src/DirectoryB/Controller/'
type: annotation
The accepted answer is of course completely correct.
However, once you move from having one controller directory to multiple directories, updating your services.yaml file can be a bit of a pain. Even having to have directories specifically for controllers can be limiting.
Here is an alternate approach which allows creating controllers wherever you want and automatically tagging them.
Start with an empty controller interface for tagging.
interface ControllerInterface {}
Now have all your controllers implement the interface
class Controller1 implements ControllerInterface { ...
class Controller2 implements ControllerInterface { ...
And then adjust the kernel to automatically tag all your controller interface classes with the controller tag.
# src/Kernel.php
protected function build(ContainerBuilder $container)
{
$container->registerForAutoconfiguration(ControllerInterface::class)
->addTag('controller.service_arguments')
;
}
And presto. You can create your controllers wherever you want with nothing in services.yaml.
Update:
If you would like to avoid editing Kernel.php then you can use the _instanceof functionality in your services.yaml file.
#config/services.yaml
services:
_instanceof:
App\Contract\ControllerInterface:
tags: ['controller.service_arguments']
Another Update: As long as your controller extends Symfony's AbstractController then no additional tagging is needed. You can even delete the default controller lines in the default services.yaml file if you want.
I'm working on a bundle for Symfony 4 that is structured like this:
\Acme
\FooBundle
\Article
\Entity
- Article.php
- Comment.php
\Form
- ArticleType.php
\Repository
- ArticleRepository.php
- CommentRepository.php
- ArticleManager.php
\User
\Entity
- User.php
\Repository
- UserRepository.php
- UserManager.php
\SomethingElse
\Entity
- SomethingElse.php
\Repository
- SomethingElseRepository.php
- SomethingElseManager.php
There are many more folders and entities, but is irrelevant for the question.
Autowiring all the classes in that folder can be created with a config like this one:
Acme\FooBundle\:
resource: '../../*/{*Manager.php,Repository/*Repository.php}'
exclude: '../../{Manager/BaseManager.php,Repository/BaseRepository.php}'
autowire: true
But when you need to add service tags like doctrine.repository_service, this kind of configuration won't help no more. Without the tag, when using in controller like:
$this->getDoctrine()->getRepository(Bar::class)
or
$this->getDoctrine()->getManager()->getRepository(Bar::class)
it throws an error:
The "Acme\FooBundle\SomethingElse\Repository\SomethingElseRepository" entity repository implements "Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepositoryInterface", but its service could not be found. Make sure the service exists and is tagged with "doctrine.repository_service".
The thing is that, since they all reside in the same root folder I'm not allowed to use a config like the following one, because it would have duplicated Acme\FooBundle\ keys:
Acme\FooBundle\:
resource: '../../*/{*Manager.php}'
exclude: '../../{Manager/BaseManager.php}'
autowire: true
Acme\FooBundle\:
resource: '../../*/{Repository/*Repository.php}'
exclude: '../../{Repository/BaseRepository.php}'
autowire: true
tags: ['doctrine.repository_service']
So, I was wondering if there's a workaround that I couldn't find or I should just manually add each and every service?
Edit:
It would have been a nice feature to be able to use an annotation in the class so when it's loaded it "knows" it's tag, but I'm thinking it works the other way around, loading a class because is was tagged with a certain tag.
I had the same error message after upgrading to symfony 4.4 from 3.4.
The issue seemed to be that the entity had an annotation to #ORM\Entity(repositoryClass="App\Repository\MyRepository")
while the repository extends ServiceEntityRepository and in the constructor points to the entity parent::__construct($registry, MyEntity::class);.
Removing the annotation on the entity fixed the issue.
I encountered the same error message after refactoring (renaming) some entities and the related repositories using PhpStorm 2019.2 The refactor did not update the repository class name in the doc block for the entity:
* #ORM\Entity(repositoryClass="App\Repository\OldRepository")
So I used right-click > Copy Reference to get the fully qualified name of NewRepository and pasted it in to the doc block reference:
* #ORM\Entity(repositoryClass="\App\Repository\NewRepository")
PhpStorm prefixed the class with a backslash and I didn't notice until after trying many combinations of suggested solutions for this error. I only needed to remove the backslash and the error is gone:
* #ORM\Entity(repositoryClass="App\Repository\NewRepository")
You can autoconfigure tags in your Kernel / Main Bundle Class:
https://symfony.com/doc/current/service_container/tags.html#autoconfiguring-tags
<?php
namespace Acme\FooBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class FooBundle extends Bundle
{
public function build(ContainerBuilder $container)
{
parent::build($container);
$container->registerForAutoconfiguration(EntityRepository::class)
->addTag('doctrine.repository_service');
}
}
You can tag all of your repositories, like this:
App\Repository\:
resource: '../src/Repository'
autowire: true
tags: ['doctrine.repository_service']
Thanks #t-van-den-berg and #arleigh-hix !
I had this problem after migrating from Symfony 3.4 to 4.4, when I wanted to use old Repositories with new services.
My solution was a little variation:
use App\Repository\NewRepository;
//...
/**
* #ORM\Entity(repositoryClass=NewRepository::class)
*/
And service declaration (to use Interface):
App\Repository\NewRepository:
arguments:
- "#doctrine"
App\Repository\NewRepositoryInterface: '#App\Repository\NewRepository'
I upgraded from Symfony 2.7 to 3.0. It works almost. Only problem: I'm not able to overwrite AppBundle\Entity\MyRepository in the code below, the file is not even necessary (I renamed it for testing) and got skipped by Symfony.
app/config/services.yml
# old, 2.7 (worked):
myRepositoryService:
class: AppBundle\Entity\MyRepository
factory_service: doctrine.orm.entity_manager
factory_method: getRepository
arguments: [AppBundle\Entity\MyEntity]
# new, 3.0 (skips the MyRepository):
myRepositoryService:
class: AppBundle\Entity\MyRepository
factory: ['#doctrine.orm.entity_manager', 'getRepository']
arguments: ['AppBundle\Entity\MyEntity']
AppBundle\Entity\MyRepository
class MyRepository extends EntityRepository {
public function findAll() {
die("MyRepository->findAll()"); // not executed
}
}
AppBundle\Controller\MyController.php
$myItems = $this->get('myRepositoryService')->findAll(); // should die but doesn't
Did I misconfigure my services.yml so that Symfony creates a temporary repository file for the entity instead of using the file I created?
Thanks in advance!
Following code is working for me in Symfony 3.0:
some_repository:
class: AppBundle\Repository\SomeRepository
factory: ['#doctrine.orm.default_entity_manager', getRepository]
arguments: [AppBundle:SomeEntity]
Please note the different than yours factory service name and that there are no single quotes for factory method and entity name.
Also as I've mentions in my comment, there should be repositoryClass set in entity's mapping.
I generated CRUD with command:
doctrine:generate:crud --entity=TeoBlogBundle
and i have simply CRUD for my Bundle. I would like use this CRUD in Sonata Admin Bundle, but I never found example for this.
I must create BlogAdmin class for my Bundle? Is not possible to import my CRUD? I want use my BlogBundle only in backend - SonataAdmin, where i have others bundles to manage my site. I would like add this to menu Sonata.
Sonata Admin bundle allow to extend CRUD controller and then you can use it without generating doctrine crud. You must create BlogAdmin Bundle. Use following code:
namespace Tutorial\BlogBundle\Controller;
use Sonata\AdminBundle\Controller\CRUDController as Controller;
class CommentAdminController extends Controller
{
}
Or you can suppress the need to create the admin controller. Here's example syntax for config.yml. The null below is required to accomplish this.
my.listing.admin.resource:
class: My\ExampleBundle\Admin\ResourceAdmin
tags:
- { name: sonata.admin, manager_type: orm, group: "Resource", label: "My Resource" }
arguments: [null, My\ExampleBundle\Entity\Resource, null ]
^
|
---------------------------------------------------------+
I'm using official documentation for symfony 2.1 for overriding default FOSUserBundle forms. But when I tried to override form handlers I've got this error:
InvalidArgumentException: The service definition
"test_user.form.handler.registration" does not exist.
Files listing:
<?php
// src/Test/UserBundle/Form/Handler/RegistrationFormHandler.php
namespace Test\UserBundle\Form\Handler;
use FOS\UserBundle\Form\Handler\RegistrationFormHandler as BaseHandler;
use FOS\UserBundle\Model\UserInterface;
class RegistrationFormHandler extends BaseHandler
{
protected function onSuccess(UserInterface $user, $confirmation)
{
// logic here...
parent::onSuccess($user, $confirmation);
}
}
=-=-=-=-=
# src/Test/UserBundle/Resources/config/services.yml
services:
test_user.form.handler.registration:
class: Test\UserBundle\Form\Handler\RegistrationFormHandler
arguments: ["#fos_user.registration.form", "#request", "#fos_user.user_manager", "#fos_user.mailer", "#fos_user.util.token_generator"]
scope: request
public: false
=-=-=-=-=
# app/config/config.yml
fos_user:
db_driver: orm
firewall_name: dev
user_class: Test\UserBundle\Entity\User
registration:
form:
handler: test_user.form.handler.registration
P.S. Yes, I have read similar questions, but there is not the same problem that I have.
Take a close look at the last line in services.yml. It says public: false, that is, this service is not accessible from the code (see Advanced Container Configuration). You can do one of two things: change the value of public to true or remove the line since the default value is true.
The problem was simple. I created my UnserBundle manually, so folder named DependencyInjection has not been created. This folder contains php files, which load services configuration.