diff options
Diffstat (limited to 'vendor/symfony/twig-bridge/Symfony/Bridge/Twig/Extension')
7 files changed, 804 insertions, 0 deletions
diff --git a/vendor/symfony/twig-bridge/Symfony/Bridge/Twig/Extension/CodeExtension.php b/vendor/symfony/twig-bridge/Symfony/Bridge/Twig/Extension/CodeExtension.php new file mode 100644 index 00000000..a6202b24 --- /dev/null +++ b/vendor/symfony/twig-bridge/Symfony/Bridge/Twig/Extension/CodeExtension.php | |||
@@ -0,0 +1,232 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of the Symfony package. | ||
5 | * | ||
6 | * (c) Fabien Potencier <fabien@symfony.com> | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | namespace Symfony\Bridge\Twig\Extension; | ||
13 | |||
14 | if (!defined('ENT_SUBSTITUTE')) { | ||
15 | define('ENT_SUBSTITUTE', 8); | ||
16 | } | ||
17 | |||
18 | /** | ||
19 | * Twig extension relate to PHP code and used by the profiler and the default exception templates. | ||
20 | * | ||
21 | * @author Fabien Potencier <fabien@symfony.com> | ||
22 | */ | ||
23 | class CodeExtension extends \Twig_Extension | ||
24 | { | ||
25 | private $fileLinkFormat; | ||
26 | private $rootDir; | ||
27 | private $charset; | ||
28 | |||
29 | /** | ||
30 | * Constructor. | ||
31 | * | ||
32 | * @param string $fileLinkFormat The format for links to source files | ||
33 | * @param string $rootDir The project root directory | ||
34 | * @param string $charset The charset | ||
35 | */ | ||
36 | public function __construct($fileLinkFormat, $rootDir, $charset) | ||
37 | { | ||
38 | $this->fileLinkFormat = empty($fileLinkFormat) ? ini_get('xdebug.file_link_format') : $fileLinkFormat; | ||
39 | $this->rootDir = str_replace('\\', '/', $rootDir).'/'; | ||
40 | $this->charset = $charset; | ||
41 | } | ||
42 | |||
43 | /** | ||
44 | * {@inheritdoc} | ||
45 | */ | ||
46 | public function getFilters() | ||
47 | { | ||
48 | return array( | ||
49 | 'abbr_class' => new \Twig_Filter_Method($this, 'abbrClass', array('is_safe' => array('html'))), | ||
50 | 'abbr_method' => new \Twig_Filter_Method($this, 'abbrMethod', array('is_safe' => array('html'))), | ||
51 | 'format_args' => new \Twig_Filter_Method($this, 'formatArgs', array('is_safe' => array('html'))), | ||
52 | 'format_args_as_text' => new \Twig_Filter_Method($this, 'formatArgsAsText'), | ||
53 | 'file_excerpt' => new \Twig_Filter_Method($this, 'fileExcerpt', array('is_safe' => array('html'))), | ||
54 | 'format_file' => new \Twig_Filter_Method($this, 'formatFile', array('is_safe' => array('html'))), | ||
55 | 'format_file_from_text' => new \Twig_Filter_Method($this, 'formatFileFromText', array('is_safe' => array('html'))), | ||
56 | 'file_link' => new \Twig_Filter_Method($this, 'getFileLink', array('is_safe' => array('html'))), | ||
57 | ); | ||
58 | } | ||
59 | |||
60 | public function abbrClass($class) | ||
61 | { | ||
62 | $parts = explode('\\', $class); | ||
63 | $short = array_pop($parts); | ||
64 | |||
65 | return sprintf("<abbr title=\"%s\">%s</abbr>", $class, $short); | ||
66 | } | ||
67 | |||
68 | public function abbrMethod($method) | ||
69 | { | ||
70 | if (false !== strpos($method, '::')) { | ||
71 | list($class, $method) = explode('::', $method, 2); | ||
72 | $result = sprintf("%s::%s()", $this->abbrClass($class), $method); | ||
73 | } elseif ('Closure' === $method) { | ||
74 | $result = sprintf("<abbr title=\"%s\">%s</abbr>", $method, $method); | ||
75 | } else { | ||
76 | $result = sprintf("<abbr title=\"%s\">%s</abbr>()", $method, $method); | ||
77 | } | ||
78 | |||
79 | return $result; | ||
80 | } | ||
81 | |||
82 | /** | ||
83 | * Formats an array as a string. | ||
84 | * | ||
85 | * @param array $args The argument array | ||
86 | * | ||
87 | * @return string | ||
88 | */ | ||
89 | public function formatArgs($args) | ||
90 | { | ||
91 | $result = array(); | ||
92 | foreach ($args as $key => $item) { | ||
93 | if ('object' === $item[0]) { | ||
94 | $parts = explode('\\', $item[1]); | ||
95 | $short = array_pop($parts); | ||
96 | $formattedValue = sprintf("<em>object</em>(<abbr title=\"%s\">%s</abbr>)", $item[1], $short); | ||
97 | } elseif ('array' === $item[0]) { | ||
98 | $formattedValue = sprintf("<em>array</em>(%s)", is_array($item[1]) ? $this->formatArgs($item[1]) : $item[1]); | ||
99 | } elseif ('string' === $item[0]) { | ||
100 | $formattedValue = sprintf("'%s'", htmlspecialchars($item[1], ENT_QUOTES, $this->charset)); | ||
101 | } elseif ('null' === $item[0]) { | ||
102 | $formattedValue = '<em>null</em>'; | ||
103 | } elseif ('boolean' === $item[0]) { | ||
104 | $formattedValue = '<em>'.strtolower(var_export($item[1], true)).'</em>'; | ||
105 | } elseif ('resource' === $item[0]) { | ||
106 | $formattedValue = '<em>resource</em>'; | ||
107 | } else { | ||
108 | $formattedValue = str_replace("\n", '', var_export(htmlspecialchars((string) $item[1], ENT_QUOTES, $this->charset), true)); | ||
109 | } | ||
110 | |||
111 | $result[] = is_int($key) ? $formattedValue : sprintf("'%s' => %s", $key, $formattedValue); | ||
112 | } | ||
113 | |||
114 | return implode(', ', $result); | ||
115 | } | ||
116 | |||
117 | /** | ||
118 | * Formats an array as a string. | ||
119 | * | ||
120 | * @param array $args The argument array | ||
121 | * | ||
122 | * @return string | ||
123 | */ | ||
124 | public function formatArgsAsText($args) | ||
125 | { | ||
126 | return strip_tags($this->formatArgs($args)); | ||
127 | } | ||
128 | |||
129 | /** | ||
130 | * Returns an excerpt of a code file around the given line number. | ||
131 | * | ||
132 | * @param string $file A file path | ||
133 | * @param int $line The selected line number | ||
134 | * | ||
135 | * @return string An HTML string | ||
136 | */ | ||
137 | public function fileExcerpt($file, $line) | ||
138 | { | ||
139 | if (is_readable($file)) { | ||
140 | $code = highlight_file($file, true); | ||
141 | // remove main code/span tags | ||
142 | $code = preg_replace('#^<code.*?>\s*<span.*?>(.*)</span>\s*</code>#s', '\\1', $code); | ||
143 | $content = preg_split('#<br />#', $code); | ||
144 | |||
145 | $lines = array(); | ||
146 | for ($i = max($line - 3, 1), $max = min($line + 3, count($content)); $i <= $max; $i++) { | ||
147 | $lines[] = '<li'.($i == $line ? ' class="selected"' : '').'><code>'.self::fixCodeMarkup($content[$i - 1]).'</code></li>'; | ||
148 | } | ||
149 | |||
150 | return '<ol start="'.max($line - 3, 1).'">'.implode("\n", $lines).'</ol>'; | ||
151 | } | ||
152 | } | ||
153 | |||
154 | /** | ||
155 | * Formats a file path. | ||
156 | * | ||
157 | * @param string $file An absolute file path | ||
158 | * @param integer $line The line number | ||
159 | * @param string $text Use this text for the link rather than the file path | ||
160 | * | ||
161 | * @return string | ||
162 | */ | ||
163 | public function formatFile($file, $line, $text = null) | ||
164 | { | ||
165 | if (null === $text) { | ||
166 | $file = trim($file); | ||
167 | $text = $file; | ||
168 | if (0 === strpos($text, $this->rootDir)) { | ||
169 | $text = str_replace($this->rootDir, '', str_replace('\\', '/', $text)); | ||
170 | $text = sprintf('<abbr title="%s">kernel.root_dir</abbr>/%s', $this->rootDir, $text); | ||
171 | } | ||
172 | } | ||
173 | |||
174 | $text = "$text at line $line"; | ||
175 | |||
176 | if (false !== $link = $this->getFileLink($file, $line)) { | ||
177 | return sprintf('<a href="%s" title="Click to open this file" class="file_link">%s</a>', htmlspecialchars($link, ENT_QUOTES | ENT_SUBSTITUTE, $this->charset), $text); | ||
178 | } | ||
179 | |||
180 | return $text; | ||
181 | } | ||
182 | |||
183 | /** | ||
184 | * Returns the link for a given file/line pair. | ||
185 | * | ||
186 | * @param string $file An absolute file path | ||
187 | * @param integer $line The line number | ||
188 | * | ||
189 | * @return string A link of false | ||
190 | */ | ||
191 | public function getFileLink($file, $line) | ||
192 | { | ||
193 | if ($this->fileLinkFormat && is_file($file)) { | ||
194 | return strtr($this->fileLinkFormat, array('%f' => $file, '%l' => $line)); | ||
195 | } | ||
196 | |||
197 | return false; | ||
198 | } | ||
199 | |||
200 | public function formatFileFromText($text) | ||
201 | { | ||
202 | $that = $this; | ||
203 | |||
204 | return preg_replace_callback('/in ("|")?(.+?)\1(?: +(?:on|at))? +line (\d+)/s', function ($match) use ($that) { | ||
205 | return 'in '.$that->formatFile($match[2], $match[3]); | ||
206 | }, $text); | ||
207 | } | ||
208 | |||
209 | public function getName() | ||
210 | { | ||
211 | return 'code'; | ||
212 | } | ||
213 | |||
214 | protected static function fixCodeMarkup($line) | ||
215 | { | ||
216 | // </span> ending tag from previous line | ||
217 | $opening = strpos($line, '<span'); | ||
218 | $closing = strpos($line, '</span>'); | ||
219 | if (false !== $closing && (false === $opening || $closing < $opening)) { | ||
220 | $line = substr_replace($line, '', $closing, 7); | ||
221 | } | ||
222 | |||
223 | // missing </span> tag at the end of line | ||
224 | $opening = strpos($line, '<span'); | ||
225 | $closing = strpos($line, '</span>'); | ||
226 | if (false !== $opening && (false === $closing || $closing > $opening)) { | ||
227 | $line .= '</span>'; | ||
228 | } | ||
229 | |||
230 | return $line; | ||
231 | } | ||
232 | } | ||
diff --git a/vendor/symfony/twig-bridge/Symfony/Bridge/Twig/Extension/FormExtension.php b/vendor/symfony/twig-bridge/Symfony/Bridge/Twig/Extension/FormExtension.php new file mode 100644 index 00000000..fbfa5243 --- /dev/null +++ b/vendor/symfony/twig-bridge/Symfony/Bridge/Twig/Extension/FormExtension.php | |||
@@ -0,0 +1,136 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of the Symfony package. | ||
5 | * | ||
6 | * (c) Fabien Potencier <fabien@symfony.com> | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | namespace Symfony\Bridge\Twig\Extension; | ||
13 | |||
14 | use Symfony\Bridge\Twig\TokenParser\FormThemeTokenParser; | ||
15 | use Symfony\Bridge\Twig\Form\TwigRendererInterface; | ||
16 | use Symfony\Component\Form\Extension\Core\View\ChoiceView; | ||
17 | |||
18 | /** | ||
19 | * FormExtension extends Twig with form capabilities. | ||
20 | * | ||
21 | * @author Fabien Potencier <fabien@symfony.com> | ||
22 | * @author Bernhard Schussek <bschussek@gmail.com> | ||
23 | */ | ||
24 | class FormExtension extends \Twig_Extension | ||
25 | { | ||
26 | /** | ||
27 | * This property is public so that it can be accessed directly from compiled | ||
28 | * templates without having to call a getter, which slightly decreases performance. | ||
29 | * | ||
30 | * @var TwigRendererInterface | ||
31 | */ | ||
32 | public $renderer; | ||
33 | |||
34 | public function __construct(TwigRendererInterface $renderer) | ||
35 | { | ||
36 | $this->renderer = $renderer; | ||
37 | } | ||
38 | |||
39 | /** | ||
40 | * {@inheritdoc} | ||
41 | */ | ||
42 | public function initRuntime(\Twig_Environment $environment) | ||
43 | { | ||
44 | $this->renderer->setEnvironment($environment); | ||
45 | } | ||
46 | |||
47 | /** | ||
48 | * {@inheritdoc} | ||
49 | */ | ||
50 | public function getTokenParsers() | ||
51 | { | ||
52 | return array( | ||
53 | // {% form_theme form "SomeBundle::widgets.twig" %} | ||
54 | new FormThemeTokenParser(), | ||
55 | ); | ||
56 | } | ||
57 | |||
58 | /** | ||
59 | * {@inheritdoc} | ||
60 | */ | ||
61 | public function getFunctions() | ||
62 | { | ||
63 | return array( | ||
64 | 'form_enctype' => new \Twig_Function_Node('Symfony\Bridge\Twig\Node\FormEnctypeNode', array('is_safe' => array('html'))), | ||
65 | 'form_widget' => new \Twig_Function_Node('Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode', array('is_safe' => array('html'))), | ||
66 | 'form_errors' => new \Twig_Function_Node('Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode', array('is_safe' => array('html'))), | ||
67 | 'form_label' => new \Twig_Function_Node('Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode', array('is_safe' => array('html'))), | ||
68 | 'form_row' => new \Twig_Function_Node('Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode', array('is_safe' => array('html'))), | ||
69 | 'form_rest' => new \Twig_Function_Node('Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode', array('is_safe' => array('html'))), | ||
70 | 'form' => new \Twig_Function_Node('Symfony\Bridge\Twig\Node\RenderBlockNode', array('is_safe' => array('html'))), | ||
71 | 'form_start' => new \Twig_Function_Node('Symfony\Bridge\Twig\Node\RenderBlockNode', array('is_safe' => array('html'))), | ||
72 | 'form_end' => new \Twig_Function_Node('Symfony\Bridge\Twig\Node\RenderBlockNode', array('is_safe' => array('html'))), | ||
73 | 'csrf_token' => new \Twig_Function_Method($this, 'renderer->renderCsrfToken'), | ||
74 | ); | ||
75 | } | ||
76 | |||
77 | /** | ||
78 | * {@inheritdoc} | ||
79 | */ | ||
80 | public function getFilters() | ||
81 | { | ||
82 | return array( | ||
83 | 'humanize' => new \Twig_Filter_Method($this, 'renderer->humanize'), | ||
84 | ); | ||
85 | } | ||
86 | |||
87 | /** | ||
88 | * {@inheritdoc} | ||
89 | */ | ||
90 | public function getTests() | ||
91 | { | ||
92 | return array( | ||
93 | 'selectedchoice' => new \Twig_Test_Method($this, 'isSelectedChoice'), | ||
94 | ); | ||
95 | } | ||
96 | |||
97 | /** | ||
98 | * Returns whether a choice is selected for a given form value. | ||
99 | * | ||
100 | * Unfortunately Twig does not support an efficient way to execute the | ||
101 | * "is_selected" closure passed to the template by ChoiceType. It is faster | ||
102 | * to implement the logic here (around 65ms for a specific form). | ||
103 | * | ||
104 | * Directly implementing the logic here is also faster than doing so in | ||
105 | * ChoiceView (around 30ms). | ||
106 | * | ||
107 | * The worst option tested so far is to implement the logic in ChoiceView | ||
108 | * and access the ChoiceView method directly in the template. Doing so is | ||
109 | * around 220ms slower than doing the method call here in the filter. Twig | ||
110 | * seems to be much more efficient at executing filters than at executing | ||
111 | * methods of an object. | ||
112 | * | ||
113 | * @param ChoiceView $choice The choice to check. | ||
114 | * @param string|array $selectedValue The selected value to compare. | ||
115 | * | ||
116 | * @return Boolean Whether the choice is selected. | ||
117 | * | ||
118 | * @see ChoiceView::isSelected() | ||
119 | */ | ||
120 | public function isSelectedChoice(ChoiceView $choice, $selectedValue) | ||
121 | { | ||
122 | if (is_array($selectedValue)) { | ||
123 | return false !== array_search($choice->value, $selectedValue, true); | ||
124 | } | ||
125 | |||
126 | return $choice->value === $selectedValue; | ||
127 | } | ||
128 | |||
129 | /** | ||
130 | * {@inheritdoc} | ||
131 | */ | ||
132 | public function getName() | ||
133 | { | ||
134 | return 'form'; | ||
135 | } | ||
136 | } | ||
diff --git a/vendor/symfony/twig-bridge/Symfony/Bridge/Twig/Extension/HttpKernelExtension.php b/vendor/symfony/twig-bridge/Symfony/Bridge/Twig/Extension/HttpKernelExtension.php new file mode 100644 index 00000000..a8377234 --- /dev/null +++ b/vendor/symfony/twig-bridge/Symfony/Bridge/Twig/Extension/HttpKernelExtension.php | |||
@@ -0,0 +1,88 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of the Symfony package. | ||
5 | * | ||
6 | * (c) Fabien Potencier <fabien@symfony.com> | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | namespace Symfony\Bridge\Twig\Extension; | ||
13 | |||
14 | use Symfony\Component\HttpKernel\Fragment\FragmentHandler; | ||
15 | use Symfony\Component\HttpKernel\Controller\ControllerReference; | ||
16 | |||
17 | /** | ||
18 | * Provides integration with the HttpKernel component. | ||
19 | * | ||
20 | * @author Fabien Potencier <fabien@symfony.com> | ||
21 | */ | ||
22 | class HttpKernelExtension extends \Twig_Extension | ||
23 | { | ||
24 | private $handler; | ||
25 | |||
26 | /** | ||
27 | * Constructor. | ||
28 | * | ||
29 | * @param FragmentHandler $handler A FragmentHandler instance | ||
30 | */ | ||
31 | public function __construct(FragmentHandler $handler) | ||
32 | { | ||
33 | $this->handler = $handler; | ||
34 | } | ||
35 | |||
36 | public function getFunctions() | ||
37 | { | ||
38 | return array( | ||
39 | 'render' => new \Twig_Function_Method($this, 'renderFragment', array('is_safe' => array('html'))), | ||
40 | 'render_*' => new \Twig_Function_Method($this, 'renderFragmentStrategy', array('is_safe' => array('html'))), | ||
41 | 'controller' => new \Twig_Function_Method($this, 'controller'), | ||
42 | ); | ||
43 | } | ||
44 | |||
45 | /** | ||
46 | * Renders a fragment. | ||
47 | * | ||
48 | * @param string|ControllerReference $uri A URI as a string or a ControllerReference instance | ||
49 | * @param array $options An array of options | ||
50 | * | ||
51 | * @return string The fragment content | ||
52 | * | ||
53 | * @see Symfony\Component\HttpKernel\Fragment\FragmentHandler::render() | ||
54 | */ | ||
55 | public function renderFragment($uri, $options = array()) | ||
56 | { | ||
57 | $strategy = isset($options['strategy']) ? $options['strategy'] : 'inline'; | ||
58 | unset($options['strategy']); | ||
59 | |||
60 | return $this->handler->render($uri, $strategy, $options); | ||
61 | } | ||
62 | |||
63 | /** | ||
64 | * Renders a fragment. | ||
65 | * | ||
66 | * @param string $strategy A strategy name | ||
67 | * @param string|ControllerReference $uri A URI as a string or a ControllerReference instance | ||
68 | * @param array $options An array of options | ||
69 | * | ||
70 | * @return string The fragment content | ||
71 | * | ||
72 | * @see Symfony\Component\HttpKernel\Fragment\FragmentHandler::render() | ||
73 | */ | ||
74 | public function renderFragmentStrategy($strategy, $uri, $options = array()) | ||
75 | { | ||
76 | return $this->handler->render($uri, $strategy, $options); | ||
77 | } | ||
78 | |||
79 | public function controller($controller, $attributes = array(), $query = array()) | ||
80 | { | ||
81 | return new ControllerReference($controller, $attributes, $query); | ||
82 | } | ||
83 | |||
84 | public function getName() | ||
85 | { | ||
86 | return 'http_kernel'; | ||
87 | } | ||
88 | } | ||
diff --git a/vendor/symfony/twig-bridge/Symfony/Bridge/Twig/Extension/RoutingExtension.php b/vendor/symfony/twig-bridge/Symfony/Bridge/Twig/Extension/RoutingExtension.php new file mode 100644 index 00000000..8274abf3 --- /dev/null +++ b/vendor/symfony/twig-bridge/Symfony/Bridge/Twig/Extension/RoutingExtension.php | |||
@@ -0,0 +1,100 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of the Symfony package. | ||
5 | * | ||
6 | * (c) Fabien Potencier <fabien@symfony.com> | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | namespace Symfony\Bridge\Twig\Extension; | ||
13 | |||
14 | use Symfony\Component\Routing\Generator\UrlGeneratorInterface; | ||
15 | |||
16 | /** | ||
17 | * Provides integration of the Routing component with Twig. | ||
18 | * | ||
19 | * @author Fabien Potencier <fabien@symfony.com> | ||
20 | */ | ||
21 | class RoutingExtension extends \Twig_Extension | ||
22 | { | ||
23 | private $generator; | ||
24 | |||
25 | public function __construct(UrlGeneratorInterface $generator) | ||
26 | { | ||
27 | $this->generator = $generator; | ||
28 | } | ||
29 | |||
30 | /** | ||
31 | * Returns a list of functions to add to the existing list. | ||
32 | * | ||
33 | * @return array An array of functions | ||
34 | */ | ||
35 | public function getFunctions() | ||
36 | { | ||
37 | return array( | ||
38 | 'url' => new \Twig_Function_Method($this, 'getUrl', array('is_safe_callback' => array($this, 'isUrlGenerationSafe'))), | ||
39 | 'path' => new \Twig_Function_Method($this, 'getPath', array('is_safe_callback' => array($this, 'isUrlGenerationSafe'))), | ||
40 | ); | ||
41 | } | ||
42 | |||
43 | public function getPath($name, $parameters = array(), $relative = false) | ||
44 | { | ||
45 | return $this->generator->generate($name, $parameters, $relative ? UrlGeneratorInterface::RELATIVE_PATH : UrlGeneratorInterface::ABSOLUTE_PATH); | ||
46 | } | ||
47 | |||
48 | public function getUrl($name, $parameters = array(), $schemeRelative = false) | ||
49 | { | ||
50 | return $this->generator->generate($name, $parameters, $schemeRelative ? UrlGeneratorInterface::NETWORK_PATH : UrlGeneratorInterface::ABSOLUTE_URL); | ||
51 | } | ||
52 | |||
53 | /** | ||
54 | * Determines at compile time whether the generated URL will be safe and thus | ||
55 | * saving the unneeded automatic escaping for performance reasons. | ||
56 | * | ||
57 | * The URL generation process percent encodes non-alphanumeric characters. So there is no risk | ||
58 | * that malicious/invalid characters are part of the URL. The only character within an URL that | ||
59 | * must be escaped in html is the ampersand ("&") which separates query params. So we cannot mark | ||
60 | * the URL generation as always safe, but only when we are sure there won't be multiple query | ||
61 | * params. This is the case when there are none or only one constant parameter given. | ||
62 | * E.g. we know beforehand this will be safe: | ||
63 | * - path('route') | ||
64 | * - path('route', {'param': 'value'}) | ||
65 | * But the following may not: | ||
66 | * - path('route', var) | ||
67 | * - path('route', {'param': ['val1', 'val2'] }) // a sub-array | ||
68 | * - path('route', {'param1': 'value1', 'param2': 'value2'}) | ||
69 | * If param1 and param2 reference placeholder in the route, it would still be safe. But we don't know. | ||
70 | * | ||
71 | * @param \Twig_Node $argsNode The arguments of the path/url function | ||
72 | * | ||
73 | * @return array An array with the contexts the URL is safe | ||
74 | */ | ||
75 | public function isUrlGenerationSafe(\Twig_Node $argsNode) | ||
76 | { | ||
77 | // support named arguments | ||
78 | $paramsNode = $argsNode->hasNode('parameters') ? $argsNode->getNode('parameters') : ( | ||
79 | $argsNode->hasNode(1) ? $argsNode->getNode(1) : null | ||
80 | ); | ||
81 | |||
82 | if (null === $paramsNode || $paramsNode instanceof \Twig_Node_Expression_Array && count($paramsNode) <= 2 && | ||
83 | (!$paramsNode->hasNode(1) || $paramsNode->getNode(1) instanceof \Twig_Node_Expression_Constant) | ||
84 | ) { | ||
85 | return array('html'); | ||
86 | } | ||
87 | |||
88 | return array(); | ||
89 | } | ||
90 | |||
91 | /** | ||
92 | * Returns the name of the extension. | ||
93 | * | ||
94 | * @return string The extension name | ||
95 | */ | ||
96 | public function getName() | ||
97 | { | ||
98 | return 'routing'; | ||
99 | } | ||
100 | } | ||
diff --git a/vendor/symfony/twig-bridge/Symfony/Bridge/Twig/Extension/SecurityExtension.php b/vendor/symfony/twig-bridge/Symfony/Bridge/Twig/Extension/SecurityExtension.php new file mode 100644 index 00000000..c9f4466c --- /dev/null +++ b/vendor/symfony/twig-bridge/Symfony/Bridge/Twig/Extension/SecurityExtension.php | |||
@@ -0,0 +1,63 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of the Symfony package. | ||
5 | * | ||
6 | * (c) Fabien Potencier <fabien@symfony.com> | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | namespace Symfony\Bridge\Twig\Extension; | ||
13 | |||
14 | use Symfony\Component\Security\Acl\Voter\FieldVote; | ||
15 | use Symfony\Component\Security\Core\SecurityContextInterface; | ||
16 | |||
17 | /** | ||
18 | * SecurityExtension exposes security context features. | ||
19 | * | ||
20 | * @author Fabien Potencier <fabien@symfony.com> | ||
21 | */ | ||
22 | class SecurityExtension extends \Twig_Extension | ||
23 | { | ||
24 | private $context; | ||
25 | |||
26 | public function __construct(SecurityContextInterface $context = null) | ||
27 | { | ||
28 | $this->context = $context; | ||
29 | } | ||
30 | |||
31 | public function isGranted($role, $object = null, $field = null) | ||
32 | { | ||
33 | if (null === $this->context) { | ||
34 | return false; | ||
35 | } | ||
36 | |||
37 | if (null !== $field) { | ||
38 | $object = new FieldVote($object, $field); | ||
39 | } | ||
40 | |||
41 | return $this->context->isGranted($role, $object); | ||
42 | } | ||
43 | |||
44 | /** | ||
45 | * {@inheritdoc} | ||
46 | */ | ||
47 | public function getFunctions() | ||
48 | { | ||
49 | return array( | ||
50 | 'is_granted' => new \Twig_Function_Method($this, 'isGranted'), | ||
51 | ); | ||
52 | } | ||
53 | |||
54 | /** | ||
55 | * Returns the name of the extension. | ||
56 | * | ||
57 | * @return string The extension name | ||
58 | */ | ||
59 | public function getName() | ||
60 | { | ||
61 | return 'security'; | ||
62 | } | ||
63 | } | ||
diff --git a/vendor/symfony/twig-bridge/Symfony/Bridge/Twig/Extension/TranslationExtension.php b/vendor/symfony/twig-bridge/Symfony/Bridge/Twig/Extension/TranslationExtension.php new file mode 100644 index 00000000..2ab3832d --- /dev/null +++ b/vendor/symfony/twig-bridge/Symfony/Bridge/Twig/Extension/TranslationExtension.php | |||
@@ -0,0 +1,118 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of the Symfony package. | ||
5 | * | ||
6 | * (c) Fabien Potencier <fabien@symfony.com> | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | namespace Symfony\Bridge\Twig\Extension; | ||
13 | |||
14 | use Symfony\Bridge\Twig\TokenParser\TransTokenParser; | ||
15 | use Symfony\Bridge\Twig\TokenParser\TransChoiceTokenParser; | ||
16 | use Symfony\Bridge\Twig\TokenParser\TransDefaultDomainTokenParser; | ||
17 | use Symfony\Component\Translation\TranslatorInterface; | ||
18 | use Symfony\Bridge\Twig\NodeVisitor\TranslationNodeVisitor; | ||
19 | use Symfony\Bridge\Twig\NodeVisitor\TranslationDefaultDomainNodeVisitor; | ||
20 | |||
21 | /** | ||
22 | * Provides integration of the Translation component with Twig. | ||
23 | * | ||
24 | * @author Fabien Potencier <fabien@symfony.com> | ||
25 | */ | ||
26 | class TranslationExtension extends \Twig_Extension | ||
27 | { | ||
28 | private $translator; | ||
29 | private $translationNodeVisitor; | ||
30 | |||
31 | public function __construct(TranslatorInterface $translator, \Twig_NodeVisitorInterface $translationNodeVisitor = null) | ||
32 | { | ||
33 | if (!$translationNodeVisitor) { | ||
34 | $translationNodeVisitor = new TranslationNodeVisitor(); | ||
35 | } | ||
36 | |||
37 | $this->translator = $translator; | ||
38 | $this->translationNodeVisitor = $translationNodeVisitor; | ||
39 | } | ||
40 | |||
41 | public function getTranslator() | ||
42 | { | ||
43 | return $this->translator; | ||
44 | } | ||
45 | |||
46 | /** | ||
47 | * {@inheritdoc} | ||
48 | */ | ||
49 | public function getFilters() | ||
50 | { | ||
51 | return array( | ||
52 | 'trans' => new \Twig_Filter_Method($this, 'trans'), | ||
53 | 'transchoice' => new \Twig_Filter_Method($this, 'transchoice'), | ||
54 | ); | ||
55 | } | ||
56 | |||
57 | /** | ||
58 | * Returns the token parser instance to add to the existing list. | ||
59 | * | ||
60 | * @return array An array of Twig_TokenParser instances | ||
61 | */ | ||
62 | public function getTokenParsers() | ||
63 | { | ||
64 | return array( | ||
65 | // {% trans %}Symfony is great!{% endtrans %} | ||
66 | new TransTokenParser(), | ||
67 | |||
68 | // {% transchoice count %} | ||
69 | // {0} There is no apples|{1} There is one apple|]1,Inf] There is {{ count }} apples | ||
70 | // {% endtranschoice %} | ||
71 | new TransChoiceTokenParser(), | ||
72 | |||
73 | // {% trans_default_domain "foobar" %} | ||
74 | new TransDefaultDomainTokenParser(), | ||
75 | ); | ||
76 | } | ||
77 | |||
78 | /** | ||
79 | * {@inheritdoc} | ||
80 | */ | ||
81 | public function getNodeVisitors() | ||
82 | { | ||
83 | return array($this->translationNodeVisitor, new TranslationDefaultDomainNodeVisitor()); | ||
84 | } | ||
85 | |||
86 | public function getTranslationNodeVisitor() | ||
87 | { | ||
88 | return $this->translationNodeVisitor; | ||
89 | } | ||
90 | |||
91 | public function trans($message, array $arguments = array(), $domain = null, $locale = null) | ||
92 | { | ||
93 | if (null === $domain) { | ||
94 | $domain = 'messages'; | ||
95 | } | ||
96 | |||
97 | return $this->translator->trans($message, $arguments, $domain, $locale); | ||
98 | } | ||
99 | |||
100 | public function transchoice($message, $count, array $arguments = array(), $domain = null, $locale = null) | ||
101 | { | ||
102 | if (null === $domain) { | ||
103 | $domain = 'messages'; | ||
104 | } | ||
105 | |||
106 | return $this->translator->transChoice($message, $count, array_merge(array('%count%' => $count), $arguments), $domain, $locale); | ||
107 | } | ||
108 | |||
109 | /** | ||
110 | * Returns the name of the extension. | ||
111 | * | ||
112 | * @return string The extension name | ||
113 | */ | ||
114 | public function getName() | ||
115 | { | ||
116 | return 'translator'; | ||
117 | } | ||
118 | } | ||
diff --git a/vendor/symfony/twig-bridge/Symfony/Bridge/Twig/Extension/YamlExtension.php b/vendor/symfony/twig-bridge/Symfony/Bridge/Twig/Extension/YamlExtension.php new file mode 100644 index 00000000..f88829ee --- /dev/null +++ b/vendor/symfony/twig-bridge/Symfony/Bridge/Twig/Extension/YamlExtension.php | |||
@@ -0,0 +1,67 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of the Symfony package. | ||
5 | * | ||
6 | * (c) Fabien Potencier <fabien@symfony.com> | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | namespace Symfony\Bridge\Twig\Extension; | ||
13 | |||
14 | use Symfony\Component\Yaml\Dumper as YamlDumper; | ||
15 | |||
16 | /** | ||
17 | * Provides integration of the Yaml component with Twig. | ||
18 | * | ||
19 | * @author Fabien Potencier <fabien@symfony.com> | ||
20 | */ | ||
21 | class YamlExtension extends \Twig_Extension | ||
22 | { | ||
23 | /** | ||
24 | * {@inheritdoc} | ||
25 | */ | ||
26 | public function getFilters() | ||
27 | { | ||
28 | return array( | ||
29 | 'yaml_encode' => new \Twig_Filter_Method($this, 'encode'), | ||
30 | 'yaml_dump' => new \Twig_Filter_Method($this, 'dump'), | ||
31 | ); | ||
32 | } | ||
33 | |||
34 | public function encode($input, $inline = 0, $dumpObjects = false) | ||
35 | { | ||
36 | static $dumper; | ||
37 | |||
38 | if (null === $dumper) { | ||
39 | $dumper = new YamlDumper(); | ||
40 | } | ||
41 | |||
42 | return $dumper->dump($input, $inline, false, $dumpObjects); | ||
43 | } | ||
44 | |||
45 | public function dump($value, $inline = 0, $dumpObjects = false) | ||
46 | { | ||
47 | if (is_resource($value)) { | ||
48 | return '%Resource%'; | ||
49 | } | ||
50 | |||
51 | if (is_array($value) || is_object($value)) { | ||
52 | return '%'.gettype($value).'% '.$this->encode($value, $inline, $dumpObjects); | ||
53 | } | ||
54 | |||
55 | return $this->encode($value, $inline, $dumpObjects); | ||
56 | } | ||
57 | |||
58 | /** | ||
59 | * Returns the name of the extension. | ||
60 | * | ||
61 | * @return string The extension name | ||
62 | */ | ||
63 | public function getName() | ||
64 | { | ||
65 | return 'yaml'; | ||
66 | } | ||
67 | } | ||