Actualización

This commit is contained in:
Xes
2025-04-10 12:24:57 +02:00
parent 8969cc929d
commit 45420b6f0d
39760 changed files with 4303286 additions and 0 deletions

View File

@@ -0,0 +1,19 @@
<?php
/*
* 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\Exception;
/**
* Interface to implement exception identified as block-specific exceptions.
*/
interface BlockExceptionInterface
{
}

View File

@@ -0,0 +1,18 @@
<?php
/*
* 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\Exception;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class BlockNotFoundException extends NotFoundHttpException
{
}

View File

@@ -0,0 +1,18 @@
<?php
/*
* 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\Exception;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class BlockOptionsException extends NotFoundHttpException
{
}

View File

@@ -0,0 +1,43 @@
<?php
/*
* 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\Exception\Filter;
use Sonata\BlockBundle\Model\BlockInterface;
/**
* This filter handles exceptions only when debug mode is enabled.
*
* @author Olivier Paradis <paradis.olivier@gmail.com>
*/
class DebugOnlyFilter implements FilterInterface
{
/**
* @var bool
*/
protected $debug;
/**
* @param bool $debug
*/
public function __construct($debug)
{
$this->debug = $debug;
}
/**
* {@inheritdoc}
*/
public function handle(\Exception $exception, BlockInterface $block)
{
return $this->debug ? true : false;
}
}

View File

@@ -0,0 +1,34 @@
<?php
/*
* 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\Exception\Filter;
use Sonata\BlockBundle\Model\BlockInterface;
/**
* Interface for the exception filter used in the exception strategy management.
*
* It's purpose is to define which exceptions should be managed and which should simply be ignored.
*
* @author Olivier Paradis <paradis.olivier@gmail.com>
*/
interface FilterInterface
{
/**
* Returns whether or not this filter handles this exception for given block.
*
* @param \Exception $exception Exception to manage
* @param BlockInterface $block Block that provoked the exception
*
* @return bool
*/
public function handle(\Exception $exception, BlockInterface $block);
}

View File

@@ -0,0 +1,44 @@
<?php
/*
* 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\Exception\Filter;
use Sonata\BlockBundle\Model\BlockInterface;
/**
* This filter ignores exceptions that inherit a given class or interface, or in other words, it will only handle
* exceptions that do not inherit the given class or interface.
*
* @author Olivier Paradis <paradis.olivier@gmail.com>
*/
class IgnoreClassFilter implements FilterInterface
{
/**
* @var string
*/
protected $class;
/**
* @param string $class
*/
public function __construct($class)
{
$this->class = $class;
}
/**
* {@inheritdoc}
*/
public function handle(\Exception $exception, BlockInterface $block)
{
return !$exception instanceof $this->class;
}
}

View File

@@ -0,0 +1,30 @@
<?php
/*
* 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\Exception\Filter;
use Sonata\BlockBundle\Model\BlockInterface;
/**
* This filter will handle all exceptions.
*
* @author Olivier Paradis <paradis.olivier@gmail.com>
*/
class KeepAllFilter implements FilterInterface
{
/**
* {@inheritdoc}
*/
public function handle(\Exception $exception, BlockInterface $block)
{
return true;
}
}

View File

@@ -0,0 +1,30 @@
<?php
/*
* 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\Exception\Filter;
use Sonata\BlockBundle\Model\BlockInterface;
/**
* This filters will ignore all exceptions.
*
* @author Olivier Paradis <paradis.olivier@gmail.com>
*/
class KeepNoneFilter implements FilterInterface
{
/**
* {@inheritdoc}
*/
public function handle(\Exception $exception, BlockInterface $block)
{
return false;
}
}

View File

@@ -0,0 +1,90 @@
<?php
/*
* 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\Exception\Renderer;
use Sonata\BlockBundle\Model\BlockInterface;
use Symfony\Component\Debug\Exception\FlattenException;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Templating\EngineInterface;
/**
* This renderer uses a template to display an error message at the block position with extensive debug information.
*
* @author Olivier Paradis <paradis.olivier@gmail.com>
*/
class InlineDebugRenderer implements RendererInterface
{
/**
* @var EngineInterface
*/
protected $templating;
/**
* @var string
*/
protected $template;
/**
* @var bool
*/
protected $forceStyle;
/**
* @var bool
*/
protected $debug;
/**
* @param EngineInterface $templating Templating engine
* @param string $template Template to render
* @param bool $debug Whether the debug is enabled or not
* @param bool $forceStyle Whether to force style within the template or not
*/
public function __construct(EngineInterface $templating, $template, $debug, $forceStyle = true)
{
$this->templating = $templating;
$this->template = $template;
$this->debug = $debug;
$this->forceStyle = $forceStyle;
}
/**
* {@inheritdoc}
*/
public function render(\Exception $exception, BlockInterface $block, Response $response = null)
{
$response = $response ?: new Response();
// enforce debug mode or ignore silently
if (!$this->debug) {
return $response;
}
$flattenException = FlattenException::create($exception);
$code = $flattenException->getStatusCode();
$parameters = [
'exception' => $flattenException,
'status_code' => $code,
'status_text' => isset(Response::$statusTexts[$code]) ? Response::$statusTexts[$code] : '',
'logger' => false,
'currentContent' => false,
'block' => $block,
'forceStyle' => $this->forceStyle,
];
$content = $this->templating->render($this->template, $parameters);
$response->setContent($content);
return $response;
}
}

View File

@@ -0,0 +1,62 @@
<?php
/*
* 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\Exception\Renderer;
use Sonata\BlockBundle\Model\BlockInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Templating\EngineInterface;
/**
* This renderer uses a template to display an error message at the block position.
*
* @author Olivier Paradis <paradis.olivier@gmail.com>
*/
class InlineRenderer implements RendererInterface
{
/**
* @var EngineInterface
*/
protected $templating;
/**
* @var string
*/
protected $template;
/**
* @param EngineInterface $templating Templating engine
* @param string $template Template to render
*/
public function __construct(EngineInterface $templating, $template)
{
$this->templating = $templating;
$this->template = $template;
}
/**
* {@inheritdoc}
*/
public function render(\Exception $exception, BlockInterface $block, Response $response = null)
{
$parameters = [
'exception' => $exception,
'block' => $block,
];
$content = $this->templating->render($this->template, $parameters);
$response = $response ?: new Response();
$response->setContent($content);
return $response;
}
}

View File

@@ -0,0 +1,31 @@
<?php
/*
* 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\Exception\Renderer;
use Sonata\BlockBundle\Model\BlockInterface;
use Symfony\Component\HttpFoundation\Response;
/**
* This renderer re-throws the exception and lets the framework handle the exception.
*
* @author Olivier Paradis <paradis.olivier@gmail.com>
*/
class MonkeyThrowRenderer implements RendererInterface
{
/**
* {@inheritdoc}
*/
public function render(\Exception $banana, BlockInterface $block, Response $response = null)
{
throw $banana;
}
}

View File

@@ -0,0 +1,34 @@
<?php
/*
* 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\Exception\Renderer;
use Sonata\BlockBundle\Model\BlockInterface;
use Symfony\Component\HttpFoundation\Response;
/**
* Interface for exception renderer.
*
* @author Olivier Paradis <paradis.olivier@gmail.com>
*/
interface RendererInterface
{
/**
* Renders an exception into an HTTP response.
*
* @param \Exception $exception Exception provoked
* @param BlockInterface $block Block that provoked the exception
* @param Response $response Response to alter
*
* @return Response
*/
public function render(\Exception $exception, BlockInterface $block, Response $response = null);
}

View File

@@ -0,0 +1,210 @@
<?php
/*
* 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\Exception\Strategy;
use Sonata\BlockBundle\Exception\Filter\FilterInterface;
use Sonata\BlockBundle\Exception\Renderer\RendererInterface;
use Sonata\BlockBundle\Model\BlockInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Response;
/**
* The strategy manager handles exceptions thrown by a block. It uses an exception filter to identify which exceptions
* it should handle or ignore. It then uses an exception renderer to "somehow" display the exception.
*
* @author Olivier Paradis <paradis.olivier@gmail.com>
*/
class StrategyManager implements StrategyManagerInterface
{
/**
* @var ContainerInterface
*/
protected $container;
/**
* @var array
*/
protected $filters;
/**
* @var array
*/
protected $renderers;
/**
* @var array
*/
protected $blockFilters;
/**
* @var array
*/
protected $blockRenderers;
/**
* @var string
*/
protected $defaultFilter;
/**
* @var string
*/
protected $defaultRenderer;
/**
* @param ContainerInterface $container Dependency injection container
* @param array $filters Filter definitions
* @param array $renderers Renderer definitions
* @param array $blockFilters Filter names for each block
* @param array $blockRenderers Renderer names for each block
*/
public function __construct(ContainerInterface $container, array $filters, array $renderers, array $blockFilters, array $blockRenderers)
{
$this->container = $container;
$this->filters = $filters;
$this->renderers = $renderers;
$this->blockFilters = $blockFilters;
$this->blockRenderers = $blockRenderers;
}
/**
* Sets the default filter name.
*
* @param string $name
*
* @throws \InvalidArgumentException
*/
public function setDefaultFilter($name)
{
if (!array_key_exists($name, $this->filters)) {
throw new \InvalidArgumentException(sprintf('Cannot set default exception filter "%s". It does not exist.', $name));
}
$this->defaultFilter = $name;
}
/**
* Sets the default renderer name.
*
* @param string $name
*
* @throws \InvalidArgumentException
*/
public function setDefaultRenderer($name)
{
if (!array_key_exists($name, $this->renderers)) {
throw new \InvalidArgumentException(sprintf('Cannot set default exception renderer "%s". It does not exist.', $name));
}
$this->defaultRenderer = $name;
}
/**
* {@inheritdoc}
*/
public function handleException(\Exception $exception, BlockInterface $block, Response $response = null)
{
$response = $response ?: new Response();
$response->setPrivate();
$filter = $this->getBlockFilter($block);
if ($filter->handle($exception, $block)) {
$renderer = $this->getBlockRenderer($block);
$response = $renderer->render($exception, $block, $response);
}
// render empty block template?
return $response;
}
/**
* Returns the exception renderer for given block.
*
* @param BlockInterface $block
*
* @throws \RuntimeException
*
* @return RendererInterface
*/
public function getBlockRenderer(BlockInterface $block)
{
$type = $block->getType();
$name = isset($this->blockRenderers[$type]) ? $this->blockRenderers[$type] : $this->defaultRenderer;
$service = $this->getRendererService($name);
if (!$service instanceof RendererInterface) {
throw new \RuntimeException(sprintf('The service "%s" is not an exception renderer', $name));
}
return $service;
}
/**
* Returns the exception filter for given block.
*
* @param BlockInterface $block
*
* @throws \RuntimeException
*
* @return FilterInterface
*/
public function getBlockFilter(BlockInterface $block)
{
$type = $block->getType();
$name = isset($this->blockFilters[$type]) ? $this->blockFilters[$type] : $this->defaultFilter;
$service = $this->getFilterService($name);
if (!$service instanceof FilterInterface) {
throw new \RuntimeException(sprintf('The service "%s" is not an exception filter', $name));
}
return $service;
}
/**
* Returns the filter service for given filter name.
*
* @param string $name
*
* @throws \RuntimeException
*
* @return object
*/
protected function getFilterService($name)
{
if (!isset($this->filters[$name])) {
throw new \RuntimeException('The filter "%s" does not exist.');
}
return $this->container->get($this->filters[$name]);
}
/**
* Returns the renderer service for given renderer name.
*
* @param string $name
*
* @throws \RuntimeException
*
* @return object
*/
protected function getRendererService($name)
{
if (!isset($this->renderers[$name])) {
throw new \RuntimeException('The renderer "%s" does not exist.');
}
return $this->container->get($this->renderers[$name]);
}
}

View File

@@ -0,0 +1,34 @@
<?php
/*
* 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\Exception\Strategy;
use Sonata\BlockBundle\Model\BlockInterface;
use Symfony\Component\HttpFoundation\Response;
/**
* Interface for exception strategy management.
*
* @author Olivier Paradis <paradis.olivier@gmail.com>
*/
interface StrategyManagerInterface
{
/**
* Handles an exception for a given block.
*
* @param \Exception $exception Exception to handle
* @param BlockInterface $block Block that provoked the exception
* @param Response $response Response provided to the block service
*
* @return Response
*/
public function handleException(\Exception $exception, BlockInterface $block, Response $response = null);
}