How to Remove or overwrite sonata admin pagination? - symfony

When creating a page, pagination takes a very long time. I want to delete it or override it. Tell me who faced I want to remove these things

To remove only the Twig view (no impact on performance, it's just visual) :
you can define a custom Pager using this :
# app/config/your_sonata_services_config.yml
services:
app.admin.post:
class: AppBundle\Admin\PostAdmin
tags:
- { name: sonata.admin, manager_type: orm, group: "Content", label: "Post", pager_type: "simple" }
arguments:
- ~
- AppBundle\Entity\Post
- ~
public: true
With tag pager_type: simple, the view SonataAdminBundle:Pager:simple_pager_results.html.twig will be called.
source : https://symfony.com/doc/master/bundles/SonataAdminBundle/cookbook/recipe_improve_performance_large_datasets.html
To disable COUNT(*) of rows and improve performance :
You can have a look here https://github.com/sonata-project/SonataDoctrineORMAdminBundle/issues/297, you have to :
extend the default SonataPager with your own class that overrides computeNbResult()
extends the default SonataProxyQuery with your own class that overrides getFixedQueryBuilder()
extend the default SonataDatagridBuilder with your own class that overrides getBaseDatagrid()
Reference those in your services

Related

How to remove routes only in child admin (SonataAdminBundle)?

I have admin like "User Admin" and one child admin like "Document Admin""
admin.users:
class: App\Admin\UserAdmin
arguments: [~, App\Entity\User, SonataAdminBundle:CRUD]
calls:
- [addChild, ['#admin.documents'] ]
tags:
- {name: sonata.admin, manager_type: orm, label: Users}
public: true
admin.documents:
class: App\Admin\DocumentsAdmin
arguments: [~, App\Entity\Document, ~]
calls:
- [setParentAssociationMapping, ['user']]
- [setTranslationDomain, ['admin']]
tags:
- {name: sonata.admin, manager_type: orm, label: Documents}
public: true
And i try to remove create and delete route
App\Admin\DocumentAdmin
protected function configureRoutes(RouteCollection $collection)
{
parent::configureRoutes($collection);
$collection->remove('delete');
$collection->remove('create');
}
But when i open this admin (/admin/app/user/1/document/list), i receive error:
An exception has been thrown during the rendering of a template
("Unable to generate a URL for the named route
"admin_app_user_document_create" as such route does not exist.").
Not working, but should be. I want to see child admin wit users documents without add and create buttons.
But when i open document admin directly ( /admin/app/document/list ) - everything is ok! I see list without add and edit and delete button.
How to remove routes in DocumentAdmin for both situation ?
Symfony 4 / Sonata Admin 3.35
You only removed the create and delete links. You need to remove the link to list the entity too. I guess this is what you need? Add this line too.
protected function configureRoutes(RouteCollection $collection)
{
parent::configureRoutes($collection);
$collection->remove('delete');
$collection->remove('create');
$collection->remove('list');
}
You can see list documents because you did not remove the list action from route collection.
Just do cache:clear it take time to regenerate routes

Change left menu labels on Sonata Admin

How can I change the labels in the left menu of my Sonata Admin installation?
I would like to change (and understand how they are generated):
The "admin" text
The "PostCategory" label (and change it to something more "WordPress-ish" :) like "Post Categories")
These labels are defined in the tags property in the service definition of your admin page, in the config file of the admin section. See documentation here.
Example in a admin-services.yml file:
services:
app.admin.category:
class: AppBundle\Admin\CategoryAdmin
tags:
- { name: sonata.admin, manager_type: orm, group: "My Admin Group", label: "Post Categories" }
arguments:
- ~
- AppBundle\Entity\Category
- ~
calls:
- [ setTranslationDomain, [AppBundle]]
The group tag corresponds to your admin label, and the label one to your PostCategory.
I guess you didn't specify these tags, and admin is the default group name, and PostCategory the name of your class.
EDIT:
The label and the group option are translation keys. You specify the translation domain under the calls tag, with setTranslationDomain, and the default catalog is messages. See documentation on translation here.

how to get data from the entity Repository before every page render in symfony2?

Q1.I want to count the unread messages before every page rendered ,and add the number into twig template.i don't know how to make it
Q2.i have read the symfony tutorial,it seems that i will make a service ,but i don't know how to do it.is the following code right? and i don't know what to write at the seconde argument
namespace App\RepairBundle\Service;
use Symfony\Component\DependencyInjection\ContainerInterface;
use App\RepairBundle\Entity\RepairMessageRepository;
class CountUnReadMessage
{
protected $container;
protected $messageRepository;
public function __construct(ContainerInterface $container,RepairMessageRepository $messageRepository)
{
$this->container = $container;
$this->messageRepository = $messageRepository;
}
public function countUnRead()
{
$number = $this->messageRepository->countByUnread($this->container->get('security.token_storage')->getToken()->getUser()->getId());
return $number;
}
}
parameters:
app.repair.count_unread_message: App\RepairBundle\Service\CountUnReadMessage
services:
app.repair.count_unread_message:
class: %app.repair.count_unread_message%
arguments:
- #service_container
- #
If piece of the twig template containing message counter similar in all templates, you can move it to separate template and call service inside this template. You steps to achieve this might look like this:
Write service for getting message counter (you almost got it, but try to avoid injecting whole container in servce since it is a very bad practice. In this case, i think you could inject only security.token_storage)
Make this service visible in twig templates by declare it in config file.
config.yml
twig:
globals:
count_read_message: #app.repair.count_unread_message
In your separate twig file call this service
message_block.html.twig
{{ count_read_message.countUnRead() }}
And include this twig file to needed template (better idea would be keep main template for most of templates and include you file in this template, but this dependenced of template structure)
I hope you got the main idea =)
P.S. Answering for Q2 - it is #doctrine.orm.entity_manager
If you want to inject repository make another service with your repository:
app.message_repository:
class: Doctrine\ORM\EntityRepository
factory: ["#doctrine.orm.default_entity_manager", getRepository]
arguments:
- App\RepairBundle\Entity\RepairMessage
Then in your service:
app.repair.count_unread_message:
class: %app.repair.count_unread_message%
arguments:
- #service_container
- #app.message_repository
BTW you don't need container, inject only security.token_storage instead of container.

Symfony2 add event listener dynamically

How would you add an event listener (in my case it's a doctrine event) dynamically to the kernel without using services.yml pattern?
I found the answer myself after doing some digging into the vendor directory and appProdProjectContainer.php file. If you want your events to be registered with event manager you have to specify the tags in your services.yml for the events that you want this to trigger for like:
event_listener:
class: Company\MyBundle\Listener\MyListener
arguments: [#security.context, #logger]
tags:
-
name: doctrine.event_listener
event: preRemove
-
name: doctrine.event_listener
event: onFlush
Now if you want to dynamically register these events, you need to leave the event_listener resource in services.yml, but delete the tags part and dynamically add them that as follow:
if (something) {
$evm = $em->getConnection()->getEventManager();
$evm->addEventListener(
[
0 => 'preRemove',
1 => 'onFlush'
],
$this->container->get('event_listener');
}

Changing xml-mapping from the user entity (SonataUserBundle) to annotations

I've implemented the SonataAdmin and SonataUserBundle into my project.
With this I've created the Application\Sonata\UserBundle which has a User entity. This entity uses xml-mapping for Doctrine. I'm wondering if it's possible to change this configuration to annotations as I'm using annotations in the rest of my project.
Thx.
sonata.user.admin.user:
class: %sonata.user.admin.user.class%
tags:
- { name: sonata.admin, manager_type: orm, group: Usuarios, label: Usuarios }
arguments: [null, %sonata.user.admin.user.entity%, SonataAdminBundle:CRUD]
calls:
- [ setUserManager, [fos_user.user_manager]]
where sonata.user.admin.user.class and .entity are values set in your config file.
You should probably change your fos_user.user_manager also but i don't know what you use...

Resources