I have created a block for sonata page that includes a title, a text, an image (from sonata media) and should include a link to another page on the site.
Considering the website will be bilingual (including the URLs), I can't have the user type the link in the admin. The best option would probably be to have a dropdown list of all active pages on the site, but I didn't manage to do it.
In sonata page admin, when you create (or edit) a page, there is actually such a list, the "Destination" field. So I dug a little and found the PageSelectorType which uses a function called getChoices() that would do the trick. However I didn't manage to use that function (or that field) in my block's admin.
Here's my block form so far :
public function buildEditForm(FormMapper $formMapper, BlockInterface $block)
{
$formMapper
->add('settings', 'sonata_type_immutable_array', array(
'keys' => array(
array('title', 'text', array('required' => false)),
array('texte', 'text', array('required' => false)),
array($this->getMediaBuilder($formMapper), null, array('context' => 'media_accueil')),
)
))
;
}
Any idea ?
Got it, there may be a better (cleaner) solution, but at least it works. Here are the steps :
In services.yml, add the page manager service as a parameter :
sonata.block.service.text_with_link:
class: Application\Sonata\PageBundle\Block\TextWithLinkBlockService
arguments:
- sonata.block.service.text_with_link
- "@templating"
- @sonata.page.manager.page
tags:
- { name: sonata.block }
In your BlockService php file, add the __construct method as follow to initialize the page manager :
class TexteTitreBlockService extends BaseBlockService
{
/**
* @var PageManagerInterface
*/
protected $pageManager;
/**
* @param string $name
* @param EngineInterface $templating
* @param PageManagerInterface $pageManager
*/
public function __construct($name, EngineInterface $templating, PageManagerInterface $pageManager)
{
parent::__construct($name, $templating);
$this->pageManager = $pageManager;
}
}
Then all you need to do is to get the list of pages :
$pageList = $this->pageManager->findBy(array(
'routeName' => Page::PAGE_ROUTE_CMS_NAME,
));
And you can then use the content of that variable to use in a ChoiceType::class (with whatever is useful to you, the page name, the page slug, etc...)