I'm using Symfony and the Sonata Bundle to generate my admin interface. I have 3 classes:
Restaurant
Service
RestaurantService
With classes Restaurant and Service having a OneToMany relationship with RestaurantService.
I try RestaurantService as a child admin in Restaurant but I've got those errors:
ContextErrorException in RestaurantAdmin.php line 143:
Runtime Notice: Declaration of
GSG\AdminBundle\Admin\RestaurantAdmin::configureSideMenu() should be
compatible with
Sonata\AdminBundle\Admin\Admin::configureSideMenu(Knp\Menu\ItemInterface
$menu, $action, Sonata\AdminBundle\Admin\AdminInterface $childAdmin =
NULL)
and
FileLoaderLoadException in classes.php line 13757:
Runtime Notice: Declaration of
GSG\AdminBundle\Admin\RestaurantAdmin::configureSideMenu() should be
compatible with
Sonata\AdminBundle\Admin\Admin::configureSideMenu(Knp\Menu\ItemInterface
$menu, $action, Sonata\AdminBundle\Admin\AdminInterface $childAdmin =
NULL) in /Volumes/Data/ge0ra/www/admin_gsg/app/config/. (which is
being imported from
"/Volumes/Data/ge0ra/www/admin_gsg/app/config/routing.yml").
Here is my services.yml file:
services:
sonata.admin.restaurant:
class: GSG\AdminBundle\Admin\RestaurantAdmin
tags:
- { name: sonata.admin, manager_type: orm, group: "Gestion des restaurants", label: "Restaurants" }
arguments:
- ~
- GSG\AdminBundle\Entity\Restaurant
- ~
calls:
- [ addChild, [#sonata.admin.restaurantservice]]
sonata.admin.service:
class: GSG\AdminBundle\Admin\ServiceAdmin
tags:
- { name: sonata.admin, manager_type: orm, group: "Gestion des restaurants", label: "Services" }
arguments:
- ~
- GSG\AdminBundle\Entity\Service
- ~
sonata.admin.restaurantservice:
class: GSG\AdminBundle\Admin\RestaurantServiceAdmin
tags:
- { name: sonata.admin, manager_type: orm, group: "Gestion des restaurants", label: "RestaurantServices" }
arguments:
- ~
- GSG\AdminBundle\Entity\RestaurantService
- ~
in my RestaurantAdmin class:
protected function configureSideMenu(MenuItemInterface $menu, $action, AdminInterface $childAdmin = null)
{
if (!$childAdmin && !in_array($action, array('edit'))) {
return;
}
$admin = $this->isChild() ? $this->getParent() : $this;
$id = $admin->getRequest()->get('id');
$menu->addChild(
'Voir/Editer',
array('uri' => $admin->generateUrl('edit', array('id' => $id)))
);
$menu->addChild(
'Services',
array('uri' => $admin->generateUrl('sonata.admin.restaurantservice.list', array('id' => $id)))
);
}
and my RestaurantServiceAdmin class:
class RestaurantServiceAdmin extends Admin
{
protected $parentAssociationMapping = 'Restaurant';
// Fields to be shown on create/edit forms
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('service', 'sonata_type_model')
;
}
// Fields to be shown on filter forms
protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
}
// Fields to be shown on lists
protected function configureListFields(ListMapper $listMapper)
{
if (!$this->isChild())
$listMapper->addIdentifier('id')->addIdentifier('Restaurant');
$listMapper
->add('service', 'sonata_type_model')
;
}
}
Do someone have an idea from where those errors can come?
Thanks!
Your RestaurantAdmin class has the first parameter of configureSideMenu set as MenuItemInterface $menu when it should be an instance of \Knp\Menu\ItemInterface.
The Menu part of the type hint is wrong.
Related
I use symfony 3 and I try to manage an admin side to manage my products and my commands for my ecommerce website, but I always have the same error :
ReflectionException - Class Admin\AdminBundle\Admin\Entity\Product does not exist
this is my services :
services:
app.admin.produit:
class: Admin\AdminBundle\Admin\ProduitAdmin
tags:
- { name: sonata.admin, manager_type: orm, group: "Content", label: "Produit" }
arguments:
- ~
- Admin\AdminBundle\Admin\Entity\Produit
- ~
calls:
- [ setTranslationDomain, [AdminAdminBundle]]
public: true
app.admin.commande:
class: Admin\AdminBundle\Admin\CommandeAdmin
tags:
- { name: sonata.admin, manager_type: orm, group: "Content", label: "Commande" }
arguments:
- ~
- Admin\AdminBundle\Admin\Entity\Commande
- ~
calls:
- [ setTranslationDomain, [AdminAdminBundle]]
public: true
This is my CommandAdmin :
<?php
namespace Admin\AdminBundle\Admin;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Show\ShowMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
class CommandeAdmin extends AbstractAdmin
{
// Fields to be shown on create/edit forms
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('idProduit', 'entity', array('class' => 'Admin\AdminBundle\Entity\Produit'))
->add('date')
;
}
// Fields to be shown on filter forms
protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
$datagridMapper
// ->add('idProduit')
->add('date')
;
}
// Fields to be shown on lists
protected function configureListFields(ListMapper $listMapper)
{
$listMapper
->addIdentifier('idProduit', 'entity', array('class' => 'Admin\AdminBundle\Entity\Produit'))
->add('date')
;
}
// Fields to be shown on show action
protected function configureShowFields(ShowMapper $showMapper)
{
$showMapper
->add('idProduit')
->add('date')
;
}
}
This is my ProduitAdmin :
<?php
namespace Admin\AdminBundle\Admin;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Show\ShowMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
class ProduitAdmin extends AbstractAdmin
{
// Fields to be shown on create/edit forms
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('nom')
->add('description')
->add('quantite')
->add('prix')
->add('marque')
->add('fournisseur')
;
}
// Fields to be shown on filter forms
protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
$datagridMapper
->add('nom')
->add('description')
->add('quantite')
->add('prix')
->add('marque')
->add('fournisseur')
;
}
// Fields to be shown on lists
protected function configureListFields(ListMapper $listMapper)
{
$listMapper
->addIdentifier('nom')
->add('description')
->add('quantite')
->add('prix')
->add('marque')
->add('fournisseur')
;
}
// Fields to be shown on show action
protected function configureShowFields(ShowMapper $showMapper)
{
$showMapper
->add('nom')
->add('description')
->add('quantite')
->add('prix')
->add('marque')
->add('fournisseur')
;
}
}
This is the Stack Trace :
ReflectionException:
Class Admin\AdminBundle\Admin\Entity\Produit does not exist
at vendor/sonata-project/admin-bundle/Controller/CRUDController.php:480
at ReflectionClass->__construct('Admin\\AdminBundle\\Admin\\Entity\\Produit')
(vendor/sonata-project/admin-bundle/Controller/CRUDController.php:480)
at Sonata\AdminBundle\Controller\CRUDController->createAction()
at call_user_func_array(array(object(CRUDController), 'createAction'), array())
(vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php:153)
at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), 1)
(vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php:68)
at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), 1, true)
(vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Kernel.php:169)
at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
(web/app_dev.php:29)
If someone have an idea
The error is pretty explainable: The class Admin\AdminBundle\Admin\Entity\Produit doesn't seem to exists. Take a look at your code, I guess it's not there.
My best guess would be that you mean Admin\AdminBundle\Entity\Produit (note the removed Admin\ subnamespace). The same applies to your Commande class specification just below it.
I want to allow some users to add news, but also I don't want them to edit each others newses. So after loggin to admin panel they should be able to see only theirs newses. I'm currently doing this with sonata.
Is there any configuration for this?
My service.yml:
services:
sonata.admin.news:
class: MyBundle\Admin\NewsAdmin
tags:
- { name: sonata.admin, manager_type: orm, group: "Content", label: "News" }
arguments:
- ~
- MyBundle\Entity\News
- ~
- "#doctrine.orm.entity_manager"
calls:
- [ setTranslationDomain, [MyBundle]]
NewsAdmin contains regular stuff so there is no point in putting it here.
You can inject the security context service into your NewsAdmin
class NewsAdmin extends Admin
{
protected $security;
protected $em;
public function __construct($code, $class, $baseControllerName, $entityManager, SecurityContext $security)
{
parent::__construct($code, $class, $baseControllerName);
$this->em = $entityManager;
$this->security = $security;
}
public function getNewInstance()
{
$news = parent::getNewInstance();
$news->setUser($this->security->getToken()->getUser());
return $formDefinition;
}
public function createQuery($context = 'list')
{
$queryBuilder = $this->getModelManager()->getEntityManager($this->getClass())->createQueryBuilder();
$queryBuilder
->select('news')
->from($this->getClass(), 'news')
->andWhere('news.user = :user')
->setParameter(':user', $this->security->getToken()->getUser());
$proxyQuery = new ProxyQuery($queryBuilder);
return $proxyQuery;
}
And in your Admin definition:
services:
sonata.admin.news:
class: MyBundle\Admin\NewsAdmin
tags:
- { name: sonata.admin, manager_type: orm, group: "Content", label: "News" }
arguments:
- ~
- MyBundle\Entity\News
- ~
- "#doctrine.orm.entity_manager"
- "#security.context"
calls:
- [ setTranslationDomain, [MyBundle]]
I got a weird result using the Sonata Admin -- list view. Here is the snapshot.
http://i.stack.imgur.com/AGmVI.png
config.yml:
# ...
sonata_admin:
title: Administration
title_logo: extras/fi.gif
sonata_block:
default_contexts: [cms]
blocks:
# Enable the SonataAdminBundle block
sonata.admin.block.admin_list:
contexts: [admin]
services.yml:
# ...
services:
sonata.department.admin:
class: %sonata.department.admin.class%
tags:
- { name: sonata.admin, manager_type: orm }
DepartmentAdmin.php
<?php
namespace Abc\Bundles\HelloBundle\Admin;
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Form\FormMapper;
class DepartmentAdmin extends Admin
{
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->with('Department')
->add('name')
->end();
}
protected function configureDatagridFilter(DatagridMapper $datagridMapper)
{
$datagridMapper->add('name');
}
protected function configureListFilter(ListMapper $listMapper)
{
$listMapper->addIdentifier('name');
}
}
Entity\Department.php
//...
public function __toString()
{
$name = $this->getName();
return empty($name) ? 'Add Department' : $name;
}
The thing is, I did not integrate SonataUserBundle with this project as I find it inappropriate to the spec. Any ideas why am I getting an empty list view? For some reason, the configureListFilter is not called.
Shame on me! the issue is with the function name
configureListFilter
It should be
configureListField
waaah!.. took me long to realize that typo crap.. Thanks #AldeeMativo for the help
I have follow error when try to enter in admin dashboard:
Cannot import resource "/var/www/autoportal/app/config/." from
"/var/www/autoportal/app/config/routing.yml". (The autoloader expected
class "App\AdminBundle\Admin\AutoAdmin" to be defined in file
"/var/www/autoportal/src/App/AdminBundle/Admin/AutoAdmin.php". The
file was found but the class was not in it, the class name or
namespace probably has a typo.)
My admin class:
namespace App\AdminBundle\Admin;
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Form\FormMapper;
class AutoAdmin extends Admin
{
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('name')
->add('enabled', null, array('required' => false))
;
}
protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
$datagridMapper
->add('name')
->add('posts')
;
}
protected function configureListFields(ListMapper $listMapper)
{
$listMapper
->addIdentifier('name')
->add('slug')
->add('enabled')
;
}
}
Service configure:
services:
app_admin.auto:
class: App\AdminBundle\Admin\AutoAdmin
tags:
- { name: sonata.admin, manager_type: orm, group: posts, label: "Auto" }
arguments:
- ~
- 'App\AutoPortalBundle\Entity\Auto'
- 'SonataAdminBundle:CRUD'
calls:
- [ setTranslationDomain, [AppAdminBundle]]
routing file:
app_auto_portal_controller:
resource: "#AppAutoPortalBundle/Controller"
type: annotation
app_auto_portal:
resource: "#AppAutoPortalBundle/Resources/config/routing.yml"
prefix: /
login:
pattern: /login
defaults: { _controller: AppAutoPortalBundle:Security:login }
login_check:
pattern: /login_check
admin:
resource: '#SonataAdminBundle/Resources/config/routing/sonata_admin.xml'
prefix: /admin
_sonata_admin:
resource: .
type: sonata_admin
prefix: /admin
On this page I found how to add route for my custom action.
protected function configureRoutes(RouteCollection $collection) {
$collection->add('ispremium', $this->getRouterIdParameter().'/ispremium');
}
After that I add custom action in my Admin class:
protected function configureListFields(ListMapper $listMapper)
{
$listMapper
->addIdentifier('id')
->add('code', null, array('label' => 'Code'))
->add('_action', 'actions', array(
'actions' => array(
'ispremium' => array(
'template' => 'AppMyBundleBundle:Admin:ispremium.html.twig'
)
)
))
;
}
It generated url like this:
/app_dev.php/admin/mobispot/discodes/discode/300876/ispremium
My template for this link:
Link
I dont' know how to solve this problems:
How to define custom controller for that route pass?
Now I have an error:
Method "Sonata\AdminBundle\Controller\CRUDController::ispremiumAction" does not exist.
Can I change generated url with generateUrl method?
When you are creating service for EntityAdmin class the third argument is the controller name. You can create a class that extends CRUDController and set it in service. e.g
The controller,
//Vendor\YourBundle\Controller\EntityAdminController.php
class EntityAdminController extends CRUDController
{
public function ispremiumAction()
{
//process
}
}
In services.yml,
entity.admin.service:
class: FQCN\Of\EntityAdmin
tags:
- { name: sonata.admin, manager_type: orm, group: your_group, label: Label }
arguments: [null, FQCN\Of\Entity, VendorYourBundle:EntityAdmin]