Есть ли способ для службы блокировки получить идентификатор страницы, с которой она вызывается?

В моем приложении Symfony 3.3 я создал блочную службу с использованием SonataBlockBundle. Теперь я хочу вытащить некоторые другие значения полей со страницы, на которой находится блок. Другими словами, я хочу сделать что-то вроде этого:

public function configureSettings(OptionsResolver $resolver)
{
    $pageRepository = $this->doctrine->getRepository('ApplicationSonataPageBundle:Page');

    $pageId = someMagicalMethodCall();

    $page = $repository->findOneBy(['id' => $pageId]);
    $images = $page->getImageUrls;
    $resolver->setDefaults(array(
        'content' => 'Some custom content',
        'images' => $images,
        'template' => 'AppBundle:Block:block_media.html.twig',
    ));
}

Это возможно? Если да, то что бы я поставил вместо someMagicalMethodCall в блоке выше?


person Patrick    schedule 28.02.2018    source источник
comment
какую платформу / фреймворк вы здесь используете?   -  person Josh Woodcock    schedule 28.02.2018
comment
Хороший вопрос, Джош. Увидев ваш комментарий, я отредактировал вопрос, включив в него эту информацию.   -  person Patrick    schedule 28.02.2018


Ответы (2)


Это возможно, но вам нужно добавить в свой блок дополнительную услугу - CmsManagerSelector. Затем в вашем configureSettings вам нужно получить правильный менеджер и получить от него текущий экземпляр страницы. Например, в вашем коде:

public function configureSettings(OptionsResolver $resolver)
{
    $cmsManager = $this->cmsManagerSelector->retrieve();
    // $page will be the Page object already, no need to call doctrine repository. Reference: https://github.com/sonata-project/SonataPageBundle/blob/3.x/src/CmsManager/BaseCmsPageManager.php#L38
    $page = $cmsManager->getCurrentPage();

    $images = $page->getImageUrls;
    $resolver->setDefaults(array(
        'content' => 'Some custom content',
        'images' => $images,
        'template' => 'AppBundle:Block:block_media.html.twig',
    ));
}
person Jakub Krawczyk    schedule 28.02.2018
comment
Спасибо! Я просто попытался ввести @CmsManagerSelector в admin.yml и получил исключение ServiceNotFoundException. Есть ли другое имя, под которым живет этот объект? - person Patrick; 28.02.2018
comment
@Patrickatwork, если вы используете автоматическое подключение, вы можете просто указать CmsManagerSelectorInterface typehint в конструкторе. Если нет, я считаю, что sonata.page.cms_manager_selector - правильное имя службы. - person Jakub Krawczyk; 28.02.2018
comment
Похоже, что в основном он работает, но по какой-то причине вызов $ page- ›getImages () дает мне Call to a member function getImages() on null. Таким образом, похоже, что у приложения возникли проблемы с поиском страницы. - person Patrick; 28.02.2018
comment
А вы уверены, что здесь сохранен снимок вашей страницы? $cmsManager->getCurrentPage(); возвращает значение null или вы выполнили какие-то операции после него? - person Jakub Krawczyk; 28.02.2018
comment
Он определенно возвращает null, поскольку вызов функции-члена находится на следующей строке и после этого не используется. - person Patrick; 28.02.2018
comment
Конфигурация правильная? Вы очистили кеш. Я дважды проверил свой проект, а также подтвердил, что тот же подход используется в самом SonataPageBundle - github.com/sonata-project/SonataPageBundle/blob/2.x/Block/. - person Jakub Krawczyk; 28.02.2018
comment
Интересно то, что исключение возникает только при попытках встроенного редактирования / удаления на бэкэнде. На передней панели все выглядит нормально. - person Patrick; 28.02.2018
comment
Вам нужно установить его в configureSettings()? Может быть, было бы неплохо переместить это в buildEditForm(). Тогда у вас будет доступ к методу BlockInterface with getPage(), который используется, как здесь: github.com/sonata-project/SonataPageBundle/blob/3.x/src/Block/ - person Jakub Krawczyk; 28.02.2018

Благодаря Якубу Кравчику и наставнику я нашел эту страницу:

Получение экземпляра контейнера в настраиваемом блоке сонаты

... что привело меня к другому способу получения страницы, связанной с блоком, из метода execute (). Итак, теперь у меня есть следующий код, который мне хорошо служит:

public function execute(BlockContextInterface $blockContext, Response $response = null)
{
    $page = $blockContext->getBlock()->getPage();
    $localImages = $page->getImages();
    $imageProvider = $this->provider;
    foreach ($localImages as $key => $image) {
        $publicImages[$key]['url'] = $imageProvider->generatePublicUrl($image, 'reference');
        $publicImages[$key]['name'] = $image->getName();
    }
    $settings = $blockContext->getSettings();
    $settings['images'] = $publicImages;
    return $this->renderResponse($blockContext->getTemplate(), array(
        'block' => $blockContext->getBlock(),
        'settings' => $settings,
    ), $response);
}

Еще раз спасибо всем причастным.

person Patrick    schedule 28.02.2018