问题
我使用了这个解决方案https://stackoverflow.com/a/15167450/2910183,但是当我尝试打开管理仪表板 ( http://localhost/app_dev.php/admin/dashboard
) 时出现以下错误。清理缓存后也会发生这种情况。
ClassNotFoundException:尝试从 ~/htdocs/symfony2training/app/cache/dev/appDevDebugProjectContainer.php 第 2216 行中的命名空间“Acme\ProductBundle\Block”加载类“AcmeBlockService”。您需要从另一个命名空间“使用”它吗?
有谁知道问题出在哪里?
代码
这是我的一部分app/config/config.yml
sonata_block:
default_contexts: [cms]
blocks:
sonata.admin.block.admin_list:
contexts: [admin]
sonata.user.block.menu: # used to display the menu in profile pages
sonata.user.block.account: # used to display menu option (login option)
acme.block.products:
sonata_admin:
dashboard:
blocks:
# display a dashboard block
- { position: left, type: acme.block.products }
- { position: left, type: sonata.admin.block.admin_list }
我的一部分src/Acme/ProductBundle/Resources/config/services.yml
services:
acme.block.products:
id: acme.block.products
class: Acme\ProductBundle\Block\ProductsBlockService
arguments:
- { name: service, id: templating }
tags:
- { name: sonata.block }
我的src/Acme/ProductBundle/Document/Products.php
文件在:
<?php
namespace Acme\ProductBundle\Block;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Sonata\BlockBundle\Model\BlockInterface;
use Sonata\BlockBundle\Block\BlockContextInterface;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Validator\ErrorElement;
class ProductsBlockService extends BaseBlockService {
public function getName() {
return 'Products';
}
public function getDefaultSettings() {
return array();
}
public function validateBlock(ErrorElement $errorElement, BlockInterface $block) {
}
public function buildEditForm(FormMapper $formMapper, BlockInterface $block) {
}
public function execute(BlockInterface $block, Response $response = null) {
$settings = array_merge($this->getDefaultSettings(), $block->getSettings());
return $this->renderResponse('AcmeProductBundle:Block:admin_products.html.twig', array(
'block' => $block,
'settings' => $settings
), $response);
}
}
解决方案
- 我查看了另一个块 (
vendor/sonata-project/user-bundle/Sonata/UserBundle/Block/AccountBlockService.php
),我意识到它的文件名就像类名。所以我src/Acme/ProductBundle/Document/Products.php
改为src/Acme/ProductBundle/Document/ProductsBlockService.php
- 它有效,但出现了另一个错误:
FatalErrorException:编译错误:Acme\ProductBundle\Block\ProductsBlockService::execute() 的声明必须与 Sonata\BlockBundle\Block\BlockServiceInterface::execute(Sonata\BlockBundle\Block\BlockContextInterface $blockContext, Symfony\Component\HttpFoundation\响应 $response = NULL) 在 ~/htdocs/symfony2training/src/Acme/ProductBundle/Block/ProductsBlockService.php 行 0
- 解决方法写在错误信息中:Acme\ProductBundle\Block\ProductsBlockService::execute() must be compatible with Sonata\BlockBundle\Block\BlockServiceInterface::execute()。所以我查看了我的助手(来自 1. 的AccountBlockService.php),比较
execute()
方法并编写我自己的解决方案。
所以最后我的src/Acme/ProductBundle/Document/ProductsBlockService.php
文件如下所示。
<?php
namespace Acme\ProductBundle\Block;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Validator\ErrorElement;
use Sonata\BlockBundle\Block\BaseBlockService;
use Sonata\BlockBundle\Block\BlockContextInterface;
use Sonata\BlockBundle\Model\BlockInterface;
use Sonata\UserBundle\Menu\ProfileMenuBuilder;
use Sonata\UserBundle\Model\UserInterface;
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Security\Core\SecurityContextInterface;
class ProductsBlockService extends BaseBlockService {
public function getName() {
return 'Products';
}
public function validateBlock(ErrorElement $errorElement, BlockInterface $block) {
}
public function buildEditForm(FormMapper $formMapper, BlockInterface $block) {
}
public function setDefaultSettings(OptionsResolverInterface $resolver) {
$resolver->setDefaults(array(
'template' => 'AcmeProductBundle:Block:admin_products.html.twig',
'ttl' => 0
));
}
public function execute(BlockContextInterface $blockContext, Response $response = null) {
return $this->renderPrivateResponse($blockContext->getTemplate(), array(
'block' => $blockContext->getBlock(),
'context' => $blockContext,
), $response);
}
}