Use doctrine CRUD in Sonata Admin - php

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 ]
^
|
---------------------------------------------------------+

Related

Symfony 4 - controllers in two directories

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.

Deleting a Group of Fields from an Admin

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.

How to override SonataUser entities properties and forms?

I am setting up a brand new project using Symfony 2.7.x and Sonata Admin 2.3.x plus Sonata User. By default Sonata add a bunch of useless fields and I want to keep my entity as clean as possible. So my first question is:
It's possible to override Sonata User entities in order to get ride of some useless properties? How?
Now as second part of the question and related to the same I want to create or use my own form for add new Users and/or Groups because with defaults ones I can't add roles. See the image below to see what I am talking about:
I should be able to add new dynamic roles from there and I can't.
Is this possible? How? Any workaround?
I took a look at Github here and Docs here but couldn't find nothing helpful. Any advices?
You can get rid of the Sonata properties by extending the FOSUserBundle entity directly rather than SonataUser User model.
change the entity that your User extends actually:
use Sonata\UserBundle\Model\User as BaseUser;
to the following:
use FOS\UserBundle\Entity\User as BaseUser;
Then, to delete useless properties from forms and maybe add new, override the default sonata UserAdmin class:
1- Create an admin class called UserAdmin in your own bundle.
2- Open the file vendor/sonata-project/user-bundle/Admin/Model/UserAdmin.php and take the configureFormFields from it. Paste it in your own admin class and keep only the fields you need by deleting useless fields from the base form builder.
The class can looks like:
use FOS\UserBundle\Model\UserManagerInterface;
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Form\FormMapper;
class UserAdmin extends Admin // You can extends directly from SonataUserAdmin if it's easier for you
{
protected $userManager;
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
... The fields you keep ...
}
/**
* #param UserManagerInterface $userManager
*/
public function setUserManager(UserManagerInterface $userManager)
{
$this->userManager = $userManager;
}
/**
* #return UserManagerInterface
*/
public function getUserManager()
{
return $this->userManager;
}
}
3- Define the new UserAdmin class as a service
services:
sonata.user.admin.user:
class: YourOwnAdminBundle\Admin\UserAdmin
tags:
- { name: sonata.admin, manager_type: orm, group: %sonata.user.admin.groupname%, label: "User", label_catalogue: %sonata.user.admin.label_catalogue%", icon: "%sonata.user.admin.groupicon%"}
arguments:
- ~
- %sonata.user.admin.user.entity%
- %sonata.user.admin.user.controller%
calls:
- [setUserManager, ["#fos_user.user_manager"]]
- [setTranslationDomain, ["%sonata.user.admin.user.translation_domain%"]]
Then, adapt the configuration of sonata-user in config.yml:
sonata_user:
...
admin:
user:
class: YourOwnAdminBundle\Admin\UserAdmin
controller: SonataAdminBundle:CRUD
translation: SonataUserBundle
And it should be good.
Look at this similar question in case of I forgotten something or you need more.

Passing arguments to a view in a different bundle - symfony2

I'm creating a control panel application that has a base bundle with some basic functionality and specific bundles for advanced and specific functionality.
for example the base bundle handles user authentication and holds all the template assets and other bundles add functionalities to config different parts of the operating system.
I need to be able to add menu links in the layout of the base bundle to each of the other bundles. and I prefer to do it in each bundles configuration so I can mix and match features for different clients.
I read all about Compiler Passes, Extensions and dependency injection with no luck. is there correct of doing it ?
If you are using Twig this should do the trick...
{% render "DifferentBundle:ControllerName:functionalityName" with {'argument_name': 3} %}
You should have a functionalityNameAction method in your DifferentBundle controller for this to work.
Take a look at the Creating and using Templates - Embedding Controllers section in the doc.
Hope it helps.
Just in case anyone has a similar problem, here is how I achieved this:
I created a service in my BaseBundle that implements the __get , __set, __isset and __unset magic methods and has an extra append method. it stores variables in a static variable inside the class.
I then added Listeners to all my bundles :
namespace Mbs\OtherBundle\Listener;
use Mbs\BaseBundle\Services\GlobalVars;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
class ControllerListener
{
protected $_global_vars;
public function __construct(GlobalVars $global_vars)
{
$this->_global_vars = $global_vars;
}
public function onKernelController(FilterControllerEvent $event)
{
$this->_global_vars->append('bundles', 'mbs.other');
}
}
This is my services.yml for one of the bundles. GlobalVars is the class I mentioned earlier.
services:
mbs.base_controller_listener:
class: Mbs\OtherBundle\Listener\ControllerListener
tags:
- { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
arguments: [ #mbs.global_vars ]

Symfony2: How to render partial in Twig extension

I have a already working Twig extension in my Symfony2 app:
namespace Company\MyBundle\Service;
class MyExtension extends \Twig_Extension
{
// ...
}
I now want to create a Twig function, which itselfs takes some data and renders a partial template. But my question is: how do I get a new templating instance in my twig extension service?
Here is my current config:
services:
twig.extension.my_extensions:
class: Company\MyBundle\Service\TwigExtension
tags:
- { name: twig.extension }
If I now add arguments: [#templating] to the config, I get an (understandable) circular reference exception.
It seems one of the recommended simple ways is to inject the container directly and retrieve the templating engine from there. As you've seen, injecting in the templating engine directly causes a circular reference exception.
So, inject in #service_container and you should be good. This seems to be the approach taken by bundles such as the FOSFacebookBundle as well.

Categories