Я только что попытался установить Symfony CMF с пакетом Sonata Admin, но у меня возникли некоторые проблемы с его включением. Видимо, я не первый, но другие ответы не очень помогли мне, к сожалению.
Это мое полное исключение:
Во время рендеринга шаблона было сгенерировано исключение («Тип блока» sonata.admin.block.admin_list «не существует») в SonataAdminBundle: Core: dashboard.html.twig в строке 35.
И это мой AppKernel.php:
$bundles = array(
// Symfony Standard Edition Bundles
new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
new Symfony\Bundle\SecurityBundle\SecurityBundle(),
new Symfony\Bundle\TwigBundle\TwigBundle(),
new Symfony\Bundle\MonologBundle\MonologBundle(),
new Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle(),
new Symfony\Bundle\AsseticBundle\AsseticBundle(),
new Doctrine\Bundle\DoctrineBundle\DoctrineBundle(),
new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
// Symfony CMF Standard Edition Bundles
new Doctrine\Bundle\PHPCRBundle\DoctrinePHPCRBundle(),
new Doctrine\Bundle\DoctrineCacheBundle\DoctrineCacheBundle(),
new Symfony\Cmf\Bundle\CoreBundle\CmfCoreBundle(),
new Symfony\Cmf\Bundle\ContentBundle\CmfContentBundle(),
new Symfony\Cmf\Bundle\RoutingBundle\CmfRoutingBundle(),
new Symfony\Cmf\Bundle\SimpleCmsBundle\CmfSimpleCmsBundle(),
new Symfony\Cmf\Bundle\BlockBundle\CmfBlockBundle(),
new Sonata\BlockBundle\SonataBlockBundle(),
new Sonata\CoreBundle\SonataCoreBundle(),
new Symfony\Cmf\Bundle\MenuBundle\CmfMenuBundle(),
new Knp\Bundle\MenuBundle\KnpMenuBundle(),
new Symfony\Cmf\Bundle\CreateBundle\CmfCreateBundle(),
new FOS\RestBundle\FOSRestBundle(),
new JMS\SerializerBundle\JMSSerializerBundle(),
new Sonata\jQueryBundle\SonatajQueryBundle(),
new Sonata\DoctrinePHPCRAdminBundle\SonataDoctrinePHPCRAdminBundle(),
new Sonata\AdminBundle\SonataAdminBundle(),
// Remove this Bundle when using the SE as the basis for a new project
new Acme\DemoBundle\AcmeDemoBundle(),
);
Мои соответствующие части config.yml:
# Sonata
sonata_block:
default_contexts: [cms]
blocks:
sonata.admin.block.admin_list:
contexts: [admin]
sonata.user.block.menu:
sonata.user.block.account:
sonata.block.service.text:
И напоследок мой маршрут:
admin:
resource: '@SonataAdminBundle/Resources/config/routing/sonata_admin.xml'
prefix: /admin
_sonata_admin:
resource: .
type: sonata_admin
prefix: /admin
Любая помощь будет принята с благодарностью, я верю, что следовал инструкциям, и мое единственное изменение — добавление моего IP в app_dev.php. Я также попытался очистить свой кэш без каких-либо результатов ….
Ошибка предполагает, что ваша конфигурация sonata_block не читается или может быть перезаписана.
Не могли бы вы проверить, есть ли у вас дублирующее определение для него в одном из ваших файлов конфигурации (config * .yml)?
Некоторое время я бьюсь над этим и добавляю отладочный дамп загрузчиков блоков в Sonata\BlockBundle\Block\BlockLoaderChain::load()
, Я смог увидеть, что мой блок-загрузчик возвращался true
по умолчанию включен if ($loader->support($block)) {...
, Это превзошло загрузчик сервиса Sonata, который должен поддерживать (и загружать) этот блок. Погрузчики:
array:2 [▼
0 => BlockLoader {#617 ▼
#entityManager: DoctrineORMEntityManager_000000005e8b2927000000004be687142a8746960d6f2b18cb3522b67eef8a8d {#208 …2}
#types: array:3 [▼
0 => "cmf.block.action"1 => "cmf.block.container"2 => "cmf.block.simple"]
}
1 => ServiceLoader {#618 ▼
#types: array:1 [▼
0 => "sonata.admin.block.admin_list"]
}
]
Причина в том, что мой загрузчик расширяет ServiceLoader
, а также ->support($block)
просто проверяет, содержит ли мета-массив блока тип.
Поэтому я добавил свой support()
метод моего загрузчика блоков, который теперь будет поддерживать только те типы, которые я определил. Вот весь загрузчик:
namespace ExampleBundle\Cms\Loader;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityRepository;
use Sonata\BlockBundle\Block\Loader\ServiceLoader;
use Sonata\BlockBundle\Model\BlockInterface;
/**
* ORM block loader.
*/
class BlockLoader extends ServiceLoader
{
/**
* @var string
*/
const TYPE_ACTION = 'cmf.block.action';
/**
* @var string
*/
const TYPE_CONTAINER = 'cmf.block.container';
/**
* @var string
*/
const TYPE_SIMPLE = 'cmf.block.simple';
/**
* @var \Doctrine\ORM\EntityManager
*/
protected $entityManager;
/**
* {@inheritdoc}
*/
public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
parent::__construct(array(
self::TYPE_ACTION,
self::TYPE_CONTAINER,
self::TYPE_SIMPLE,
));
}
/**
* {@inheritdoc}
*/
public function load($configuration): BlockInterface
{
$blockDefault = parent::load($configuration);
$block = $this->getRepository($configuration['type'])->findOneByName($configuration['name']);
return $block instanceof BlockInterface ? $block : $blockDefault;
}
/**
* Get the repository for a given block type.
*
* @param string $type The block type.
*
* @return \Doctrine\ORM\Repository
*/
protected function getRepository(string $type): EntityRepository
{
foreach ($this->entityManager->getMetadataFactory()->getAllMetadata() as $metadata) {
if ($metadata->discriminatorValue === $type) {
$baseName = str_replace($metadata->namespace . '\\', '', $metadata->name);
return $this->entityManager->getRepository(sprintf('CmsBlock:%s', $baseName));
}
}
throw new \RuntimeException(sprintf('Could not find repository for block type "%s%.', $type));
}
/**
* {@inheritdoc}
*/
public function support($configuration)
{
if (parent::support($configuration) && $this->exists($configuration['type'])) {
return true;
}
return false;
}
}