merged branch bschussek/renderer (PR #5006)
Commits
-------
dc3a680
[Form] Improved FormRenderer API to reduce the size of the function call stack during rendering
Discussion
----------
[Form] Improved FormRenderer API to decrease the function call stack
Bug fix: no
Feature addition: no
Backwards compatibility break: **yes**
Symfony2 tests pass: yes
Fixes the following tickets: #4962, #4973
Todo: -
This PR reduces the function call stack size when rendering by directly calling the methods `renderBlock` and `searchAndRenderBlock` (formerly `renderSection`) and removing the delegating methods `render(Widget|Label|Row|...)`.
It breaks BC in that PHP templates now need to pass the FormView instance to `block` (formerly `renderBlock`). This is necessary, otherwise that function may behave buggy in special circumstances.
Otherwise this PR cleans up API method and parameter names to improve clarity.
This commit is contained in:
commit
214e0554be
@ -559,6 +559,22 @@
|
||||
{% endblock %}
|
||||
```
|
||||
|
||||
* The method `renderBlock()` of the helper for the PHP Templating component was
|
||||
renamed to `block()`. Its first argument is now expected to be a `FormView`
|
||||
instance.
|
||||
|
||||
Before:
|
||||
|
||||
```
|
||||
<?php echo $view['form']->renderBlock('widget_attributes') ?>
|
||||
```
|
||||
|
||||
After:
|
||||
|
||||
```
|
||||
<?php echo $view['form']->block($form, 'widget_attributes') ?>
|
||||
```
|
||||
|
||||
#### Other BC Breaks
|
||||
|
||||
* The order of the first two arguments of the methods `createNamed` and
|
||||
@ -1012,21 +1028,6 @@
|
||||
$registry->addType($registry->resolveType(new MyFormType()));
|
||||
```
|
||||
|
||||
* The method `renderBlock()` of the helper for the PHP Templating component was
|
||||
deprecated and will be removed in Symfony 2.3. You should use `block()` instead.
|
||||
|
||||
Before:
|
||||
|
||||
```
|
||||
<?php echo $view['form']->renderBlock('widget_attributes') ?>
|
||||
```
|
||||
|
||||
After:
|
||||
|
||||
```
|
||||
<?php echo $view['form']->block('widget_attributes') ?>
|
||||
```
|
||||
|
||||
* The following methods in class `FormView` were deprecated and will be
|
||||
removed in Symfony 2.3:
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
"require": {
|
||||
"php": ">=5.3.3",
|
||||
"doctrine/common": ">2.2,<2.4-dev",
|
||||
"twig/twig": ">=1.8,<2.0-dev"
|
||||
"twig/twig": ">=1.9.1,<2.0-dev"
|
||||
},
|
||||
"replace": {
|
||||
"symfony/doctrine-bridge": "self.version",
|
||||
|
@ -62,12 +62,12 @@ class FormExtension extends \Twig_Extension
|
||||
public function getFunctions()
|
||||
{
|
||||
return array(
|
||||
'form_enctype' => new \Twig_Function_Method($this, 'renderer->renderEnctype', array('is_safe' => array('html'))),
|
||||
'form_widget' => new \Twig_Function_Method($this, 'renderer->renderWidget', array('is_safe' => array('html'))),
|
||||
'form_errors' => new \Twig_Function_Method($this, 'renderer->renderErrors', array('is_safe' => array('html'))),
|
||||
'form_label' => new \Twig_Function_Method($this, 'renderer->renderLabel', array('is_safe' => array('html'))),
|
||||
'form_row' => new \Twig_Function_Method($this, 'renderer->renderRow', array('is_safe' => array('html'))),
|
||||
'form_rest' => new \Twig_Function_Method($this, 'renderer->renderRest', array('is_safe' => array('html'))),
|
||||
'form_enctype' => new \Twig_Function_Node('Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode', array('is_safe' => array('html'))),
|
||||
'form_widget' => new \Twig_Function_Node('Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode', array('is_safe' => array('html'))),
|
||||
'form_errors' => new \Twig_Function_Node('Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode', array('is_safe' => array('html'))),
|
||||
'form_label' => new \Twig_Function_Node('Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode', array('is_safe' => array('html'))),
|
||||
'form_row' => new \Twig_Function_Node('Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode', array('is_safe' => array('html'))),
|
||||
'form_rest' => new \Twig_Function_Node('Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode', array('is_safe' => array('html'))),
|
||||
'csrf_token' => new \Twig_Function_Method($this, 'renderer->renderCsrfToken'),
|
||||
);
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ class TwigRendererEngine extends AbstractRendererEngine implements TwigRendererE
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function renderBlock(FormView $view, $resource, $block, array $variables = array())
|
||||
public function renderBlock(FormView $view, $resource, $blockName, array $variables = array())
|
||||
{
|
||||
$cacheKey = $view->vars[self::CACHE_KEY_VAR];
|
||||
|
||||
@ -55,7 +55,7 @@ class TwigRendererEngine extends AbstractRendererEngine implements TwigRendererE
|
||||
|
||||
// We do not call renderBlock here to avoid too many nested level calls
|
||||
// (XDebug limits the level to 100 by default)
|
||||
$this->template->displayBlock($block, $context, $this->resources[$cacheKey]);
|
||||
$this->template->displayBlock($blockName, $context, $this->resources[$cacheKey]);
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
@ -72,11 +72,11 @@ class TwigRendererEngine extends AbstractRendererEngine implements TwigRendererE
|
||||
*
|
||||
* @param string $cacheKey The cache key of the form view.
|
||||
* @param FormView $view The form view for finding the applying themes.
|
||||
* @param string $block The name of the block to load.
|
||||
* @param string $blockName The name of the block to load.
|
||||
*
|
||||
* @return Boolean True if the resource could be loaded, false otherwise.
|
||||
*/
|
||||
protected function loadResourceForBlock($cacheKey, FormView $view, $block)
|
||||
protected function loadResourceForBlockName($cacheKey, FormView $view, $blockName)
|
||||
{
|
||||
// The caller guarantees that $this->resources[$cacheKey][$block] is
|
||||
// not set, but it doesn't have to check whether $this->resources[$cacheKey]
|
||||
@ -86,7 +86,7 @@ class TwigRendererEngine extends AbstractRendererEngine implements TwigRendererE
|
||||
// As said in the previous, the caller guarantees that
|
||||
// $this->resources[$cacheKey][$block] is not set. Since the themes are
|
||||
// already loaded, it can only be a non-existing block.
|
||||
$this->resources[$cacheKey][$block] = false;
|
||||
$this->resources[$cacheKey][$blockName] = false;
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -117,25 +117,25 @@ class TwigRendererEngine extends AbstractRendererEngine implements TwigRendererE
|
||||
$parentCacheKey = $view->parent->vars[self::CACHE_KEY_VAR];
|
||||
|
||||
if (!isset($this->resources[$parentCacheKey])) {
|
||||
$this->loadResourceForBlock($parentCacheKey, $view->parent, $block);
|
||||
$this->loadResourceForBlockName($parentCacheKey, $view->parent, $blockName);
|
||||
}
|
||||
|
||||
// EAGER CACHE POPULATION (see doc comment)
|
||||
foreach ($this->resources[$parentCacheKey] as $blockName => $resource) {
|
||||
if (!isset($this->resources[$cacheKey][$blockName])) {
|
||||
$this->resources[$cacheKey][$blockName] = $resource;
|
||||
foreach ($this->resources[$parentCacheKey] as $nestedBlockName => $resource) {
|
||||
if (!isset($this->resources[$cacheKey][$nestedBlockName])) {
|
||||
$this->resources[$cacheKey][$nestedBlockName] = $resource;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Even though we loaded the themes, it can happen that none of them
|
||||
// contains the searched block
|
||||
if (!isset($this->resources[$cacheKey][$block])) {
|
||||
if (!isset($this->resources[$cacheKey][$blockName])) {
|
||||
// Cache that we didn't find anything to speed up further accesses
|
||||
$this->resources[$cacheKey][$block] = false;
|
||||
$this->resources[$cacheKey][$blockName] = false;
|
||||
}
|
||||
|
||||
return false !== $this->resources[$cacheKey][$block];
|
||||
return false !== $this->resources[$cacheKey][$blockName];
|
||||
}
|
||||
|
||||
/**
|
||||
|
56
src/Symfony/Bridge/Twig/Node/SearchAndRenderBlockNode.php
Normal file
56
src/Symfony/Bridge/Twig/Node/SearchAndRenderBlockNode.php
Normal file
@ -0,0 +1,56 @@
|
||||
<?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\Bridge\Twig\Node;
|
||||
|
||||
/**
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
class SearchAndRenderBlockNode extends \Twig_Node_Expression_Function
|
||||
{
|
||||
public function compile(\Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler->addDebugInfo($this);
|
||||
$compiler->raw('$this->env->getExtension(\'form\')->renderer->searchAndRenderBlock(');
|
||||
|
||||
preg_match('/_([^_]+)$/', $this->getAttribute('name'), $matches);
|
||||
|
||||
$label = null;
|
||||
$arguments = iterator_to_array($this->getNode('arguments'));
|
||||
$blockNameSuffix = $matches[1];
|
||||
|
||||
if (isset($arguments[0])) {
|
||||
$compiler->subcompile($arguments[0]);
|
||||
$compiler->raw(', \'' . $blockNameSuffix . '\'');
|
||||
|
||||
if (isset($arguments[1])) {
|
||||
$compiler->raw(', ');
|
||||
|
||||
// The "label" function allows one extra argument here, the label
|
||||
if ('label' === $blockNameSuffix) {
|
||||
if (isset($arguments[2])) {
|
||||
$compiler->subcompile($arguments[2]);
|
||||
$compiler->raw(' + ');
|
||||
}
|
||||
|
||||
// Add the label to the variable array
|
||||
$compiler->raw('array(\'label\' => ');
|
||||
$compiler->subcompile($arguments[1]);
|
||||
$compiler->raw(')');
|
||||
} else {
|
||||
$compiler->subcompile($arguments[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$compiler->raw(")");
|
||||
}
|
||||
}
|
@ -141,32 +141,36 @@ class FormExtensionDivLayoutTest extends AbstractDivLayoutTest
|
||||
|
||||
protected function renderEnctype(FormView $view)
|
||||
{
|
||||
return (string) $this->extension->renderer->renderEnctype($view);
|
||||
return (string) $this->extension->renderer->searchAndRenderBlock($view, 'enctype');
|
||||
}
|
||||
|
||||
protected function renderLabel(FormView $view, $label = null, array $vars = array())
|
||||
{
|
||||
return (string) $this->extension->renderer->renderLabel($view, $label, $vars);
|
||||
if ($label !== null) {
|
||||
$vars += array('label' => $label);
|
||||
}
|
||||
|
||||
return (string) $this->extension->renderer->searchAndRenderBlock($view, 'label', $vars);
|
||||
}
|
||||
|
||||
protected function renderErrors(FormView $view)
|
||||
{
|
||||
return (string) $this->extension->renderer->renderErrors($view);
|
||||
return (string) $this->extension->renderer->searchAndRenderBlock($view, 'errors');
|
||||
}
|
||||
|
||||
protected function renderWidget(FormView $view, array $vars = array())
|
||||
{
|
||||
return (string) $this->extension->renderer->renderWidget($view, $vars);
|
||||
return (string) $this->extension->renderer->searchAndRenderBlock($view, 'widget', $vars);
|
||||
}
|
||||
|
||||
protected function renderRow(FormView $view, array $vars = array())
|
||||
{
|
||||
return (string) $this->extension->renderer->renderRow($view, $vars);
|
||||
return (string) $this->extension->renderer->searchAndRenderBlock($view, 'row', $vars);
|
||||
}
|
||||
|
||||
protected function renderRest(FormView $view, array $vars = array())
|
||||
{
|
||||
return (string) $this->extension->renderer->renderRest($view, $vars);
|
||||
return (string) $this->extension->renderer->searchAndRenderBlock($view, 'rest', $vars);
|
||||
}
|
||||
|
||||
protected function setTheme(FormView $view, array $themes)
|
||||
|
@ -77,32 +77,36 @@ class FormExtensionTableLayoutTest extends AbstractTableLayoutTest
|
||||
|
||||
protected function renderEnctype(FormView $view)
|
||||
{
|
||||
return (string) $this->extension->renderer->renderEnctype($view);
|
||||
return (string) $this->extension->renderer->searchAndRenderBlock($view, 'enctype');
|
||||
}
|
||||
|
||||
protected function renderLabel(FormView $view, $label = null, array $vars = array())
|
||||
{
|
||||
return (string) $this->extension->renderer->renderLabel($view, $label, $vars);
|
||||
if ($label !== null) {
|
||||
$vars += array('label' => $label);
|
||||
}
|
||||
|
||||
return (string) $this->extension->renderer->searchAndRenderBlock($view, 'label', $vars);
|
||||
}
|
||||
|
||||
protected function renderErrors(FormView $view)
|
||||
{
|
||||
return (string) $this->extension->renderer->renderErrors($view);
|
||||
return (string) $this->extension->renderer->searchAndRenderBlock($view, 'errors');
|
||||
}
|
||||
|
||||
protected function renderWidget(FormView $view, array $vars = array())
|
||||
{
|
||||
return (string) $this->extension->renderer->renderWidget($view, $vars);
|
||||
return (string) $this->extension->renderer->searchAndRenderBlock($view, 'widget', $vars);
|
||||
}
|
||||
|
||||
protected function renderRow(FormView $view, array $vars = array())
|
||||
{
|
||||
return (string) $this->extension->renderer->renderRow($view, $vars);
|
||||
return (string) $this->extension->renderer->searchAndRenderBlock($view, 'row', $vars);
|
||||
}
|
||||
|
||||
protected function renderRest(FormView $view, array $vars = array())
|
||||
{
|
||||
return (string) $this->extension->renderer->renderRest($view, $vars);
|
||||
return (string) $this->extension->renderer->searchAndRenderBlock($view, 'rest', $vars);
|
||||
}
|
||||
|
||||
protected function setTheme(FormView $view, array $themes)
|
||||
|
@ -17,7 +17,7 @@
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.3.3",
|
||||
"twig/twig": ">=1.8,<2.0-dev"
|
||||
"twig/twig": ">=1.9.1,<2.0-dev"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/form": "2.1.*",
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->block('widget_attributes') ?>
|
||||
<?php echo $view['form']->block($form, 'widget_attributes') ?>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<input type="checkbox"
|
||||
<?php echo $view['form']->block('widget_attributes') ?>
|
||||
<?php echo $view['form']->block($form, 'widget_attributes') ?>
|
||||
<?php if ($value): ?> value="<?php echo $view->escape($value) ?>"<?php endif ?>
|
||||
<?php if ($checked): ?> checked="checked"<?php endif ?>
|
||||
/>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->block('choice_widget_options') ?>
|
||||
<?php echo $view['form']->block($form, 'choice_widget_options') ?>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?php if ($expanded): ?>
|
||||
<?php echo $view['form']->block('choice_widget_expanded') ?>
|
||||
<?php echo $view['form']->block($form, 'choice_widget_expanded') ?>
|
||||
<?php else: ?>
|
||||
<?php echo $view['form']->block('choice_widget_collapsed') ?>
|
||||
<?php echo $view['form']->block($form, 'choice_widget_collapsed') ?>
|
||||
<?php endif ?>
|
||||
|
@ -1,13 +1,13 @@
|
||||
<select
|
||||
<?php echo $view['form']->block('widget_attributes') ?>
|
||||
<?php echo $view['form']->block($form, 'widget_attributes') ?>
|
||||
<?php if ($multiple): ?> multiple="multiple"<?php endif ?>
|
||||
>
|
||||
<?php if (null !== $empty_value): ?><option value=""><?php echo $view->escape($view['translator']->trans($empty_value, array(), $translation_domain)) ?></option><?php endif; ?>
|
||||
<?php if (count($preferred_choices) > 0): ?>
|
||||
<?php echo $view['form']->block('choice_widget_options', array('choices' => $preferred_choices)) ?>
|
||||
<?php echo $view['form']->block($form, 'choice_widget_options', array('choices' => $preferred_choices)) ?>
|
||||
<?php if (count($choices) > 0 && null !== $separator): ?>
|
||||
<option disabled="disabled"><?php echo $separator ?></option>
|
||||
<?php endif ?>
|
||||
<?php endif ?>
|
||||
<?php echo $view['form']->block('choice_widget_options', array('choices' => $choices)) ?>
|
||||
<?php echo $view['form']->block($form, 'choice_widget_options', array('choices' => $choices)) ?>
|
||||
</select>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<div <?php echo $view['form']->block('widget_container_attributes') ?>>
|
||||
<div <?php echo $view['form']->block($form, 'widget_container_attributes') ?>>
|
||||
<?php foreach ($form as $child): ?>
|
||||
<?php echo $view['form']->widget($child) ?>
|
||||
<?php echo $view['form']->label($child) ?>
|
||||
|
@ -3,7 +3,7 @@
|
||||
<?php foreach ($choices as $index => $choice): ?>
|
||||
<?php if (is_array($choice)): ?>
|
||||
<optgroup label="<?php echo $view->escape($translatorHelper->trans($index, array(), $translation_domain)) ?>">
|
||||
<?php echo $formHelper->block('choice_widget_options', array('choices' => $choice)) ?>
|
||||
<?php echo $formHelper->block($form, 'choice_widget_options', array('choices' => $choice)) ?>
|
||||
</optgroup>
|
||||
<?php else: ?>
|
||||
<option value="<?php echo $view->escape($choice->value) ?>"<?php if ($is_selected($choice->value, $value)): ?> selected="selected"<?php endif?>><?php echo $view->escape($translatorHelper->trans($choice->label, array(), $translation_domain)) ?></option>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->block('widget_container_attributes') ?>
|
||||
<?php echo $view['form']->block($form, 'widget_container_attributes') ?>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?php if ($widget == 'single_text'): ?>
|
||||
<?php echo $view['form']->block('form_widget_simple'); ?>
|
||||
<?php echo $view['form']->block($form, 'form_widget_simple'); ?>
|
||||
<?php else: ?>
|
||||
<div <?php echo $view['form']->block('widget_container_attributes') ?>>
|
||||
<div <?php echo $view['form']->block($form, 'widget_container_attributes') ?>>
|
||||
<?php echo str_replace(array('{{ year }}', '{{ month }}', '{{ day }}'), array(
|
||||
$view['form']->widget($form['year']),
|
||||
$view['form']->widget($form['month']),
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?php if ($widget == 'single_text'): ?>
|
||||
<?php echo $view['form']->block('form_widget_simple'); ?>
|
||||
<?php echo $view['form']->block($form, 'form_widget_simple'); ?>
|
||||
<?php else: ?>
|
||||
<div <?php echo $view['form']->block('widget_container_attributes') ?>>
|
||||
<div <?php echo $view['form']->block($form, 'widget_container_attributes') ?>>
|
||||
<?php echo $view['form']->widget($form['date']).' '.$view['form']->widget($form['time']) ?>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->block('form_widget_simple', array('type' => isset($type) ? $type : 'email')) ?>
|
||||
<?php echo $view['form']->block($form, 'form_widget_simple', array('type' => isset($type) ? $type : 'email')) ?>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->block('form_enctype') ?>
|
||||
<?php echo $view['form']->block($form, 'form_enctype') ?>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->block('form_errors') ?>
|
||||
<?php echo $view['form']->block($form, 'form_errors') ?>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->block('form_label') ?>
|
||||
<?php echo $view['form']->block($form, 'form_label') ?>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->block('form_rest') ?>
|
||||
<?php echo $view['form']->block($form, 'form_rest') ?>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->block('form_row') ?>
|
||||
<?php echo $view['form']->block($form, 'form_row') ?>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->block('form_rows') ?>
|
||||
<?php echo $view['form']->block($form, 'form_rows') ?>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->block('form_widget_simple') ?>
|
||||
<?php echo $view['form']->block($form, 'form_widget_simple') ?>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?php if ($compound): ?>
|
||||
<?php echo $view['form']->block('form_widget_compound')?>
|
||||
<?php echo $view['form']->block($form, 'form_widget_compound')?>
|
||||
<?php else: ?>
|
||||
<?php echo $view['form']->block('form_widget_simple')?>
|
||||
<?php echo $view['form']->block($form, 'form_widget_simple')?>
|
||||
<?php endif ?>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<div <?php echo $view['form']->block('widget_container_attributes') ?>>
|
||||
<div <?php echo $view['form']->block($form, 'widget_container_attributes') ?>>
|
||||
<?php if (!$form->parent && $errors): ?>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
@ -6,6 +6,6 @@
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif ?>
|
||||
<?php echo $view['form']->block('form_rows') ?>
|
||||
<?php echo $view['form']->block($form, 'form_rows') ?>
|
||||
<?php echo $view['form']->rest($form) ?>
|
||||
</div>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<input
|
||||
type="<?php echo isset($type) ? $view->escape($type) : 'text' ?>"
|
||||
<?php if (!empty($value)): ?>value="<?php echo $view->escape($value) ?>"<?php endif ?>
|
||||
<?php echo $view['form']->block('widget_attributes') ?>
|
||||
<?php echo $view['form']->block($form, 'widget_attributes') ?>
|
||||
/>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->block('form_widget_simple', array('type' => isset($type) ? $type : "hidden")) ?>
|
||||
<?php echo $view['form']->block($form, 'form_widget_simple', array('type' => isset($type) ? $type : "hidden")) ?>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->block('form_widget_simple', array('type' => isset($type) ? $type : "number")) ?>
|
||||
<?php echo $view['form']->block($form, 'form_widget_simple', array('type' => isset($type) ? $type : "number")) ?>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo str_replace('{{ widget }}', $view['form']->block('form_widget_simple'), $money_pattern) ?>
|
||||
<?php echo str_replace('{{ widget }}', $view['form']->block($form, 'form_widget_simple'), $money_pattern) ?>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->block('form_widget_simple', array('type' => isset($type) ? $type : "text")) ?>
|
||||
<?php echo $view['form']->block($form, 'form_widget_simple', array('type' => isset($type) ? $type : "text")) ?>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->block('form_widget_simple', array('type' => isset($type) ? $type : "password")) ?>
|
||||
<?php echo $view['form']->block($form, 'form_widget_simple', array('type' => isset($type) ? $type : "password")) ?>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->block('form_widget_simple', array('type' => isset($type) ? $type : "text")) ?> %
|
||||
<?php echo $view['form']->block($form, 'form_widget_simple', array('type' => isset($type) ? $type : "text")) ?> %
|
||||
|
@ -1,5 +1,5 @@
|
||||
<input type="radio"
|
||||
<?php echo $view['form']->block('widget_attributes') ?>
|
||||
<?php echo $view['form']->block($form, 'widget_attributes') ?>
|
||||
value="<?php echo $view->escape($value) ?>"
|
||||
<?php if ($checked): ?> checked="checked"<?php endif ?>
|
||||
/>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->block('form_rows') ?>
|
||||
<?php echo $view['form']->block($form, 'form_rows') ?>
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->block('form_widget_simple', array('type' => isset($type) ? $type : "search")) ?>
|
||||
<?php echo $view['form']->block($form, 'form_widget_simple', array('type' => isset($type) ? $type : "search")) ?>
|
||||
|
@ -1 +1 @@
|
||||
<textarea <?php echo $view['form']->block('widget_attributes') ?>><?php echo $view->escape($value) ?></textarea>
|
||||
<textarea <?php echo $view['form']->block($form, 'widget_attributes') ?>><?php echo $view->escape($value) ?></textarea>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?php if ($widget == 'single_text'): ?>
|
||||
<?php echo $view['form']->block('form_widget_simple'); ?>
|
||||
<?php echo $view['form']->block($form, 'form_widget_simple'); ?>
|
||||
<?php else: ?>
|
||||
<div <?php echo $view['form']->block('widget_container_attributes') ?>>
|
||||
<div <?php echo $view['form']->block($form, 'widget_container_attributes') ?>>
|
||||
<?php
|
||||
// There should be no spaces between the colons and the widgets, that's why
|
||||
// this block is written in a single PHP tag
|
||||
|
@ -1 +1 @@
|
||||
<?php echo $view['form']->block('form_widget_simple', array('type' => isset($type) ? $type : "url")) ?>
|
||||
<?php echo $view['form']->block($form, 'form_widget_simple', array('type' => isset($type) ? $type : "url")) ?>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<table <?php echo $view['form']->block('widget_container_attributes') ?>>
|
||||
<table <?php echo $view['form']->block($form, 'widget_container_attributes') ?>>
|
||||
<?php if (!$form->parent): ?>
|
||||
<?php echo $view['form']->errors($form) ?>
|
||||
<?php endif ?>
|
||||
<?php echo $view['form']->block('form_rows') ?>
|
||||
<?php echo $view['form']->block($form, 'form_rows') ?>
|
||||
<?php echo $view['form']->rest($form) ?>
|
||||
</table>
|
||||
|
@ -75,7 +75,7 @@ class FormHelper extends Helper
|
||||
*/
|
||||
public function enctype(FormView $view)
|
||||
{
|
||||
return $this->renderer->renderEnctype($view);
|
||||
return $this->renderer->searchAndRenderBlock($view, 'enctype');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -98,7 +98,7 @@ class FormHelper extends Helper
|
||||
*/
|
||||
public function widget(FormView $view, array $variables = array())
|
||||
{
|
||||
return $this->renderer->renderWidget($view, $variables);
|
||||
return $this->renderer->searchAndRenderBlock($view, 'widget', $variables);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -111,7 +111,7 @@ class FormHelper extends Helper
|
||||
*/
|
||||
public function row(FormView $view, array $variables = array())
|
||||
{
|
||||
return $this->renderer->renderRow($view, $variables);
|
||||
return $this->renderer->searchAndRenderBlock($view, 'row', $variables);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -125,7 +125,11 @@ class FormHelper extends Helper
|
||||
*/
|
||||
public function label(FormView $view, $label = null, array $variables = array())
|
||||
{
|
||||
return $this->renderer->renderLabel($view, $label, $variables);
|
||||
if ($label !== null) {
|
||||
$variables += array('label' => $label);
|
||||
}
|
||||
|
||||
return $this->renderer->searchAndRenderBlock($view, 'label', $variables);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -137,7 +141,7 @@ class FormHelper extends Helper
|
||||
*/
|
||||
public function errors(FormView $view)
|
||||
{
|
||||
return $this->renderer->renderErrors($view);
|
||||
return $this->renderer->searchAndRenderBlock($view, 'errors');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -150,36 +154,21 @@ class FormHelper extends Helper
|
||||
*/
|
||||
public function rest(FormView $view, array $variables = array())
|
||||
{
|
||||
return $this->renderer->renderRest($view, $variables);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias of {@link block()}
|
||||
*
|
||||
* @param string $block The name of the block to render.
|
||||
* @param array $variables The variable to pass to the template.
|
||||
*
|
||||
* @return string The HTML markup
|
||||
*
|
||||
* @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
|
||||
* {@link block()} instead.
|
||||
*/
|
||||
public function renderBlock($block, array $variables = array())
|
||||
{
|
||||
return $this->renderer->renderBlock($block, $variables);
|
||||
return $this->renderer->searchAndRenderBlock($view, 'rest', $variables);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a block of the template.
|
||||
*
|
||||
* @param string $block The name of the block to render.
|
||||
* @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($block, array $variables = array())
|
||||
public function block(FormView $view, $blockName, array $variables = array())
|
||||
{
|
||||
return $this->renderer->renderBlock($block, $variables);
|
||||
return $this->renderer->renderBlock($view, $blockName, $variables);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,2 +1,2 @@
|
||||
<?php $type = isset($type) ? $type : 'text' ?>
|
||||
<input type="<?php echo $type ?>" <?php $view['form']->renderBlock('widget_attributes') ?> value="<?php echo $value ?>" rel="theme" />
|
||||
<input type="<?php echo $type ?>" <?php $view['form']->block($form, 'widget_attributes') ?> value="<?php echo $value ?>" rel="theme" />
|
||||
|
@ -74,52 +74,52 @@ abstract class AbstractRendererEngine implements FormRendererEngineInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getResourceForBlock(FormView $view, $block)
|
||||
public function getResourceForBlockName(FormView $view, $blockName)
|
||||
{
|
||||
$cacheKey = $view->vars[self::CACHE_KEY_VAR];
|
||||
|
||||
if (!isset($this->resources[$cacheKey][$block])) {
|
||||
$this->loadResourceForBlock($cacheKey, $view, $block);
|
||||
if (!isset($this->resources[$cacheKey][$blockName])) {
|
||||
$this->loadResourceForBlockName($cacheKey, $view, $blockName);
|
||||
}
|
||||
|
||||
return $this->resources[$cacheKey][$block];
|
||||
return $this->resources[$cacheKey][$blockName];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getResourceForBlockHierarchy(FormView $view, array $blockHierarchy, $hierarchyLevel)
|
||||
public function getResourceForBlockNameHierarchy(FormView $view, array $blockNameHierarchy, $hierarchyLevel)
|
||||
{
|
||||
$cacheKey = $view->vars[self::CACHE_KEY_VAR];
|
||||
$block = $blockHierarchy[$hierarchyLevel];
|
||||
$blockName = $blockNameHierarchy[$hierarchyLevel];
|
||||
|
||||
if (!isset($this->resources[$cacheKey][$block])) {
|
||||
$this->loadResourceForBlockHierarchy($cacheKey, $view, $blockHierarchy, $hierarchyLevel);
|
||||
if (!isset($this->resources[$cacheKey][$blockName])) {
|
||||
$this->loadResourceForBlockNameHierarchy($cacheKey, $view, $blockNameHierarchy, $hierarchyLevel);
|
||||
}
|
||||
|
||||
return $this->resources[$cacheKey][$block];
|
||||
return $this->resources[$cacheKey][$blockName];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getResourceHierarchyLevel(FormView $view, array $blockHierarchy, $hierarchyLevel)
|
||||
public function getResourceHierarchyLevel(FormView $view, array $blockNameHierarchy, $hierarchyLevel)
|
||||
{
|
||||
$cacheKey = $view->vars[self::CACHE_KEY_VAR];
|
||||
$block = $blockHierarchy[$hierarchyLevel];
|
||||
$blockName = $blockNameHierarchy[$hierarchyLevel];
|
||||
|
||||
if (!isset($this->resources[$cacheKey][$block])) {
|
||||
$this->loadResourceForBlockHierarchy($cacheKey, $view, $blockHierarchy, $hierarchyLevel);
|
||||
if (!isset($this->resources[$cacheKey][$blockName])) {
|
||||
$this->loadResourceForBlockNameHierarchy($cacheKey, $view, $blockNameHierarchy, $hierarchyLevel);
|
||||
}
|
||||
|
||||
// If $block was previously rendered loaded with loadTemplateForBlock(), the template
|
||||
// is cached but the hierarchy level is not. In this case, we know that the block
|
||||
// exists at this very hierarchy level, so we can just set it.
|
||||
if (!isset($this->resourceHierarchyLevels[$cacheKey][$block])) {
|
||||
$this->resourceHierarchyLevels[$cacheKey][$block] = $hierarchyLevel;
|
||||
if (!isset($this->resourceHierarchyLevels[$cacheKey][$blockName])) {
|
||||
$this->resourceHierarchyLevels[$cacheKey][$blockName] = $hierarchyLevel;
|
||||
}
|
||||
|
||||
return $this->resourceHierarchyLevels[$cacheKey][$block];
|
||||
return $this->resourceHierarchyLevels[$cacheKey][$blockName];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -129,11 +129,11 @@ abstract class AbstractRendererEngine implements FormRendererEngineInterface
|
||||
*
|
||||
* @param string $cacheKey The cache key of the form view.
|
||||
* @param FormView $view The form view for finding the applying themes.
|
||||
* @param string $block The name of the block to load.
|
||||
* @param string $blockName The name of the block to load.
|
||||
*
|
||||
* @return Boolean True if the resource could be loaded, false otherwise.
|
||||
*/
|
||||
abstract protected function loadResourceForBlock($cacheKey, FormView $view, $block);
|
||||
abstract protected function loadResourceForBlockName($cacheKey, FormView $view, $blockName);
|
||||
|
||||
/**
|
||||
* Loads the cache with the resource for a specific level of a block hierarchy.
|
||||
@ -144,62 +144,62 @@ abstract class AbstractRendererEngine implements FormRendererEngineInterface
|
||||
* resource.
|
||||
* @param FormView $view The form view for finding the applying
|
||||
* themes.
|
||||
* @param array $blockHierarchy The block hierarchy, with the most
|
||||
* @param array $blockNameHierarchy The block hierarchy, with the most
|
||||
* specific block name at the end.
|
||||
* @param integer $hierarchyLevel The level in the block hierarchy that
|
||||
* should be loaded.
|
||||
*
|
||||
* @return Boolean True if the resource could be loaded, false otherwise.
|
||||
*/
|
||||
private function loadResourceForBlockHierarchy($cacheKey, FormView $view, array $blockHierarchy, $hierarchyLevel)
|
||||
private function loadResourceForBlockNameHierarchy($cacheKey, FormView $view, array $blockNameHierarchy, $hierarchyLevel)
|
||||
{
|
||||
$block = $blockHierarchy[$hierarchyLevel];
|
||||
$blockName = $blockNameHierarchy[$hierarchyLevel];
|
||||
|
||||
// Try to find a template for that block
|
||||
if ($this->loadResourceForBlock($cacheKey, $view, $block)) {
|
||||
if ($this->loadResourceForBlockName($cacheKey, $view, $blockName)) {
|
||||
// If loadTemplateForBlock() returns true, it was able to populate the
|
||||
// cache. The only missing thing is to set the hierarchy level at which
|
||||
// the template was found.
|
||||
$this->resourceHierarchyLevels[$cacheKey][$block] = $hierarchyLevel;
|
||||
$this->resourceHierarchyLevels[$cacheKey][$blockName] = $hierarchyLevel;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($hierarchyLevel > 0) {
|
||||
$parentLevel = $hierarchyLevel - 1;
|
||||
$parentBlock = $blockHierarchy[$parentLevel];
|
||||
$parentBlockName = $blockNameHierarchy[$parentLevel];
|
||||
|
||||
// The next two if statements contain slightly duplicated code. This is by intention
|
||||
// and tries to avoid execution of unnecessary checks in order to increase performance.
|
||||
|
||||
if (isset($this->resources[$cacheKey][$parentBlock])) {
|
||||
if (isset($this->resources[$cacheKey][$parentBlockName])) {
|
||||
// It may happen that the parent block is already loaded, but its level is not.
|
||||
// In this case, the parent block must have been loaded by loadResourceForBlock(),
|
||||
// which does not check the hierarchy of the block. Subsequently the block must have
|
||||
// been found directly on the parent level.
|
||||
if (!isset($this->resourceHierarchyLevels[$cacheKey][$parentBlock])) {
|
||||
$this->resourceHierarchyLevels[$cacheKey][$parentBlock] = $parentLevel;
|
||||
if (!isset($this->resourceHierarchyLevels[$cacheKey][$parentBlockName])) {
|
||||
$this->resourceHierarchyLevels[$cacheKey][$parentBlockName] = $parentLevel;
|
||||
}
|
||||
|
||||
// Cache the shortcuts for further accesses
|
||||
$this->resources[$cacheKey][$block] = $this->resources[$cacheKey][$parentBlock];
|
||||
$this->resourceHierarchyLevels[$cacheKey][$block] = $this->resourceHierarchyLevels[$cacheKey][$parentBlock];
|
||||
$this->resources[$cacheKey][$blockName] = $this->resources[$cacheKey][$parentBlockName];
|
||||
$this->resourceHierarchyLevels[$cacheKey][$blockName] = $this->resourceHierarchyLevels[$cacheKey][$parentBlockName];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->loadResourceForBlockHierarchy($cacheKey, $view, $blockHierarchy, $parentLevel)) {
|
||||
if ($this->loadResourceForBlockNameHierarchy($cacheKey, $view, $blockNameHierarchy, $parentLevel)) {
|
||||
// Cache the shortcuts for further accesses
|
||||
$this->resources[$cacheKey][$block] = $this->resources[$cacheKey][$parentBlock];
|
||||
$this->resourceHierarchyLevels[$cacheKey][$block] = $this->resourceHierarchyLevels[$cacheKey][$parentBlock];
|
||||
$this->resources[$cacheKey][$blockName] = $this->resources[$cacheKey][$parentBlockName];
|
||||
$this->resourceHierarchyLevels[$cacheKey][$blockName] = $this->resourceHierarchyLevels[$cacheKey][$parentBlockName];
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Cache the result for further accesses
|
||||
$this->resources[$cacheKey][$block] = false;
|
||||
$this->resourceHierarchyLevels[$cacheKey][$block] = false;
|
||||
$this->resources[$cacheKey][$blockName] = false;
|
||||
$this->resourceHierarchyLevels[$cacheKey][$blockName] = false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -173,5 +173,5 @@ CHANGELOG
|
||||
* `toArrayKeys`
|
||||
* `isChoiceGroup`
|
||||
* `isChoiceSelected`
|
||||
* added method `block` to FormHelper and deprecated `renderBlock` instead
|
||||
* [BC BREAK] renamed method `renderBlock` in FormHelper to `block` and changed its signature
|
||||
* made FormView properties public and deprecated their accessor methods
|
||||
|
@ -35,7 +35,7 @@ class TemplatingRendererEngine extends AbstractRendererEngine
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function renderBlock(FormView $view, $resource, $block, array $variables = array())
|
||||
public function renderBlock(FormView $view, $resource, $blockName, array $variables = array())
|
||||
{
|
||||
return trim($this->engine->render($resource, $variables));
|
||||
}
|
||||
@ -50,11 +50,11 @@ class TemplatingRendererEngine extends AbstractRendererEngine
|
||||
*
|
||||
* @param string $cacheKey The cache key of the form view.
|
||||
* @param FormView $view The form view for finding the applying themes.
|
||||
* @param string $block The name of the block to load.
|
||||
* @param string $blockName The name of the block to load.
|
||||
*
|
||||
* @return Boolean True if the resource could be loaded, false otherwise.
|
||||
*/
|
||||
protected function loadResourceForBlock($cacheKey, FormView $view, $block)
|
||||
protected function loadResourceForBlockName($cacheKey, FormView $view, $blockName)
|
||||
{
|
||||
// Recursively try to find the block in the themes assigned to $view,
|
||||
// then of its parent form, then of the parent form of the parent and so on.
|
||||
@ -64,7 +64,7 @@ class TemplatingRendererEngine extends AbstractRendererEngine
|
||||
// Check each theme whether it contains the searched block
|
||||
if (isset($this->themes[$cacheKey])) {
|
||||
for ($i = count($this->themes[$cacheKey]) - 1; $i >= 0; --$i) {
|
||||
if ($this->loadResourceFromTheme($cacheKey, $block, $this->themes[$cacheKey][$i])) {
|
||||
if ($this->loadResourceFromTheme($cacheKey, $blockName, $this->themes[$cacheKey][$i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -73,7 +73,7 @@ class TemplatingRendererEngine extends AbstractRendererEngine
|
||||
// Check the default themes once we reach the root form without success
|
||||
if (!$view->parent) {
|
||||
for ($i = count($this->defaultThemes) - 1; $i >= 0; --$i) {
|
||||
if ($this->loadResourceFromTheme($cacheKey, $block, $this->defaultThemes[$i])) {
|
||||
if ($this->loadResourceFromTheme($cacheKey, $blockName, $this->defaultThemes[$i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -84,21 +84,21 @@ class TemplatingRendererEngine extends AbstractRendererEngine
|
||||
if ($view->parent) {
|
||||
$parentCacheKey = $view->parent->vars[self::CACHE_KEY_VAR];
|
||||
|
||||
if (!isset($this->resources[$parentCacheKey][$block])) {
|
||||
$this->loadResourceForBlock($parentCacheKey, $view->parent, $block);
|
||||
if (!isset($this->resources[$parentCacheKey][$blockName])) {
|
||||
$this->loadResourceForBlockName($parentCacheKey, $view->parent, $blockName);
|
||||
}
|
||||
|
||||
// If a template exists in the parent themes, cache that template
|
||||
// for the current theme as well to speed up further accesses
|
||||
if ($this->resources[$parentCacheKey][$block]) {
|
||||
$this->resources[$cacheKey][$block] = $this->resources[$parentCacheKey][$block];
|
||||
if ($this->resources[$parentCacheKey][$blockName]) {
|
||||
$this->resources[$cacheKey][$blockName] = $this->resources[$parentCacheKey][$blockName];
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Cache that we didn't find anything to speed up further accesses
|
||||
$this->resources[$cacheKey][$block] = false;
|
||||
$this->resources[$cacheKey][$blockName] = false;
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -107,15 +107,15 @@ class TemplatingRendererEngine extends AbstractRendererEngine
|
||||
* Tries to load the resource for a block from a theme.
|
||||
*
|
||||
* @param string $cacheKey The cache key for storing the resource.
|
||||
* @param string $block The name of the block to load a resource for.
|
||||
* @param string $blockName The name of the block to load a resource for.
|
||||
* @param mixed $theme The theme to load the block from.
|
||||
*
|
||||
* @return Boolean True if the resource could be loaded, false otherwise.
|
||||
*/
|
||||
protected function loadResourceFromTheme($cacheKey, $block, $theme)
|
||||
protected function loadResourceFromTheme($cacheKey, $blockName, $theme)
|
||||
{
|
||||
if ($this->engine->exists($templateName = $theme . ':' . $block . '.html.php')) {
|
||||
$this->resources[$cacheKey][$block] = $templateName;
|
||||
if ($this->engine->exists($templateName = $theme . ':' . $blockName . '.html.php')) {
|
||||
$this->resources[$cacheKey][$blockName] = $templateName;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ class FormRenderer implements FormRendererInterface
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $blockHierarchyMap = array();
|
||||
private $blockNameHierarchyMap = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
@ -50,7 +50,7 @@ class FormRenderer implements FormRendererInterface
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $stack = array();
|
||||
private $variableStack = array();
|
||||
|
||||
public function __construct(FormRendererEngineInterface $engine, CsrfProviderInterface $csrfProvider = null)
|
||||
{
|
||||
@ -74,58 +74,6 @@ class FormRenderer implements FormRendererInterface
|
||||
$this->engine->setTheme($view, $themes);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function renderEnctype(FormView $view)
|
||||
{
|
||||
return $this->renderSection($view, 'enctype');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function renderRow(FormView $view, array $variables = array())
|
||||
{
|
||||
return $this->renderSection($view, 'row', $variables);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function renderRest(FormView $view, array $variables = array())
|
||||
{
|
||||
return $this->renderSection($view, 'rest', $variables);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function renderWidget(FormView $view, array $variables = array())
|
||||
{
|
||||
return $this->renderSection($view, 'widget', $variables);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function renderErrors(FormView $view)
|
||||
{
|
||||
return $this->renderSection($view, 'errors');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function renderLabel(FormView $view, $label = null, array $variables = array())
|
||||
{
|
||||
if ($label !== null) {
|
||||
$variables += array('label' => $label);
|
||||
}
|
||||
|
||||
return $this->renderSection($view, 'label', $variables);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@ -141,18 +89,18 @@ class FormRenderer implements FormRendererInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function renderBlock($block, array $variables = array())
|
||||
public function renderBlock(FormView $view, $blockName, array $variables = array())
|
||||
{
|
||||
if (0 == count($this->stack)) {
|
||||
if (0 == count($this->variableStack)) {
|
||||
throw new FormException('This method should only be called while rendering a form element.');
|
||||
}
|
||||
|
||||
list($view, $scopeVariables) = end($this->stack);
|
||||
$scopeVariables = end($this->variableStack);
|
||||
|
||||
$resource = $this->engine->getResourceForBlock($view, $block);
|
||||
$resource = $this->engine->getResourceForBlockName($view, $blockName);
|
||||
|
||||
if (!$resource) {
|
||||
throw new FormException(sprintf('No block "%s" found while rendering the form.', $block));
|
||||
throw new FormException(sprintf('No block "%s" found while rendering the form.', $blockName));
|
||||
}
|
||||
|
||||
// Merge the passed with the existing attributes
|
||||
@ -169,38 +117,30 @@ class FormRenderer implements FormRendererInterface
|
||||
// cannot be overwritten
|
||||
$variables = array_replace($scopeVariables, $variables);
|
||||
|
||||
return $this->engine->renderBlock($view, $resource, $block, $variables);
|
||||
$this->variableStack[] = $variables;
|
||||
|
||||
// Do the rendering
|
||||
$html = $this->engine->renderBlock($view, $resource, $blockName, $variables);
|
||||
|
||||
// Clear the stack
|
||||
array_pop($this->variableStack);
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function humanize($text)
|
||||
public function searchAndRenderBlock(FormView $view, $blockNameSuffix, array $variables = array())
|
||||
{
|
||||
return ucfirst(trim(strtolower(preg_replace('/[_\s]+/', ' ', $text))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the given section of a form view.
|
||||
*
|
||||
* @param FormView $view The form view.
|
||||
* @param string $section The name of the section to render.
|
||||
* @param array $variables The variables to pass to the template.
|
||||
*
|
||||
* @return string The HTML markup.
|
||||
*
|
||||
* @throws Exception\FormException If no fitting template was found.
|
||||
*/
|
||||
protected function renderSection(FormView $view, $section, array $variables = array())
|
||||
{
|
||||
$renderOnlyOnce = in_array($section, array('row', 'widget'));
|
||||
$renderOnlyOnce = in_array($blockNameSuffix, array('row', 'widget'));
|
||||
|
||||
if ($renderOnlyOnce && $view->isRendered()) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// The cache key for storing the variables and types
|
||||
$mapKey = $uniqueBlockName = $view->vars['full_block_name'] . '_' . $section;
|
||||
$mapKey = $uniqueBlockName = $view->vars['full_block_name'] . '_' . $blockNameSuffix;
|
||||
|
||||
// In templates, we have to deal with two kinds of block hierarchies:
|
||||
//
|
||||
@ -229,16 +169,16 @@ class FormRenderer implements FormRendererInterface
|
||||
// widget() function again to render the block for the parent type.
|
||||
//
|
||||
// The second kind is implemented in the following blocks.
|
||||
if (!isset($this->blockHierarchyMap[$mapKey])) {
|
||||
if (!isset($this->blockNameHierarchyMap[$mapKey])) {
|
||||
// INITIAL CALL
|
||||
// Calculate the hierarchy of template blocks and start on
|
||||
// the bottom level of the hierarchy (= "_<id>_<section>" block)
|
||||
$blockHierarchy = array();
|
||||
$blockNameHierarchy = array();
|
||||
foreach ($view->vars['types'] as $type) {
|
||||
$blockHierarchy[] = $type . '_' . $section;
|
||||
$blockNameHierarchy[] = $type . '_' . $blockNameSuffix;
|
||||
}
|
||||
$blockHierarchy[] = $uniqueBlockName;
|
||||
$hierarchyLevel = count($blockHierarchy) - 1;
|
||||
$blockNameHierarchy[] = $uniqueBlockName;
|
||||
$hierarchyLevel = count($blockNameHierarchy) - 1;
|
||||
|
||||
// The default variable scope contains all view variables, merged with
|
||||
// the variables passed explicitly to the helper
|
||||
@ -247,7 +187,7 @@ class FormRenderer implements FormRendererInterface
|
||||
// RECURSIVE CALL
|
||||
// If a block recursively calls renderSection() again, resume rendering
|
||||
// using the parent type in the hierarchy.
|
||||
$blockHierarchy = $this->blockHierarchyMap[$mapKey];
|
||||
$blockNameHierarchy = $this->blockNameHierarchyMap[$mapKey];
|
||||
$hierarchyLevel = $this->hierarchyLevelMap[$mapKey] - 1;
|
||||
|
||||
// Reuse the current scope and merge it with the explicitly passed variables
|
||||
@ -255,22 +195,22 @@ class FormRenderer implements FormRendererInterface
|
||||
}
|
||||
|
||||
// Load the resource where this block can be found
|
||||
$resource = $this->engine->getResourceForBlockHierarchy($view, $blockHierarchy, $hierarchyLevel);
|
||||
$resource = $this->engine->getResourceForBlockNameHierarchy($view, $blockNameHierarchy, $hierarchyLevel);
|
||||
|
||||
// Update the current hierarchy level to the one at which the resource was
|
||||
// found. For example, if looking for "choice_widget", but only a resource
|
||||
// is found for its parent "form_widget", then the level is updated here
|
||||
// to the parent level.
|
||||
$hierarchyLevel = $this->engine->getResourceHierarchyLevel($view, $blockHierarchy, $hierarchyLevel);
|
||||
$hierarchyLevel = $this->engine->getResourceHierarchyLevel($view, $blockNameHierarchy, $hierarchyLevel);
|
||||
|
||||
// The actually existing block name in $resource
|
||||
$block = $blockHierarchy[$hierarchyLevel];
|
||||
$blockName = $blockNameHierarchy[$hierarchyLevel];
|
||||
|
||||
// Escape if no resource exists for this block
|
||||
if (!$resource) {
|
||||
throw new FormException(sprintf(
|
||||
'Unable to render the form as none of the following blocks exist: "%s".',
|
||||
implode('", "', array_reverse($blockHierarchy))
|
||||
implode('", "', array_reverse($blockNameHierarchy))
|
||||
));
|
||||
}
|
||||
|
||||
@ -295,7 +235,7 @@ class FormRenderer implements FormRendererInterface
|
||||
// We need to store these values in maps (associative arrays) because within a
|
||||
// call to widget() another call to widget() can be made, but for a different view
|
||||
// object. These nested calls should not override each other.
|
||||
$this->blockHierarchyMap[$mapKey] = $blockHierarchy;
|
||||
$this->blockNameHierarchyMap[$mapKey] = $blockNameHierarchy;
|
||||
$this->hierarchyLevelMap[$mapKey] = $hierarchyLevel;
|
||||
$this->variableMap[$mapKey] = $variables;
|
||||
|
||||
@ -305,16 +245,16 @@ class FormRenderer implements FormRendererInterface
|
||||
//
|
||||
// A stack is sufficient for this purpose, because renderBlock() always accesses
|
||||
// the immediate next outer scope, which is always stored at the end of the stack.
|
||||
$this->stack[] = array($view, $variables);
|
||||
$this->variableStack[] = $variables;
|
||||
|
||||
// Do the rendering
|
||||
$html = $this->engine->renderBlock($view, $resource, $block, $variables);
|
||||
$html = $this->engine->renderBlock($view, $resource, $blockName, $variables);
|
||||
|
||||
// Clear the stack
|
||||
array_pop($this->stack);
|
||||
array_pop($this->variableStack);
|
||||
|
||||
// Clear the maps
|
||||
unset($this->blockHierarchyMap[$mapKey]);
|
||||
unset($this->blockNameHierarchyMap[$mapKey]);
|
||||
unset($this->hierarchyLevelMap[$mapKey]);
|
||||
unset($this->variableMap[$mapKey]);
|
||||
|
||||
@ -324,4 +264,12 @@ class FormRenderer implements FormRendererInterface
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function humanize($text)
|
||||
{
|
||||
return ucfirst(trim(strtolower(preg_replace('/[_\s]+/', ' ', $text))));
|
||||
}
|
||||
}
|
||||
|
@ -40,11 +40,11 @@ interface FormRendererEngineInterface
|
||||
* First the themes attached directly to the
|
||||
* view with {@link setTheme()} are considered,
|
||||
* then the ones of its parent etc.
|
||||
* @param string $block The name of the block to render.
|
||||
* @param string $blockName The name of the block to render.
|
||||
*
|
||||
* @return mixed The renderer resource or false, if none was found.
|
||||
*/
|
||||
public function getResourceForBlock(FormView $view, $block);
|
||||
public function getResourceForBlockName(FormView $view, $blockName);
|
||||
|
||||
/**
|
||||
* Returns the resource for a block hierarchy.
|
||||
@ -70,21 +70,23 @@ interface FormRendererEngineInterface
|
||||
* The type of the resource is decided by the implementation. The resource
|
||||
* is later passed to {@link renderBlock()} by the rendering algorithm.
|
||||
*
|
||||
* @param FormView $view The view for determining the used
|
||||
* themes. First the themes attached
|
||||
* directly to the view with
|
||||
* {@link setTheme()} are considered,
|
||||
* then the ones of its parent etc.
|
||||
* @param array $blockHierarchy The block name hierarchy, with
|
||||
* @param FormView $view The view for determining the
|
||||
* used themes. First the themes
|
||||
* attached directly to the view
|
||||
* with {@link setTheme()} are
|
||||
* considered, then the ones of
|
||||
* its parent etc.
|
||||
* @param array $blockNameHierarchy The block name hierarchy, with
|
||||
* the root block at the beginning.
|
||||
* @param integer $hierarchyLevel The level in the hierarchy at
|
||||
* which to start looking. Level 0
|
||||
* indicates the root block, i.e.
|
||||
* the first element of $blockHierarchy.
|
||||
* the first element of
|
||||
* $blockNameHierarchy.
|
||||
*
|
||||
* @return mixed The renderer resource or false, if none was found.
|
||||
*/
|
||||
public function getResourceForBlockHierarchy(FormView $view, array $blockHierarchy, $hierarchyLevel);
|
||||
public function getResourceForBlockNameHierarchy(FormView $view, array $blockNameHierarchy, $hierarchyLevel);
|
||||
|
||||
/**
|
||||
* Returns the hierarchy level at which a resource can be found.
|
||||
@ -112,21 +114,23 @@ interface FormRendererEngineInterface
|
||||
* The type of the resource is decided by the implementation. The resource
|
||||
* is later passed to {@link renderBlock()} by the rendering algorithm.
|
||||
*
|
||||
* @param FormView $view The view for determining the used
|
||||
* themes. First the themes attached
|
||||
* directly to the view with
|
||||
* {@link setTheme()} are considered,
|
||||
* then the ones of its parent etc.
|
||||
* @param array $blockHierarchy The block name hierarchy, with
|
||||
* @param FormView $view The view for determining the
|
||||
* used themes. First the themes
|
||||
* attached directly to the view
|
||||
* with {@link setTheme()} are
|
||||
* considered, then the ones of
|
||||
* its parent etc.
|
||||
* @param array $blockNameHierarchy The block name hierarchy, with
|
||||
* the root block at the beginning.
|
||||
* @param integer $hierarchyLevel The level in the hierarchy at
|
||||
* which to start looking. Level 0
|
||||
* indicates the root block, i.e.
|
||||
* the first element of $blockHierarchy.
|
||||
* the first element of
|
||||
* $blockNameHierarchy.
|
||||
*
|
||||
* @return integer|Boolean The hierarchy level or false, if no resource was found.
|
||||
*/
|
||||
public function getResourceHierarchyLevel(FormView $view, array $blockHierarchy, $hierarchyLevel);
|
||||
public function getResourceHierarchyLevel(FormView $view, array $blockNameHierarchy, $hierarchyLevel);
|
||||
|
||||
/**
|
||||
* Renders a block in the given renderer resource.
|
||||
@ -137,10 +141,10 @@ interface FormRendererEngineInterface
|
||||
*
|
||||
* @param FormView $view The view to render.
|
||||
* @param mixed $resource The renderer resource.
|
||||
* @param string $block The name of the block to render.
|
||||
* @param string $blockName The name of the block to render.
|
||||
* @param array $variables The variables to pass to the template.
|
||||
*
|
||||
* @return string The HTML markup.
|
||||
*/
|
||||
public function renderBlock(FormView $view, $resource, $block, array $variables = array());
|
||||
public function renderBlock(FormView $view, $resource, $blockName, array $variables = array());
|
||||
}
|
||||
|
@ -36,90 +36,34 @@ interface FormRendererInterface
|
||||
*/
|
||||
public function setTheme(FormView $view, $themes);
|
||||
|
||||
/**
|
||||
* Renders the HTML enctype in the form tag, if necessary.
|
||||
*
|
||||
* Example usage templates:
|
||||
*
|
||||
* <form action="..." method="post" <?php echo $renderer->renderEnctype($form) ?>>
|
||||
*
|
||||
* @param FormView $view The view for which to render the encoding type
|
||||
*
|
||||
* @return string The HTML markup
|
||||
*/
|
||||
public function renderEnctype(FormView $view);
|
||||
|
||||
/**
|
||||
* Renders the entire row for a form field.
|
||||
*
|
||||
* A row typically contains the label, errors and widget of a field.
|
||||
*
|
||||
* @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 renderRow(FormView $view, array $variables = array());
|
||||
|
||||
/**
|
||||
* 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 renderRest(FormView $view, array $variables = array());
|
||||
|
||||
/**
|
||||
* Renders the HTML for a given view.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* <?php echo $renderer->renderWidget($form) ?>
|
||||
*
|
||||
* You can pass options during the call:
|
||||
*
|
||||
* <?php echo $renderer->renderWidget($form, array('attr' => array('class' => 'foo'))) ?>
|
||||
*
|
||||
* <?php echo $renderer->renderWidget($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 renderWidget(FormView $view, array $variables = array());
|
||||
|
||||
/**
|
||||
* Renders the errors of the given view.
|
||||
*
|
||||
* @param FormView $view The view to render the errors for
|
||||
*
|
||||
* @return string The HTML markup
|
||||
*/
|
||||
public function renderErrors(FormView $view);
|
||||
|
||||
/**
|
||||
* 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 renderLabel(FormView $view, $label = null, array $variables = array());
|
||||
|
||||
/**
|
||||
* Renders a named block of the form theme.
|
||||
*
|
||||
* @param string $block The name of the block.
|
||||
* @param FormView $view The view for which to render the block.
|
||||
* @param string $blockName The name of the block.
|
||||
* @param array $variables The variables to pass to the template.
|
||||
*
|
||||
* @return string The HTML markup
|
||||
*/
|
||||
public function renderBlock($block, array $variables = array());
|
||||
public function renderBlock(FormView $view, $blockName, array $variables = array());
|
||||
|
||||
/**
|
||||
* Searches and renders a block for a given name suffix.
|
||||
*
|
||||
* The block is searched by combining the block names stored in the
|
||||
* form view with the given suffix. If a block name is found, that
|
||||
* block is rendered.
|
||||
*
|
||||
* If this method is called recursively, the block search is continued
|
||||
* where a block was found before.
|
||||
*
|
||||
* @param FormView $view The view for which to render the block.
|
||||
* @param string $blockNameSuffix The suffix of the block name.
|
||||
* @param array $variables The variables to pass to the template.
|
||||
*
|
||||
* @return string The HTML markup
|
||||
*/
|
||||
public function searchAndRenderBlock(FormView $view, $blockNameSuffix, array $variables = array());
|
||||
|
||||
/**
|
||||
* Renders a CSRF token.
|
||||
|
Reference in New Issue
Block a user