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,80 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Templating;
use Symfony\Component\Templating\DelegatingEngine as BaseDelegatingEngine;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Response;
/**
* DelegatingEngine selects an engine for a given template.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class DelegatingEngine extends BaseDelegatingEngine implements EngineInterface
{
protected $container;
/**
* Constructor.
*
* @param ContainerInterface $container The DI container
* @param array $engineIds An array of engine Ids
*/
public function __construct(ContainerInterface $container, array $engineIds)
{
$this->container = $container;
$this->engines = $engineIds;
}
/**
* {@inheritdoc}
*/
public function getEngine($name)
{
$this->resolveEngines();
return parent::getEngine($name);
}
/**
* {@inheritdoc}
*/
public function renderResponse($view, array $parameters = array(), Response $response = null)
{
$engine = $this->getEngine($view);
if ($engine instanceof EngineInterface) {
return $engine->renderResponse($view, $parameters, $response);
}
if (null === $response) {
$response = new Response();
}
$response->setContent($engine->render($view, $parameters));
return $response;
}
/**
* Resolved engine ids to their real engine instances from the container.
*/
private function resolveEngines()
{
foreach ($this->engines as $i => $engine) {
if (is_string($engine)) {
$this->engines[$i] = $this->container->get($engine);
}
}
}
}

View File

@@ -0,0 +1,36 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Templating;
use Symfony\Component\Templating\EngineInterface as BaseEngineInterface;
use Symfony\Component\HttpFoundation\Response;
/**
* EngineInterface is the interface each engine must implement.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
interface EngineInterface extends BaseEngineInterface
{
/**
* Renders a view and returns a Response.
*
* @param string $view The view name
* @param array $parameters An array of parameters to pass to the view
* @param Response $response A Response instance
*
* @return Response A Response instance
*
* @throws \RuntimeException if the template cannot be rendered
*/
public function renderResponse($view, array $parameters = array(), Response $response = null);
}

View File

@@ -0,0 +1,105 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Templating;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Session\Session;
/**
* GlobalVariables is the entry point for Symfony global variables in PHP templates.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class GlobalVariables
{
protected $container;
/**
* @param ContainerInterface $container The DI container
*/
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
/**
* Returns the current user.
*
* @return mixed
*
* @see TokenInterface::getUser()
*/
public function getUser()
{
if (!$this->container->has('security.token_storage')) {
return;
}
$tokenStorage = $this->container->get('security.token_storage');
if (!$token = $tokenStorage->getToken()) {
return;
}
$user = $token->getUser();
if (!is_object($user)) {
return;
}
return $user;
}
/**
* Returns the current request.
*
* @return Request|null The HTTP request object
*/
public function getRequest()
{
if ($this->container->has('request_stack')) {
return $this->container->get('request_stack')->getCurrentRequest();
}
}
/**
* Returns the current session.
*
* @return Session|null The session
*/
public function getSession()
{
if ($request = $this->getRequest()) {
return $request->getSession();
}
}
/**
* Returns the current app environment.
*
* @return string The current environment string (e.g 'dev')
*/
public function getEnvironment()
{
return $this->container->getParameter('kernel.environment');
}
/**
* Returns the current app debug mode.
*
* @return bool The current debug mode
*/
public function getDebug()
{
return (bool) $this->container->getParameter('kernel.debug');
}
}

View File

@@ -0,0 +1,67 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Templating\Helper;
use Symfony\Component\Templating\Helper\Helper;
use Symfony\Component\HttpKernel\Fragment\FragmentHandler;
use Symfony\Component\HttpKernel\Controller\ControllerReference;
/**
* ActionsHelper manages action inclusions.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class ActionsHelper extends Helper
{
private $handler;
/**
* Constructor.
*
* @param FragmentHandler $handler A FragmentHandler instance
*/
public function __construct(FragmentHandler $handler)
{
$this->handler = $handler;
}
/**
* Returns the fragment content for a given URI.
*
* @param string $uri A URI
* @param array $options An array of options
*
* @return string The fragment content
*
* @see FragmentHandler::render()
*/
public function render($uri, array $options = array())
{
$strategy = isset($options['strategy']) ? $options['strategy'] : 'inline';
unset($options['strategy']);
return $this->handler->render($uri, $strategy, $options);
}
public function controller($controller, $attributes = array(), $query = array())
{
return new ControllerReference($controller, $attributes, $query);
}
/**
* {@inheritdoc}
*/
public function getName()
{
return 'actions';
}
}

View File

@@ -0,0 +1,67 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Templating\Helper;
use Symfony\Component\Asset\Packages;
use Symfony\Component\Templating\Helper\Helper;
/**
* AssetsHelper helps manage asset URLs.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class AssetsHelper extends Helper
{
private $packages;
public function __construct(Packages $packages)
{
$this->packages = $packages;
}
/**
* Returns the public url/path of an asset.
*
* If the package used to generate the path is an instance of
* UrlPackage, you will always get a URL and not a path.
*
* @param string $path A public path
* @param string $packageName The name of the asset package to use
*
* @return string The public path of the asset
*/
public function getUrl($path, $packageName = null)
{
return $this->packages->getUrl($path, $packageName);
}
/**
* Returns the version of an asset.
*
* @param string $path A public path
* @param string $packageName The name of the asset package to use
*
* @return string The asset version
*/
public function getVersion($path, $packageName = null)
{
return $this->packages->getVersion($path, $packageName);
}
/**
* {@inheritdoc}
*/
public function getName()
{
return 'assets';
}
}

View File

@@ -0,0 +1,228 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Templating\Helper;
use Symfony\Component\Templating\Helper\Helper;
/**
* CodeHelper.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class CodeHelper extends Helper
{
protected $fileLinkFormat;
protected $rootDir;
protected $charset;
/**
* Constructor.
*
* @param string $fileLinkFormat The format for links to source files
* @param string $rootDir The project root directory
* @param string $charset The charset
*/
public function __construct($fileLinkFormat, $rootDir, $charset)
{
$this->fileLinkFormat = $fileLinkFormat ?: ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format');
$this->rootDir = str_replace('\\', '/', $rootDir).'/';
$this->charset = $charset;
}
/**
* Formats an array as a string.
*
* @param array $args The argument array
*
* @return string
*/
public function formatArgsAsText(array $args)
{
return strip_tags($this->formatArgs($args));
}
public function abbrClass($class)
{
$parts = explode('\\', $class);
$short = array_pop($parts);
return sprintf('<abbr title="%s">%s</abbr>', $class, $short);
}
public function abbrMethod($method)
{
if (false !== strpos($method, '::')) {
list($class, $method) = explode('::', $method, 2);
$result = sprintf('%s::%s()', $this->abbrClass($class), $method);
} elseif ('Closure' === $method) {
$result = sprintf('<abbr title="%s">%s</abbr>', $method, $method);
} else {
$result = sprintf('<abbr title="%s">%s</abbr>()', $method, $method);
}
return $result;
}
/**
* Formats an array as a string.
*
* @param array $args The argument array
*
* @return string
*/
public function formatArgs(array $args)
{
$result = array();
foreach ($args as $key => $item) {
if ('object' === $item[0]) {
$parts = explode('\\', $item[1]);
$short = array_pop($parts);
$formattedValue = sprintf('<em>object</em>(<abbr title="%s">%s</abbr>)', $item[1], $short);
} elseif ('array' === $item[0]) {
$formattedValue = sprintf('<em>array</em>(%s)', is_array($item[1]) ? $this->formatArgs($item[1]) : $item[1]);
} elseif ('string' === $item[0]) {
$formattedValue = sprintf("'%s'", htmlspecialchars($item[1], ENT_QUOTES, $this->getCharset()));
} elseif ('null' === $item[0]) {
$formattedValue = '<em>null</em>';
} elseif ('boolean' === $item[0]) {
$formattedValue = '<em>'.strtolower(var_export($item[1], true)).'</em>';
} elseif ('resource' === $item[0]) {
$formattedValue = '<em>resource</em>';
} else {
$formattedValue = str_replace("\n", '', var_export(htmlspecialchars((string) $item[1], ENT_QUOTES, $this->getCharset()), true));
}
$result[] = is_int($key) ? $formattedValue : sprintf("'%s' => %s", $key, $formattedValue);
}
return implode(', ', $result);
}
/**
* Returns an excerpt of a code file around the given line number.
*
* @param string $file A file path
* @param int $line The selected line number
*
* @return string An HTML string
*/
public function fileExcerpt($file, $line)
{
if (is_readable($file)) {
if (extension_loaded('fileinfo')) {
$finfo = new \Finfo();
// Check if the file is an application/octet-stream (eg. Phar file) because highlight_file cannot parse these files
if ('application/octet-stream' === $finfo->file($file, FILEINFO_MIME_TYPE)) {
return;
}
}
// highlight_file could throw warnings
// see https://bugs.php.net/bug.php?id=25725
$code = @highlight_file($file, true);
// remove main code/span tags
$code = preg_replace('#^<code.*?>\s*<span.*?>(.*)</span>\s*</code>#s', '\\1', $code);
$content = preg_split('#<br />#', $code);
$lines = array();
for ($i = max($line - 3, 1), $max = min($line + 3, count($content)); $i <= $max; ++$i) {
$lines[] = '<li'.($i == $line ? ' class="selected"' : '').'><code>'.self::fixCodeMarkup($content[$i - 1]).'</code></li>';
}
return '<ol start="'.max($line - 3, 1).'">'.implode("\n", $lines).'</ol>';
}
}
/**
* Formats a file path.
*
* @param string $file An absolute file path
* @param int $line The line number
* @param string $text Use this text for the link rather than the file path
*
* @return string
*/
public function formatFile($file, $line, $text = null)
{
$flags = ENT_QUOTES | ENT_SUBSTITUTE;
if (null === $text) {
$file = trim($file);
$fileStr = $file;
if (0 === strpos($fileStr, $this->rootDir)) {
$fileStr = str_replace($this->rootDir, '', str_replace('\\', '/', $fileStr));
$fileStr = htmlspecialchars($fileStr, $flags, $this->charset);
$fileStr = sprintf('<abbr title="%s">kernel.root_dir</abbr>/%s', htmlspecialchars($this->rootDir, $flags, $this->charset), $fileStr);
}
$text = sprintf('%s at line %d', $fileStr, $line);
}
if (false !== $link = $this->getFileLink($file, $line)) {
return sprintf('<a href="%s" title="Click to open this file" class="file_link">%s</a>', htmlspecialchars($link, $flags, $this->charset), $text);
}
return $text;
}
/**
* Returns the link for a given file/line pair.
*
* @param string $file An absolute file path
* @param int $line The line number
*
* @return string A link of false
*/
public function getFileLink($file, $line)
{
if ($this->fileLinkFormat && is_file($file)) {
return strtr($this->fileLinkFormat, array('%f' => $file, '%l' => $line));
}
return false;
}
public function formatFileFromText($text)
{
return preg_replace_callback('/in ("|&quot;)?(.+?)\1(?: +(?:on|at))? +line (\d+)/s', function ($match) {
return 'in '.$this->formatFile($match[2], $match[3]);
}, $text);
}
/**
* {@inheritdoc}
*/
public function getName()
{
return 'code';
}
protected static function fixCodeMarkup($line)
{
// </span> ending tag from previous line
$opening = strpos($line, '<span');
$closing = strpos($line, '</span>');
if (false !== $closing && (false === $opening || $closing < $opening)) {
$line = substr_replace($line, '', $closing, 7);
}
// missing </span> tag at the end of line
$opening = strpos($line, '<span');
$closing = strpos($line, '</span>');
if (false !== $opening && (false === $closing || $closing > $opening)) {
$line .= '</span>';
}
return $line;
}
}

View File

@@ -0,0 +1,250 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Templating\Helper;
use Symfony\Component\Templating\Helper\Helper;
use Symfony\Component\Form\FormRendererInterface;
use Symfony\Component\Form\FormView;
/**
* FormHelper provides helpers to help display forms.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Bernhard Schussek <bschussek@gmail.com>
*/
class FormHelper extends Helper
{
/**
* @var FormRendererInterface
*/
private $renderer;
/**
* @param FormRendererInterface $renderer
*/
public function __construct(FormRendererInterface $renderer)
{
$this->renderer = $renderer;
}
/**
* {@inheritdoc}
*/
public function getName()
{
return 'form';
}
/**
* Sets a theme for a given view.
*
* The theme format is "<Bundle>:<Controller>".
*
* @param FormView $view A FormView instance
* @param string|array $themes A theme or an array of theme
*/
public function setTheme(FormView $view, $themes)
{
$this->renderer->setTheme($view, $themes);
}
/**
* Renders the HTML for a form.
*
* Example usage:
*
* <?php echo view['form']->form($form) ?>
*
* You can pass options during the call:
*
* <?php echo view['form']->form($form, array('attr' => array('class' => 'foo'))) ?>
*
* <?php echo view['form']->form($form, array('separator' => '+++++')) ?>
*
* This method is mainly intended for prototyping purposes. If you want to
* control the layout of a form in a more fine-grained manner, you are
* advised to use the other helper methods for rendering the parts of the
* form individually. You can also create a custom form theme to adapt
* the look of the form.
*
* @param FormView $view The view for which to render the form
* @param array $variables Additional variables passed to the template
*
* @return string The HTML markup
*/
public function form(FormView $view, array $variables = array())
{
return $this->renderer->renderBlock($view, 'form', $variables);
}
/**
* Renders the form start tag.
*
* Example usage templates:
*
* <?php echo $view['form']->start($form) ?>>
*
* @param FormView $view The view for which to render the start tag
* @param array $variables Additional variables passed to the template
*
* @return string The HTML markup
*/
public function start(FormView $view, array $variables = array())
{
return $this->renderer->renderBlock($view, 'form_start', $variables);
}
/**
* Renders the form end tag.
*
* Example usage templates:
*
* <?php echo $view['form']->end($form) ?>>
*
* @param FormView $view The view for which to render the end tag
* @param array $variables Additional variables passed to the template
*
* @return string The HTML markup
*/
public function end(FormView $view, array $variables = array())
{
return $this->renderer->renderBlock($view, 'form_end', $variables);
}
/**
* Renders the HTML for a given view.
*
* Example usage:
*
* <?php echo $view['form']->widget($form) ?>
*
* You can pass options during the call:
*
* <?php echo $view['form']->widget($form, array('attr' => array('class' => 'foo'))) ?>
*
* <?php echo $view['form']->widget($form, array('separator' => '+++++')) ?>
*
* @param FormView $view The view for which to render the widget
* @param array $variables Additional variables passed to the template
*
* @return string The HTML markup
*/
public function widget(FormView $view, array $variables = array())
{
return $this->renderer->searchAndRenderBlock($view, 'widget', $variables);
}
/**
* Renders the entire form field "row".
*
* @param FormView $view The view for which to render the row
* @param array $variables Additional variables passed to the template
*
* @return string The HTML markup
*/
public function row(FormView $view, array $variables = array())
{
return $this->renderer->searchAndRenderBlock($view, 'row', $variables);
}
/**
* Renders the label of the given view.
*
* @param FormView $view The view for which to render the label
* @param string $label The label
* @param array $variables Additional variables passed to the template
*
* @return string The HTML markup
*/
public function label(FormView $view, $label = null, array $variables = array())
{
if (null !== $label) {
$variables += array('label' => $label);
}
return $this->renderer->searchAndRenderBlock($view, 'label', $variables);
}
/**
* Renders the errors of the given view.
*
* @param FormView $view The view to render the errors for
*
* @return string The HTML markup
*/
public function errors(FormView $view)
{
return $this->renderer->searchAndRenderBlock($view, 'errors');
}
/**
* Renders views which have not already been rendered.
*
* @param FormView $view The parent view
* @param array $variables An array of variables
*
* @return string The HTML markup
*/
public function rest(FormView $view, array $variables = array())
{
return $this->renderer->searchAndRenderBlock($view, 'rest', $variables);
}
/**
* Renders a block of the template.
*
* @param FormView $view The view for determining the used themes
* @param string $blockName The name of the block to render
* @param array $variables The variable to pass to the template
*
* @return string The HTML markup
*/
public function block(FormView $view, $blockName, array $variables = array())
{
return $this->renderer->renderBlock($view, $blockName, $variables);
}
/**
* Returns a CSRF token.
*
* Use this helper for CSRF protection without the overhead of creating a
* form.
*
* <code>
* echo $view['form']->csrfToken('rm_user_'.$user->getId());
* </code>
*
* Check the token in your action using the same CSRF token id.
*
* <code>
* $csrfProvider = $this->get('security.csrf.token_generator');
* if (!$csrfProvider->isCsrfTokenValid('rm_user_'.$user->getId(), $token)) {
* throw new \RuntimeException('CSRF attack detected.');
* }
* </code>
*
* @param string $tokenId The CSRF token id of the protected action
*
* @return string A CSRF token
*
* @throws \BadMethodCallException When no CSRF provider was injected in the constructor.
*/
public function csrfToken($tokenId)
{
return $this->renderer->renderCsrfToken($tokenId);
}
public function humanize($text)
{
return $this->renderer->humanize($text);
}
}

View File

@@ -0,0 +1,72 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Templating\Helper;
use Symfony\Component\Templating\Helper\Helper;
use Symfony\Component\HttpFoundation\RequestStack;
/**
* RequestHelper provides access to the current request parameters.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class RequestHelper extends Helper
{
protected $requestStack;
public function __construct(RequestStack $requestStack)
{
$this->requestStack = $requestStack;
}
/**
* Returns a parameter from the current request object.
*
* @param string $key The name of the parameter
* @param string $default A default value
*
* @return mixed
*
* @see Request::get()
*/
public function getParameter($key, $default = null)
{
return $this->getRequest()->get($key, $default);
}
/**
* Returns the locale.
*
* @return string
*/
public function getLocale()
{
return $this->getRequest()->getLocale();
}
private function getRequest()
{
if (!$this->requestStack->getCurrentRequest()) {
throw new \LogicException('A Request must be available.');
}
return $this->requestStack->getCurrentRequest();
}
/**
* {@inheritdoc}
*/
public function getName()
{
return 'request';
}
}

View File

@@ -0,0 +1,75 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Templating\Helper;
use Symfony\Component\Templating\Helper\Helper;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
/**
* RouterHelper manages links between pages in a template context.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class RouterHelper extends Helper
{
protected $generator;
/**
* Constructor.
*
* @param UrlGeneratorInterface $router A Router instance
*/
public function __construct(UrlGeneratorInterface $router)
{
$this->generator = $router;
}
/**
* Generates a URL reference (as an absolute or relative path) to the route with the given parameters.
*
* @param string $name The name of the route
* @param mixed $parameters An array of parameters
* @param bool $relative Whether to generate a relative or absolute path
*
* @return string The generated URL reference
*
* @see UrlGeneratorInterface
*/
public function path($name, $parameters = array(), $relative = false)
{
return $this->generator->generate($name, $parameters, $relative ? UrlGeneratorInterface::RELATIVE_PATH : UrlGeneratorInterface::ABSOLUTE_PATH);
}
/**
* Generates a URL reference (as an absolute URL or network path) to the route with the given parameters.
*
* @param string $name The name of the route
* @param mixed $parameters An array of parameters
* @param bool $schemeRelative Whether to omit the scheme in the generated URL reference
*
* @return string The generated URL reference
*
* @see UrlGeneratorInterface
*/
public function url($name, $parameters = array(), $schemeRelative = false)
{
return $this->generator->generate($name, $parameters, $schemeRelative ? UrlGeneratorInterface::NETWORK_PATH : UrlGeneratorInterface::ABSOLUTE_URL);
}
/**
* {@inheritdoc}
*/
public function getName()
{
return 'router';
}
}

View File

@@ -0,0 +1,80 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Templating\Helper;
use Symfony\Component\Templating\Helper\Helper;
use Symfony\Component\HttpFoundation\RequestStack;
/**
* SessionHelper provides read-only access to the session attributes.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class SessionHelper extends Helper
{
protected $session;
protected $requestStack;
public function __construct(RequestStack $requestStack)
{
$this->requestStack = $requestStack;
}
/**
* Returns an attribute.
*
* @param string $name The attribute name
* @param mixed $default The default value
*
* @return mixed
*/
public function get($name, $default = null)
{
return $this->getSession()->get($name, $default);
}
public function getFlash($name, array $default = array())
{
return $this->getSession()->getFlashBag()->get($name, $default);
}
public function getFlashes()
{
return $this->getSession()->getFlashBag()->all();
}
public function hasFlash($name)
{
return $this->getSession()->getFlashBag()->has($name);
}
private function getSession()
{
if (null === $this->session) {
if (!$this->requestStack->getMasterRequest()) {
throw new \LogicException('A Request must be available.');
}
$this->session = $this->requestStack->getMasterRequest()->getSession();
}
return $this->session;
}
/**
* {@inheritdoc}
*/
public function getName()
{
return 'session';
}
}

View File

@@ -0,0 +1,46 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Templating\Helper;
use Symfony\Component\Stopwatch\Stopwatch;
use Symfony\Component\Templating\Helper\Helper;
/**
* StopwatchHelper provides methods time your PHP templates.
*
* @author Wouter J <wouter@wouterj.nl>
*/
class StopwatchHelper extends Helper
{
private $stopwatch;
public function __construct(Stopwatch $stopwatch = null)
{
$this->stopwatch = $stopwatch;
}
public function getName()
{
return 'stopwatch';
}
public function __call($method, $arguments = array())
{
if (null !== $this->stopwatch) {
if (method_exists($this->stopwatch, $method)) {
return call_user_func_array(array($this->stopwatch, $method), $arguments);
}
throw new \BadMethodCallException(sprintf('Method "%s" of Stopwatch does not exist', $method));
}
}
}

View File

@@ -0,0 +1,59 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Templating\Helper;
use Symfony\Component\Templating\Helper\Helper;
use Symfony\Component\Translation\TranslatorInterface;
/**
* TranslatorHelper.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class TranslatorHelper extends Helper
{
protected $translator;
/**
* Constructor.
*
* @param TranslatorInterface $translator A TranslatorInterface instance
*/
public function __construct(TranslatorInterface $translator)
{
$this->translator = $translator;
}
/**
* @see TranslatorInterface::trans()
*/
public function trans($id, array $parameters = array(), $domain = 'messages', $locale = null)
{
return $this->translator->trans($id, $parameters, $domain, $locale);
}
/**
* @see TranslatorInterface::transChoice()
*/
public function transChoice($id, $number, array $parameters = array(), $domain = 'messages', $locale = null)
{
return $this->translator->transChoice($id, $number, $parameters, $domain, $locale);
}
/**
* {@inheritdoc}
*/
public function getName()
{
return 'translator';
}
}

View File

@@ -0,0 +1,67 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Templating\Loader;
use Symfony\Component\Templating\Storage\FileStorage;
use Symfony\Component\Templating\Loader\LoaderInterface;
use Symfony\Component\Config\FileLocatorInterface;
use Symfony\Component\Templating\TemplateReferenceInterface;
/**
* FilesystemLoader is a loader that read templates from the filesystem.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class FilesystemLoader implements LoaderInterface
{
protected $locator;
/**
* Constructor.
*
* @param FileLocatorInterface $locator A FileLocatorInterface instance
*/
public function __construct(FileLocatorInterface $locator)
{
$this->locator = $locator;
}
/**
* {@inheritdoc}
*/
public function load(TemplateReferenceInterface $template)
{
try {
$file = $this->locator->locate($template);
} catch (\InvalidArgumentException $e) {
return false;
}
return new FileStorage($file);
}
/**
* {@inheritdoc}
*/
public function isFresh(TemplateReferenceInterface $template, $time)
{
if (false === $storage = $this->load($template)) {
return false;
}
if (!is_readable((string) $storage)) {
return false;
}
return filemtime((string) $storage) < $time;
}
}

View File

@@ -0,0 +1,84 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Templating\Loader;
use Symfony\Component\Config\FileLocatorInterface;
use Symfony\Component\Templating\TemplateReferenceInterface;
/**
* TemplateLocator locates templates in bundles.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class TemplateLocator implements FileLocatorInterface
{
protected $locator;
protected $cache;
/**
* Constructor.
*
* @param FileLocatorInterface $locator A FileLocatorInterface instance
* @param string $cacheDir The cache path
*/
public function __construct(FileLocatorInterface $locator, $cacheDir = null)
{
if (null !== $cacheDir && is_file($cache = $cacheDir.'/templates.php')) {
$this->cache = require $cache;
}
$this->locator = $locator;
}
/**
* Returns a full path for a given file.
*
* @param TemplateReferenceInterface $template A template
*
* @return string The full path for the file
*/
protected function getCacheKey($template)
{
return $template->getLogicalName();
}
/**
* Returns a full path for a given file.
*
* @param TemplateReferenceInterface $template A template
* @param string $currentPath Unused
* @param bool $first Unused
*
* @return string The full path for the file
*
* @throws \InvalidArgumentException When the template is not an instance of TemplateReferenceInterface
* @throws \InvalidArgumentException When the template file can not be found
*/
public function locate($template, $currentPath = null, $first = true)
{
if (!$template instanceof TemplateReferenceInterface) {
throw new \InvalidArgumentException('The template must be an instance of TemplateReferenceInterface.');
}
$key = $this->getCacheKey($template);
if (isset($this->cache[$key])) {
return $this->cache[$key];
}
try {
return $this->cache[$key] = $this->locator->locate($template->getPath(), $currentPath);
} catch (\InvalidArgumentException $e) {
throw new \InvalidArgumentException(sprintf('Unable to find template "%s" : "%s".', $template, $e->getMessage()), 0, $e);
}
}
}

View File

@@ -0,0 +1,86 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Templating;
use Symfony\Component\Templating\PhpEngine as BasePhpEngine;
use Symfony\Component\Templating\Loader\LoaderInterface;
use Symfony\Component\Templating\TemplateNameParserInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Response;
/**
* This engine knows how to render Symfony templates.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class PhpEngine extends BasePhpEngine implements EngineInterface
{
protected $container;
/**
* Constructor.
*
* @param TemplateNameParserInterface $parser A TemplateNameParserInterface instance
* @param ContainerInterface $container The DI container
* @param LoaderInterface $loader A loader instance
* @param GlobalVariables|null $globals A GlobalVariables instance or null
*/
public function __construct(TemplateNameParserInterface $parser, ContainerInterface $container, LoaderInterface $loader, GlobalVariables $globals = null)
{
$this->container = $container;
parent::__construct($parser, $loader);
if (null !== $globals) {
$this->addGlobal('app', $globals);
}
}
/**
* {@inheritdoc}
*/
public function get($name)
{
if (!isset($this->helpers[$name])) {
throw new \InvalidArgumentException(sprintf('The helper "%s" is not defined.', $name));
}
if (is_string($this->helpers[$name])) {
$this->helpers[$name] = $this->container->get($this->helpers[$name]);
$this->helpers[$name]->setCharset($this->charset);
}
return $this->helpers[$name];
}
/**
* {@inheritdoc}
*/
public function setHelpers(array $helpers)
{
$this->helpers = $helpers;
}
/**
* {@inheritdoc}
*/
public function renderResponse($view, array $parameters = array(), Response $response = null)
{
if (null === $response) {
$response = new Response();
}
$response->setContent($this->render($view, $parameters));
return $response;
}
}

View File

@@ -0,0 +1,45 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Templating;
use Symfony\Component\Templating\TemplateNameParserInterface;
use Symfony\Component\Templating\TemplateReferenceInterface;
/**
* TemplateFilenameParser converts template filenames to
* TemplateReferenceInterface instances.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class TemplateFilenameParser implements TemplateNameParserInterface
{
/**
* {@inheritdoc}
*/
public function parse($name)
{
if ($name instanceof TemplateReferenceInterface) {
return $name;
}
$parts = explode('/', str_replace('\\', '/', $name));
$elements = explode('.', array_pop($parts));
if (3 > count($elements)) {
return false;
}
$engine = array_pop($elements);
$format = array_pop($elements);
return new TemplateReference('', implode('/', $parts), implode('.', $elements), $format, $engine);
}
}

View File

@@ -0,0 +1,79 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Templating;
use Symfony\Component\Templating\TemplateReferenceInterface;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Templating\TemplateNameParser as BaseTemplateNameParser;
/**
* TemplateNameParser converts template names from the short notation
* "bundle:section:template.format.engine" to TemplateReferenceInterface
* instances.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class TemplateNameParser extends BaseTemplateNameParser
{
protected $kernel;
protected $cache = array();
/**
* Constructor.
*
* @param KernelInterface $kernel A KernelInterface instance
*/
public function __construct(KernelInterface $kernel)
{
$this->kernel = $kernel;
}
/**
* {@inheritdoc}
*/
public function parse($name)
{
if ($name instanceof TemplateReferenceInterface) {
return $name;
} elseif (isset($this->cache[$name])) {
return $this->cache[$name];
}
// normalize name
$name = str_replace(':/', ':', preg_replace('#/{2,}#', '/', str_replace('\\', '/', $name)));
if (false !== strpos($name, '..')) {
throw new \RuntimeException(sprintf('Template name "%s" contains invalid characters.', $name));
}
if (!preg_match('/^(?:([^:]*):([^:]*):)?(.+)\.([^\.]+)\.([^\.]+)$/', $name, $matches) || $this->isAbsolutePath($name) || 0 === strpos($name, '@')) {
return parent::parse($name);
}
$template = new TemplateReference($matches[1], $matches[2], $matches[3], $matches[4], $matches[5]);
if ($template->get('bundle')) {
try {
$this->kernel->getBundle($template->get('bundle'));
} catch (\Exception $e) {
throw new \InvalidArgumentException(sprintf('Template name "%s" is not valid.', $name), 0, $e);
}
}
return $this->cache[$name] = $template;
}
private function isAbsolutePath($file)
{
return (bool) preg_match('#^(?:/|[a-zA-Z]:)#', $file);
}
}

View File

@@ -0,0 +1,57 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Templating;
use Symfony\Component\Templating\TemplateReference as BaseTemplateReference;
/**
* Internal representation of a template.
*
* @author Victor Berchet <victor@suumit.com>
*/
class TemplateReference extends BaseTemplateReference
{
public function __construct($bundle = null, $controller = null, $name = null, $format = null, $engine = null)
{
$this->parameters = array(
'bundle' => $bundle,
'controller' => $controller,
'name' => $name,
'format' => $format,
'engine' => $engine,
);
}
/**
* Returns the path to the template
* - as a path when the template is not part of a bundle
* - as a resource when the template is part of a bundle.
*
* @return string A path to the template or a resource
*/
public function getPath()
{
$controller = str_replace('\\', '/', $this->get('controller'));
$path = (empty($controller) ? '' : $controller.'/').$this->get('name').'.'.$this->get('format').'.'.$this->get('engine');
return empty($this->parameters['bundle']) ? 'views/'.$path : '@'.$this->get('bundle').'/Resources/views/'.$path;
}
/**
* {@inheritdoc}
*/
public function getLogicalName()
{
return sprintf('%s:%s:%s.%s.%s', $this->parameters['bundle'], $this->parameters['controller'], $this->parameters['name'], $this->parameters['format'], $this->parameters['engine']);
}
}

View File

@@ -0,0 +1,57 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Templating;
use Symfony\Component\Templating\TemplateNameParserInterface;
use Symfony\Component\Stopwatch\Stopwatch;
use Symfony\Component\Templating\Loader\LoaderInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Times the time spent to render a template.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class TimedPhpEngine extends PhpEngine
{
protected $stopwatch;
/**
* Constructor.
*
* @param TemplateNameParserInterface $parser A TemplateNameParserInterface instance
* @param ContainerInterface $container A ContainerInterface instance
* @param LoaderInterface $loader A LoaderInterface instance
* @param Stopwatch $stopwatch A Stopwatch instance
* @param GlobalVariables $globals A GlobalVariables instance
*/
public function __construct(TemplateNameParserInterface $parser, ContainerInterface $container, LoaderInterface $loader, Stopwatch $stopwatch, GlobalVariables $globals = null)
{
parent::__construct($parser, $container, $loader, $globals);
$this->stopwatch = $stopwatch;
}
/**
* {@inheritdoc}
*/
public function render($name, array $parameters = array())
{
$e = $this->stopwatch->start(sprintf('template.php (%s)', $name), 'template');
$ret = parent::render($name, $parameters);
$e->stop();
return $ret;
}
}