|
@@ -26,8 +26,6 @@ use Symfony\Bundle\TwigBundle\TokenParser\FormThemeTokenParser;
|
|
|
*/
|
|
|
class FormExtension extends \Twig_Extension
|
|
|
{
|
|
|
- static protected $cache = array();
|
|
|
-
|
|
|
protected $resources;
|
|
|
protected $templates;
|
|
|
protected $environment;
|
|
@@ -47,9 +45,15 @@ class FormExtension extends \Twig_Extension
|
|
|
$this->environment = $environment;
|
|
|
}
|
|
|
|
|
|
- public function setTheme(FormInterface $group, array $resources)
|
|
|
+ /**
|
|
|
+ * Sets a theme for a given field.
|
|
|
+ *
|
|
|
+ * @param FieldInterface $field A FieldInterface instance
|
|
|
+ * @param array $resources An array of resources
|
|
|
+ */
|
|
|
+ public function setTheme(FieldInterface $field, array $resources)
|
|
|
{
|
|
|
- $this->themes->attach($group, $resources);
|
|
|
+ $this->themes->attach($field, $resources);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -99,11 +103,7 @@ class FormExtension extends \Twig_Extension
|
|
|
*/
|
|
|
public function renderRow(FieldInterface $field)
|
|
|
{
|
|
|
- if (null === $this->templates) {
|
|
|
- $this->templates = $this->resolveResources($this->resources);
|
|
|
- }
|
|
|
-
|
|
|
- return $this->templates['field_row']->renderBlock('field_row', array(
|
|
|
+ return $this->render($field, 'field_row', array(
|
|
|
'child' => $field,
|
|
|
));
|
|
|
}
|
|
@@ -129,31 +129,11 @@ class FormExtension extends \Twig_Extension
|
|
|
*/
|
|
|
public function renderField(FieldInterface $field, array $attributes = array(), array $parameters = array(), $resources = null)
|
|
|
{
|
|
|
- if (null === $this->templates) {
|
|
|
- $this->templates = $this->resolveResources($this->resources);
|
|
|
- }
|
|
|
-
|
|
|
- if (null !== $resources) {
|
|
|
- // The developer provided a custom theme in the filter call
|
|
|
- $resources = array($resources);
|
|
|
- } else {
|
|
|
- // The default theme is used
|
|
|
- $parent = $field;
|
|
|
- $resources = array();
|
|
|
- while ($parent = $parent->getParent()) {
|
|
|
- if (isset($this->themes[$parent])) {
|
|
|
- $resources = $this->themes[$parent];
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- list($widget, $template) = $this->getWidget($field, $resources);
|
|
|
-
|
|
|
- return $template->renderBlock($widget, array(
|
|
|
+ return $this->render($field, 'field', array(
|
|
|
'field' => $field,
|
|
|
'attr' => $attributes,
|
|
|
'params' => $parameters,
|
|
|
- ));
|
|
|
+ ), $resources);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -165,11 +145,7 @@ class FormExtension extends \Twig_Extension
|
|
|
*/
|
|
|
public function renderHidden(FormInterface $group, array $parameters = array())
|
|
|
{
|
|
|
- if (null === $this->templates) {
|
|
|
- $this->templates = $this->resolveResources($this->resources);
|
|
|
- }
|
|
|
-
|
|
|
- return $this->templates['hidden']->renderBlock('hidden', array(
|
|
|
+ return $this->render($group, 'hidden', array(
|
|
|
'field' => $group,
|
|
|
'params' => $parameters,
|
|
|
));
|
|
@@ -183,11 +159,7 @@ class FormExtension extends \Twig_Extension
|
|
|
*/
|
|
|
public function renderErrors(FieldInterface $field, array $parameters = array())
|
|
|
{
|
|
|
- if (null === $this->templates) {
|
|
|
- $this->templates = $this->resolveResources($this->resources);
|
|
|
- }
|
|
|
-
|
|
|
- return $this->templates['errors']->renderBlock('errors', array(
|
|
|
+ return $this->render($field, 'errors', array(
|
|
|
'field' => $field,
|
|
|
'params' => $parameters,
|
|
|
));
|
|
@@ -201,11 +173,7 @@ class FormExtension extends \Twig_Extension
|
|
|
*/
|
|
|
public function renderLabel(FieldInterface $field, $label = null, array $parameters = array())
|
|
|
{
|
|
|
- if (null === $this->templates) {
|
|
|
- $this->templates = $this->resolveResources($this->resources);
|
|
|
- }
|
|
|
-
|
|
|
- return $this->templates['label']->renderBlock('label', array(
|
|
|
+ return $this->render($field, 'label', array(
|
|
|
'field' => $field,
|
|
|
'params' => $parameters,
|
|
|
'label' => null !== $label ? $label : ucfirst(strtolower(str_replace('_', ' ', $field->getKey()))),
|
|
@@ -222,28 +190,26 @@ class FormExtension extends \Twig_Extension
|
|
|
return $field->getData();
|
|
|
}
|
|
|
|
|
|
+ protected function render(FieldInterface $field, $name, array $arguments, $resources = null)
|
|
|
+ {
|
|
|
+ if ('field' === $name) {
|
|
|
+ list($name, $template) = $this->getWidget($field, $resources);
|
|
|
+ } else {
|
|
|
+ $template = $this->getTemplate($field, $name);
|
|
|
+ }
|
|
|
+
|
|
|
+ return $template->renderBlock($name, $arguments);
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* @param FieldInterface $field The field to get the widget for
|
|
|
* @param array $resources An array of template resources
|
|
|
* @return array
|
|
|
*/
|
|
|
- protected function getWidget(FieldInterface $field, array $resources = array())
|
|
|
+ protected function getWidget(FieldInterface $field, array $resources = null)
|
|
|
{
|
|
|
- $cacheable = true;
|
|
|
- $templates = array();
|
|
|
- if ($resources) {
|
|
|
- $templates = $this->resolveResources($resources);
|
|
|
- $cacheable = false;
|
|
|
- }
|
|
|
-
|
|
|
- // add "global" templates as fallback
|
|
|
- $templates = array_merge($this->templates, $templates);
|
|
|
-
|
|
|
$class = get_class($field);
|
|
|
-
|
|
|
- if (true === $cacheable && isset(self::$cache[$class])) {
|
|
|
- return self::$cache[$class];
|
|
|
- }
|
|
|
+ $templates = $this->getTemplates($field, $resources);
|
|
|
|
|
|
// find a template for the given class or one of its parents
|
|
|
do {
|
|
@@ -254,10 +220,6 @@ class FormExtension extends \Twig_Extension
|
|
|
$underscore = strtolower(preg_replace(array('/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'), array('\\1_\\2', '\\1_\\2'), strtr($c, '_', '.')));
|
|
|
|
|
|
if (isset($templates[$underscore])) {
|
|
|
- if (true === $cacheable) {
|
|
|
- self::$cache[$class] = array($underscore, $templates[$underscore]);
|
|
|
- }
|
|
|
-
|
|
|
return array($underscore, $templates[$underscore]);
|
|
|
}
|
|
|
} while (false !== $class = get_parent_class($class));
|
|
@@ -265,16 +227,45 @@ class FormExtension extends \Twig_Extension
|
|
|
throw new \RuntimeException(sprintf('Unable to render the "%s" field.', $field->getKey()));
|
|
|
}
|
|
|
|
|
|
- protected function resolveResources(array $resources)
|
|
|
+ protected function getTemplate(FieldInterface $field, $name, array $resources = null)
|
|
|
{
|
|
|
+ $templates = $this->getTemplates($field, $resources);
|
|
|
+
|
|
|
+ return $templates[$name];
|
|
|
+ }
|
|
|
+
|
|
|
+ protected function getTemplates(FieldInterface $field, array $resources = null)
|
|
|
+ {
|
|
|
+ // templates are looked for in the following resources:
|
|
|
+ // * resources provided directly into the function call
|
|
|
+ // * resources from the themes (and its parents)
|
|
|
+ // * default resources
|
|
|
+
|
|
|
+ // defaults
|
|
|
+ $all = $this->resources;
|
|
|
+
|
|
|
+ // themes
|
|
|
+ $parent = $field;
|
|
|
+ while ($parent = $parent->getParent()) {
|
|
|
+ if (isset($this->themes[$parent])) {
|
|
|
+ $all = array_merge($all, $this->themes[$parent]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // local
|
|
|
+ $all = array_merge($all, null !== $resources ? (array) $resources : array());
|
|
|
+
|
|
|
$templates = array();
|
|
|
- foreach ($resources as $resource)
|
|
|
- {
|
|
|
+ foreach ($all as $resource) {
|
|
|
if (!$resource instanceof \Twig_Template) {
|
|
|
$resource = $this->environment->loadTemplate($resource);
|
|
|
}
|
|
|
|
|
|
- $blocks = $this->resolveTemplate($resource);
|
|
|
+ // an array of blockName => template
|
|
|
+ $blocks = array();
|
|
|
+ foreach ($resource->getBlockNames() as $name) {
|
|
|
+ $blocks[$name] = $resource;
|
|
|
+ }
|
|
|
|
|
|
$templates = array_replace($templates, $blocks);
|
|
|
}
|
|
@@ -282,17 +273,6 @@ class FormExtension extends \Twig_Extension
|
|
|
return $templates;
|
|
|
}
|
|
|
|
|
|
- protected function resolveTemplate($template)
|
|
|
- {
|
|
|
- // an array of blockName => template
|
|
|
- $blocks = array();
|
|
|
- foreach ($template->getBlockNames() as $name) {
|
|
|
- $blocks[$name] = $template;
|
|
|
- }
|
|
|
-
|
|
|
- return $blocks;
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
* Returns the name of the extension.
|
|
|
*
|