<?php
declare(strict_types=1);
/*
* This file is part of the Sonata Project package.
*
* (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Sonata\BlockBundle\Block\Service;
use Sonata\BlockBundle\Block\BlockContextInterface;
use Sonata\BlockBundle\Model\BlockInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Templating\EngineInterface;
use Twig\Environment;
/**
* @author Sullivan Senechal <soullivaneuh@gmail.com>
*/
abstract class AbstractBlockService implements BlockServiceInterface
{
/**
* @var string|null
*/
protected $name;
/**
* NEXT_MAJOR: Remove this property.
*
* @var EngineInterface|null
*/
protected $templating;
/**
* @var Environment
*/
private $twig;
/**
* NEXT_MAJOR: Make `$twig` argument mandatory and remove other arguments.
*
* @param Environment|EngineInterface|string $templatingOrDeprecatedName
*/
public function __construct($templatingOrDeprecatedName = null, ?EngineInterface $templating = null)
{
// $this->twig = $twig;
// NEXT_MAJOR: Uncomment the previous assignment and remove the following lines in this method.
if ($templatingOrDeprecatedName instanceof Environment) {
$this->name = '';
$this->twig = $templatingOrDeprecatedName;
} else {
if (0 !== strpos(static::class, __NAMESPACE__.'\\')) {
$class = 'c' === static::class[0] && 0 === strpos(static::class, "class@anonymous\0") ? get_parent_class(static::class).'@anonymous' : static::class;
@trigger_error(
sprintf(
'Passing %s as argument 1 to %s::%s() is deprecated since sonata-project/block-bundle 3.16 and will throw a \TypeError as of 4.0. You must pass an instance of %s instead.',
\is_object($templatingOrDeprecatedName) ? 'instance of '.\get_class($templatingOrDeprecatedName) : \gettype($templatingOrDeprecatedName),
$class,
__FUNCTION__,
Environment::class
),
E_USER_DEPRECATED
);
}
if ($templatingOrDeprecatedName instanceof EngineInterface) {
$this->name = '';
$this->templating = $templatingOrDeprecatedName;
} elseif (\is_string($templatingOrDeprecatedName)) {
$this->name = $templatingOrDeprecatedName;
$this->templating = $templating;
} else {
$class = 'c' === static::class[0] && 0 === strpos(static::class, "class@anonymous\0") ? get_parent_class(static::class).'@anonymous' : static::class;
throw new \TypeError(sprintf(
'Argument 1 passed to %s::%s() must be a string or an instance of %s or %s, %s given.',
$class,
__FUNCTION__,
Environment::class,
EngineInterface::class,
\is_object($templatingOrDeprecatedName) ? 'instance of '.\get_class($templatingOrDeprecatedName) : \gettype($templatingOrDeprecatedName)
));
}
}
}
/**
* Returns a Response object than can be cacheable.
*
* @param string $view
*
* @return Response
*/
public function renderResponse($view, array $parameters = [], Response $response = null)
{
if (null === $this->twig) {
return $this->getTemplating()->renderResponse($view, $parameters, $response);
}
// NEXT_MAJOR: Remove the previous condition
if (null === $response) {
$response = new Response();
}
$response->setContent($this->twig->render($view, $parameters));
return $response;
}
/**
* Returns a Response object that cannot be cacheable, this must be used if the Response is related to the user.
* A good solution to make the page cacheable is to configure the block to be cached with javascript ...
*
* @param string $view
*
* @return Response
*/
public function renderPrivateResponse($view, array $parameters = [], Response $response = null)
{
return $this->renderResponse($view, $parameters, $response)
->setTtl(0)
->setPrivate()
;
}
public function setDefaultSettings(OptionsResolverInterface $resolver)
{
if (!$resolver instanceof OptionsResolver) {
throw new \BadMethodCallException(
sprintf('Calling %s with %s is unsupported', __METHOD__, \get_class($resolver))
);
}
$this->configureSettings($resolver);
}
/**
* Define the default options for the block.
*/
public function configureSettings(OptionsResolver $resolver)
{
}
public function getCacheKeys(BlockInterface $block)
{
return [
'block_id' => $block->getId(),
'updated_at' => $block->getUpdatedAt() ? $block->getUpdatedAt()->format('U') : strtotime('now'),
];
}
public function load(BlockInterface $block)
{
}
public function getJavascripts($media)
{
return [];
}
public function getStylesheets($media)
{
return [];
}
public function execute(BlockContextInterface $blockContext, Response $response = null)
{
return $this->renderResponse($blockContext->getTemplate(), [
'block_context' => $blockContext,
'block' => $blockContext->getBlock(),
], $response);
}
public function getName()
{
return $this->name;
}
/**
* NEXT_MAJOR: Remove this method.
*
* @deprecated since sonata-project/block-bundle 3.17
*/
public function getTemplating()
{
$class = 'c' === static::class[0] && 0 === strpos(static::class, "class@anonymous\0") ? get_parent_class(static::class).'@anonymous' : static::class;
@trigger_error(
sprintf(
'Method %s::%s() is deprecated since sonata-project/block-bundle 3.17 and will be removed as of version 4.0.',
$class,
__FUNCTION__
),
E_USER_DEPRECATED
);
if (null !== $this->twig) {
throw new \BadMethodCallException(sprintf(
'Calling %1$s::%2$s() is not allowed when an instance of %3$s is passed as argument 1 to %1$s::__construct().',
$class,
__FUNCTION__,
Environment::class
));
}
return $this->templating;
}
}