From 8fbf19694f253e8bacdd677362ee58967506bbb3 Mon Sep 17 00:00:00 2001 From: "Jonathan H. Wage" Date: Sat, 2 Oct 2010 16:43:30 -0500 Subject: [PATCH 01/10] Adding orm: and mongodb: annotation aliases to avoid conflicts. Recommended is to use the aliases instead of relying on the default namespace for annotations. /** @orm:Entity */ /** @mongodb:Document */ --- src/Symfony/Bundle/DoctrineBundle/Resources/config/orm.xml | 5 +++++ .../DoctrineMongoDBBundle/Resources/config/mongodb.xml | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/src/Symfony/Bundle/DoctrineBundle/Resources/config/orm.xml b/src/Symfony/Bundle/DoctrineBundle/Resources/config/orm.xml index f86804b4901b2..a8227fd750ffc 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Resources/config/orm.xml +++ b/src/Symfony/Bundle/DoctrineBundle/Resources/config/orm.xml @@ -45,6 +45,11 @@ %doctrine.orm.metadata_driver.entity_dirs% + %doctrine.orm.metadata.annotation_default_namespace% + + Doctrine\ORM\Mapping\ + orm + diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Resources/config/mongodb.xml b/src/Symfony/Bundle/DoctrineMongoDBBundle/Resources/config/mongodb.xml index fa41a2ce50756..c2f718b54e5ba 100755 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Resources/config/mongodb.xml +++ b/src/Symfony/Bundle/DoctrineMongoDBBundle/Resources/config/mongodb.xml @@ -57,6 +57,10 @@ %doctrine.odm.mongodb.metadata.annotation_default_namespace% + + Doctrine\ODM\MongoDB\Mapping\ + mongodb + %doctrine.odm.mongodb.xml_mapping_dirs% %doctrine.odm.mongodb.yml_mapping_dirs% From e88c0b7fc5a20bb768ca22552959e0b96490044a Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 3 Oct 2010 07:34:56 +0200 Subject: [PATCH 02/10] [DoctrineBundle] fixed previous commit --- src/Symfony/Bundle/DoctrineBundle/Resources/config/orm.xml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Bundle/DoctrineBundle/Resources/config/orm.xml b/src/Symfony/Bundle/DoctrineBundle/Resources/config/orm.xml index a8227fd750ffc..e4e43730dbc4a 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Resources/config/orm.xml +++ b/src/Symfony/Bundle/DoctrineBundle/Resources/config/orm.xml @@ -45,6 +45,9 @@ %doctrine.orm.metadata_driver.entity_dirs% + + + %doctrine.orm.metadata.annotation_default_namespace% Doctrine\ORM\Mapping\ @@ -52,10 +55,6 @@ - - Doctrine\ORM\Mapping\ - - %doctrine.orm.metadata_driver.mapping_dirs% From c2f856f074352cbcc6534a137c5d4bb754f1a8f3 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 4 Oct 2010 14:01:33 +0200 Subject: [PATCH 03/10] [FrameworkBundle] fixed comment --- src/Symfony/Bundle/FrameworkBundle/Templating/Engine.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Templating/Engine.php b/src/Symfony/Bundle/FrameworkBundle/Templating/Engine.php index ded9f577c80ee..63707a3abf169 100755 --- a/src/Symfony/Bundle/FrameworkBundle/Templating/Engine.php +++ b/src/Symfony/Bundle/FrameworkBundle/Templating/Engine.php @@ -137,7 +137,7 @@ protected function escapeParameters(array $parameters) } // parses template names following the following pattern: - // bundle:section:template(.format)(.renderer) + // bundle:section:template(.format).renderer public function splitTemplateName($name, array $defaults = array()) { $parts = explode(':', $name); From a38069288ce2f5d37237196531200d7a7cd291cf Mon Sep 17 00:00:00 2001 From: ornicar Date: Mon, 4 Oct 2010 12:09:20 +0200 Subject: [PATCH 04/10] Fix namespace collision --- src/Symfony/Bundle/FrameworkBundle/Client.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Client.php b/src/Symfony/Bundle/FrameworkBundle/Client.php index 27c68b2e6a7d8..d86217acdf91a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Client.php +++ b/src/Symfony/Bundle/FrameworkBundle/Client.php @@ -7,7 +7,7 @@ use Symfony\Component\HttpKernel\Client as BaseClient; use Symfony\Component\BrowserKit\History; use Symfony\Component\BrowserKit\CookieJar; -use Symfony\Component\HttpKernel\Profiler\Profiler; +use Symfony\Component\HttpKernel\Profiler\Profiler as HttpProfiler; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -67,7 +67,7 @@ public function getKernel() /** * Gets a profiler for the current Response. * - * @return Profiler A Profiler instance + * @return HttpProfiler A Profiler instance */ public function getProfiler() { From 2525998f6e47299438ccf07e6c5c92b4755f66a5 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Thu, 9 Sep 2010 12:14:06 +0200 Subject: [PATCH 05/10] replaced form field rendering with plain templates Documentation available here: http://docs.symfony-reloaded.org/master/guides/form/ --- .../Resources/config/templating.xml | 9 + .../Resources/views/Form/errors.php | 7 + .../views/Form/group/div/field_group.php | 9 + .../Resources/views/Form/group/div/row.php | 5 + .../views/Form/group/table/field_group.php | 9 + .../Resources/views/Form/group/table/row.php | 9 + .../Resources/views/Form/hidden.php | 3 + .../Resources/views/Form/label.php | 1 + .../views/Form/widget/choice_field.php | 9 + .../views/Form/widget/date_field.php | 9 + .../views/Form/widget/date_time_field.php | 2 + .../views/Form/widget/input_field.php | 1 + .../views/Form/widget/money_field.php | 6 + .../views/Form/widget/percent_field.php | 6 + .../views/Form/widget/textarea_field.php | 1 + .../views/Form/widget/time_field.php | 9 + .../views/Form/widget/toggle_field.php | 11 + .../Templating/Form/BaseField.php | 132 +++++++++ .../FrameworkBundle/Templating/Form/Field.php | 104 +++++++ .../Templating/Form/FieldGroup.php | 75 +++++ .../Templating/Form/FieldInterface.php | 22 ++ .../FrameworkBundle/Templating/Form/Form.php | 44 +++ .../Templating}/HtmlGenerator.php | 48 ++- .../Templating}/HtmlGeneratorInterface.php | 2 +- .../DependencyInjection/TwigExtension.php | 11 + .../TwigBundle/Extension/FormExtension.php | 240 +++++++++++++++ .../TwigBundle/Extension/HtmlExtension.php | 62 ++++ .../Bundle/TwigBundle/Node/FormThemeNode.php | 49 +++ .../Bundle/TwigBundle/Node/HelperNode.php | 8 +- .../Bundle/TwigBundle/Node/TagNode.php | 62 ++++ .../Resources/config/schema/twig-1.0.xsd | 28 +- .../TwigBundle/Resources/config/twig.xml | 12 + .../TwigBundle/Resources/views/form.twig | 41 +++ .../TwigBundle/Resources/views/widgets.twig | 57 ++++ .../TokenParser/ContentTagTokenParser.php | 66 +++++ .../TokenParser/FormThemeTokenParser.php | 55 ++++ .../TwigBundle/TokenParser/TagTokenParser.php | 57 ++++ src/Symfony/Component/Form/CheckboxField.php | 6 +- src/Symfony/Component/Form/ChoiceField.php | 135 +++------ src/Symfony/Component/Form/Configurable.php | 5 + src/Symfony/Component/Form/DateField.php | 62 ++-- src/Symfony/Component/Form/DateTimeField.php | 11 - src/Symfony/Component/Form/Field.php | 93 +----- src/Symfony/Component/Form/FieldGroup.php | 119 +------- src/Symfony/Component/Form/FieldInterface.php | 30 +- src/Symfony/Component/Form/FileField.php | 6 +- src/Symfony/Component/Form/Form.php | 84 +----- src/Symfony/Component/Form/HiddenField.php | 8 +- src/Symfony/Component/Form/HybridField.php | 15 + src/Symfony/Component/Form/InputField.php | 14 +- src/Symfony/Component/Form/MoneyField.php | 44 +-- src/Symfony/Component/Form/NumberField.php | 6 +- src/Symfony/Component/Form/PasswordField.php | 6 +- src/Symfony/Component/Form/PercentField.php | 8 - src/Symfony/Component/Form/RadioField.php | 6 +- .../Component/Form/Renderer/Renderer.php | 88 ------ .../Form/Renderer/RendererInterface.php | 45 --- .../Component/Form/Renderer/TableRenderer.php | 52 ---- src/Symfony/Component/Form/TextField.php | 6 +- src/Symfony/Component/Form/TextareaField.php | 8 +- src/Symfony/Component/Form/TimeField.php | 22 +- src/Symfony/Component/Form/ToggleField.php | 23 +- src/Symfony/Component/Form/Translatable.php | 20 -- .../Component/I18N/TranslatorInterface.php | 22 -- .../Component/Form/CheckboxFieldTest.php | 20 -- .../Tests/Component/Form/ChoiceFieldTest.php | 278 ------------------ .../Tests/Component/Form/DateFieldTest.php | 115 -------- .../Component/Form/DateTimeFieldTest.php | 46 --- .../Tests/Component/Form/FieldGroupTest.php | 179 +---------- .../Symfony/Tests/Component/Form/FormTest.php | 42 --- .../Tests/Component/Form/HiddenFieldTest.php | 11 - .../Component/Form/HtmlGeneratorTest.php | 91 ------ .../Tests/Component/Form/InputFieldTest.php | 33 --- .../Tests/Component/Form/MoneyFieldTest.php | 46 --- .../Tests/Component/Form/NumberFieldTest.php | 46 --- .../Component/Form/PasswordFieldTest.php | 49 --- .../Tests/Component/Form/PercentFieldTest.php | 46 --- .../Tests/Component/Form/RadioFieldTest.php | 33 --- .../Form/Renderer/RendererTestCase.php | 23 -- .../Tests/Component/Form/TextFieldTest.php | 28 -- .../Component/Form/TextareaFieldTest.php | 28 -- .../Tests/Component/Form/TimeFieldTest.php | 124 -------- .../Tests/Component/Form/ToggleFieldTest.php | 67 ----- 83 files changed, 1456 insertions(+), 2074 deletions(-) create mode 100644 src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/errors.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/group/div/field_group.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/group/div/row.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/group/table/field_group.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/group/table/row.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/hidden.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/label.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget/choice_field.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget/date_field.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget/date_time_field.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget/input_field.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget/money_field.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget/percent_field.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget/textarea_field.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget/time_field.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget/toggle_field.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Templating/Form/BaseField.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Templating/Form/Field.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Templating/Form/FieldGroup.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Templating/Form/FieldInterface.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Templating/Form/Form.php rename src/Symfony/{Component/Form => Bundle/FrameworkBundle/Templating}/HtmlGenerator.php (67%) rename src/Symfony/{Component/Form => Bundle/FrameworkBundle/Templating}/HtmlGeneratorInterface.php (97%) create mode 100644 src/Symfony/Bundle/TwigBundle/Extension/FormExtension.php create mode 100644 src/Symfony/Bundle/TwigBundle/Extension/HtmlExtension.php create mode 100644 src/Symfony/Bundle/TwigBundle/Node/FormThemeNode.php create mode 100644 src/Symfony/Bundle/TwigBundle/Node/TagNode.php create mode 100644 src/Symfony/Bundle/TwigBundle/Resources/views/form.twig create mode 100644 src/Symfony/Bundle/TwigBundle/Resources/views/widgets.twig create mode 100644 src/Symfony/Bundle/TwigBundle/TokenParser/ContentTagTokenParser.php create mode 100644 src/Symfony/Bundle/TwigBundle/TokenParser/FormThemeTokenParser.php create mode 100644 src/Symfony/Bundle/TwigBundle/TokenParser/TagTokenParser.php delete mode 100644 src/Symfony/Component/Form/Renderer/Renderer.php delete mode 100644 src/Symfony/Component/Form/Renderer/RendererInterface.php delete mode 100644 src/Symfony/Component/Form/Renderer/TableRenderer.php delete mode 100644 src/Symfony/Component/Form/Translatable.php delete mode 100644 src/Symfony/Component/I18N/TranslatorInterface.php delete mode 100644 tests/Symfony/Tests/Component/Form/CheckboxFieldTest.php delete mode 100644 tests/Symfony/Tests/Component/Form/HtmlGeneratorTest.php delete mode 100644 tests/Symfony/Tests/Component/Form/InputFieldTest.php delete mode 100644 tests/Symfony/Tests/Component/Form/MoneyFieldTest.php delete mode 100644 tests/Symfony/Tests/Component/Form/NumberFieldTest.php delete mode 100644 tests/Symfony/Tests/Component/Form/PasswordFieldTest.php delete mode 100644 tests/Symfony/Tests/Component/Form/PercentFieldTest.php delete mode 100644 tests/Symfony/Tests/Component/Form/RadioFieldTest.php delete mode 100644 tests/Symfony/Tests/Component/Form/Renderer/RendererTestCase.php delete mode 100644 tests/Symfony/Tests/Component/Form/TextFieldTest.php delete mode 100644 tests/Symfony/Tests/Component/Form/TextareaFieldTest.php delete mode 100644 tests/Symfony/Tests/Component/Form/ToggleFieldTest.php diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating.xml index 87bd3b3b5fca9..aefa0065ab1fc 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating.xml @@ -19,6 +19,8 @@ Symfony\Bundle\FrameworkBundle\Templating\Helper\SessionHelper Symfony\Bundle\FrameworkBundle\Templating\Helper\CodeHelper Symfony\Bundle\FrameworkBundle\Templating\Helper\TranslatorHelper + Symfony\Bundle\FrameworkBundle\Templating\Form\Form + Symfony\Bundle\FrameworkBundle\Templating\HtmlGenerator false null @@ -26,6 +28,8 @@ + + @@ -101,6 +105,11 @@ + + + + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/errors.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/errors.php new file mode 100644 index 0000000000000..9ade44ed9f029 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/errors.php @@ -0,0 +1,7 @@ + +
    + +
  • trans($error[0], $error[1], 'validators') ?>
  • + +
+ diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/group/div/field_group.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/group/div/field_group.php new file mode 100644 index 0000000000000..fce7c0c2605b8 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/group/div/field_group.php @@ -0,0 +1,9 @@ +errors() ?> + +
+ + render() ?> + +
+ +hidden() ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/group/div/row.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/group/div/row.php new file mode 100644 index 0000000000000..2960ecec7f2b0 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/group/div/row.php @@ -0,0 +1,5 @@ +
+ label() ?> + errors() ?> + field() ?> +
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/group/table/field_group.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/group/table/field_group.php new file mode 100644 index 0000000000000..f4eeba6ce8850 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/group/table/field_group.php @@ -0,0 +1,9 @@ +errors() ?> + + + + render() ?> + +
+ +hidden() ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/group/table/row.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/group/table/row.php new file mode 100644 index 0000000000000..8d42093f86b82 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/group/table/row.php @@ -0,0 +1,9 @@ + + + label() ?> + + + errors() ?> + widget() ?> + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/hidden.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/hidden.php new file mode 100644 index 0000000000000..8d53c09b7b8c8 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/hidden.php @@ -0,0 +1,3 @@ + + widget() ?> + diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/label.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/label.php new file mode 100644 index 0000000000000..d975823806b65 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/label.php @@ -0,0 +1 @@ + diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget/choice_field.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget/choice_field.php new file mode 100644 index 0000000000000..dd7cb72c56046 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget/choice_field.php @@ -0,0 +1,9 @@ +getOption('expanded')): ?> + + widget() ?> + + + contentTag('select', + $generator->choices($origin->getPreferredChoices(), $origin->getOtherChoices(), $origin->getEmptyValue(), $origin->getSelected()), + $attributes) ?> + diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget/date_field.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget/date_field.php new file mode 100644 index 0000000000000..4787cc8af7611 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget/date_field.php @@ -0,0 +1,9 @@ +isField()): ?> + tag('input', $attributes) ?> + + widget($attributes), + $field['month']->widget($attributes), + $field['day']->widget($attributes), + ), $origin->getPattern()) ?> + diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget/date_time_field.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget/date_time_field.php new file mode 100644 index 0000000000000..bc349b78fac5a --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget/date_time_field.php @@ -0,0 +1,2 @@ +widget($attributes) ?> +widget($attributes) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget/input_field.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget/input_field.php new file mode 100644 index 0000000000000..c425fcfa9f79c --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget/input_field.php @@ -0,0 +1 @@ +tag('input', $attributes) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget/money_field.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget/money_field.php new file mode 100644 index 0000000000000..9e55562f38e84 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget/money_field.php @@ -0,0 +1,6 @@ +render('FrameworkBundle:Form:widget/input_field.php', array( + 'field' => $field, + 'origin' => $origin, + 'attributes' => $attributes, + 'generator' => $generator, +)), $origin->getPattern()) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget/percent_field.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget/percent_field.php new file mode 100644 index 0000000000000..ecef83aa61677 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget/percent_field.php @@ -0,0 +1,6 @@ +render('FrameworkBundle:Form:widget/input_field.php', array( + 'field' => $field, + 'origin' => $origin, + 'attributes' => $attributes, + 'generator' => $generator, +)) ?> % diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget/textarea_field.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget/textarea_field.php new file mode 100644 index 0000000000000..ed5a9237c8669 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget/textarea_field.php @@ -0,0 +1 @@ +contentTag('textarea', $view->escape($field->getDisplayedData()), $attributes) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget/time_field.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget/time_field.php new file mode 100644 index 0000000000000..76cb2c2bb179d --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget/time_field.php @@ -0,0 +1,9 @@ +isField()): ?> + tag('input', $attributes) ?> + + widget($attributes).':'.$field['minute']->widget($attributes) ?> + + getOption('with_seconds')): ?> + widget($attributes) ?> + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget/toggle_field.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget/toggle_field.php new file mode 100644 index 0000000000000..373cd28cf47db --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget/toggle_field.php @@ -0,0 +1,11 @@ +render('FrameworkBundle:Form:widget/input_field.php', array( + 'field' => $field, + 'origin' => $origin, + 'attributes' => $attributes, + 'generator' => $generator, + )) +?> + +getOption('label')): ?> + contentTag('label', $view['translator']->trans($label), array('for' => $origin->getId())) ?> + diff --git a/src/Symfony/Bundle/FrameworkBundle/Templating/Form/BaseField.php b/src/Symfony/Bundle/FrameworkBundle/Templating/Form/BaseField.php new file mode 100644 index 0000000000000..076ea555c6780 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Templating/Form/BaseField.php @@ -0,0 +1,132 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +/** + * + * + * @author Fabien Potencier + */ +abstract class BaseField implements FieldInterface, SafeDecoratorInterface +{ + protected $engine; + protected $field; + protected $generator; + protected $theme; + protected $doctype; + + public function __construct(FormFieldInterface $field, Engine $engine, HtmlGeneratorInterface $generator, $theme, $doctype) + { + $this->field = $field; + $this->engine = $engine; + $this->generator = $generator; + $this->theme = $theme; + } + + public function getIterator() + { + if (!$this->field instanceof FieldGroupInterface) { + throw new \LogicException(sprintf('Cannot iterate a non group field (%s)', $this->field->getKey())); + } + + $fields = array(); + foreach ($this->field->getFields() as $field) { + if (!$field->isHidden()) { + $fields[] = $field; + } + } + + return new \ArrayIterator($this->wrapFields($fields)); + } + + /** + * Returns true if the bound field exists (implements the \ArrayAccess interface). + * + * @param string $key The key of the bound field + * + * @return Boolean true if the widget exists, false otherwise + */ + public function offsetExists($key) + { + if (!$this->field instanceof FieldGroupInterface) { + throw new \LogicException(sprintf('Cannot access a non group field as an array (%s)', $this->field->getKey())); + } + + return $this->field->has($key); + } + + /** + * Returns the form field associated with the name (implements the \ArrayAccess interface). + * + * @param string $key The offset of the value to get + * + * @return Field A form field instance + */ + public function offsetGet($key) + { + if (!$this->field instanceof FieldGroupInterface) { + throw new \LogicException(sprintf('Cannot access a non group field as an array (%s)', $this->field->getKey())); + } + + return $this->createField($this->field->get($key)); + } + + /** + * Throws an exception saying that values cannot be set (implements the \ArrayAccess interface). + * + * @param string $offset (ignored) + * @param string $value (ignored) + * + * @throws \LogicException + */ + public function offsetSet($key, $field) + { + throw new \LogicException('This helper is read-only'); + } + + /** + * Throws an exception saying that values cannot be unset (implements the \ArrayAccess interface). + * + * @param string $key + * + * @throws \LogicException + */ + public function offsetUnset($key) + { + throw new \LogicException('This helper is read-only'); + } + + protected function wrapFields($fields) + { + foreach ($fields as $id => $field) { + $fields[$id] = $this->createField($field); + } + + return $fields; + } + + protected function createField(FormFieldInterface $field) + { + if ($field instanceof Form || get_class($field) === 'Symfony\Component\Form\FieldGroup') { + return new FieldGroup($field, $this->engine, $this->generator, $this->theme, $this->doctype); + } + + return new Field($field, $this->engine, $this->generator, $this->theme, $this->doctype); + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Templating/Form/Field.php b/src/Symfony/Bundle/FrameworkBundle/Templating/Form/Field.php new file mode 100644 index 0000000000000..052ddce0b5224 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Templating/Form/Field.php @@ -0,0 +1,104 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +/** + * Field wraps a Form\FieldInterface instance. + * + * @author Fabien Potencier + */ +class Field extends BaseField +{ + static protected $cache = array(); + + public function render($template = null) + { + if ($this->field instanceof Form || get_class($this->field) === 'Symfony\Component\Form\FieldGroup') { + throw new \LogicException(sprintf('Cannot render a group field as a row (%s)', $this->field->getKey())); + } + + if (null === $template) { + $template = sprintf('FrameworkBundle:Form:group/%s/row.php', $this->theme); + } + + return $this->engine->render($template, array('field' => $this)); + } + + public function data() + { + return $this->field->getData(); + } + + public function widget(array $attributes = array(), $template = null) + { + if ($this->field instanceof Form || get_class($this->field) === 'Symfony\Component\Form\FieldGroup') { + throw new \LogicException(sprintf('Cannot render a group field (%s)', $this->field->getKey())); + } + + if (null === $template) { + $template = $this->getTemplate(); + } + + return $this->engine->render($template, array( + 'field' => $this, + 'origin' => $this->field, + 'attributes' => array_merge($this->field->getAttributes(), $attributes), + 'generator' => $this->generator, + )); + } + + public function label($label, $template = null) + { + if (null === $template) { + $template = 'FrameworkBundle:Form:label.php'; + } + + return $this->engine->render($template, array( + 'field' => $this, + 'id' => $this->field->getId(), + 'key' => $this->field->getKey(), + 'label' => $label ? $label : ucfirst(strtolower(str_replace('_', ' ', $this->field->getKey()))) + )); + } + + public function errors($template = null) + { + if (null === $template) { + $template = 'FrameworkBundle:Form:errors.php'; + } + + return $this->engine->render($template, array('field' => $this, 'errors' => $this->field->getErrors())); + } + + protected function getTemplate() + { + $class = get_class($this->field); + + if (isset(self::$cache[$class])) { + return self::$cache[$class]; + } + + // find a template for the given class or one of its parents + do { + $parts = explode('\\', $class); + $c = array_pop($parts); + + $underscore = strtolower(preg_replace(array('/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'), array('\\1_\\2', '\\1_\\2'), strtr($c, '_', '.'))); + + if ($this->engine->exists($template = 'FrameworkBundle:Form:widget/'.$underscore.'.php')) { + return self::$cache[$class] = $template; + } + } while (false !== $class = get_parent_class($class)); + + throw new \RuntimeException(sprintf('Unable to find a template to render the "%s" widget.', $this->field->getKey())); + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Templating/Form/FieldGroup.php b/src/Symfony/Bundle/FrameworkBundle/Templating/Form/FieldGroup.php new file mode 100644 index 0000000000000..791270416c16f --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Templating/Form/FieldGroup.php @@ -0,0 +1,75 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +/** + * FieldGroup wraps a Form\FieldGroupInterface instance. + * + * @author Fabien Potencier + */ +class FieldGroup extends BaseField +{ + /** + * Renders the form tag. + * + * This method only renders the opening form tag. + * You need to close it after the form rendering. + * + * This method takes into account the multipart widgets. + * + * @param string $url The URL for the action + * @param array $attributes An array of HTML attributes + * + * @return string An HTML representation of the opening form tag + */ + public function form($url, array $attributes = array()) + { + return sprintf('', $this->generator->attributes(array_merge(array( + 'action' => $url, + 'method' => isset($attributes['method']) ? strtolower($attributes['method']) : 'post', + 'enctype' => $this->field->isMultipart() ? 'multipart/form-data' : null, + ), $attributes))); + } + + public function render($template = null) + { + if (null === $template) { + $template = sprintf('FrameworkBundle:Form:group/%s/field_group.php', $this->theme); + } + + return $this->engine->render($template, array('group' => $this)); + } + + public function hidden($template = null) + { + if (null === $template) { + $template = 'FrameworkBundle:Form:hidden.php'; + } + + return $this->engine->render($template, array( + 'group' => $this, + 'hidden' => $this->wrapFields($this->field->getHiddenFields(true)) + )); + } + + public function errors($template = null) + { + if (null === $template) { + $template = 'FrameworkBundle:Form:errors.php'; + } + + return $this->engine->render($template, array( + 'group' => $this, + 'errors' => $this->field->getErrors() + )); + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Templating/Form/FieldInterface.php b/src/Symfony/Bundle/FrameworkBundle/Templating/Form/FieldInterface.php new file mode 100644 index 0000000000000..bafcd4d444596 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Templating/Form/FieldInterface.php @@ -0,0 +1,22 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +/** + * + * + * @author Fabien Potencier + */ +interface FieldInterface extends \IteratorAggregate, \ArrayAccess +{ + function render($template = null); +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Templating/Form/Form.php b/src/Symfony/Bundle/FrameworkBundle/Templating/Form/Form.php new file mode 100644 index 0000000000000..89d3a64db3bac --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Templating/Form/Form.php @@ -0,0 +1,44 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +/** + * Form is a factory that wraps Form instances. + * + * @author Fabien Potencier + */ +class Form +{ + public $generator; + + protected $engine; + protected $theme; + protected $doctype; + + public function __construct(Engine $engine, HtmlGeneratorInterface $generator, $theme = 'table', $doctype = 'xhtml') + { + $this->engine = $engine; + $this->generator = $generator; + $this->theme = $theme; + $this->doctype = $doctype; + } + + public function get(FieldGroupInterface $group, $theme = null, $doctype = null) + { + return new FieldGroup($group, $this->engine, $this->generator, null === $theme ? $this->theme : $theme, null === $doctype ? $this->doctype : $doctype); + } +} diff --git a/src/Symfony/Component/Form/HtmlGenerator.php b/src/Symfony/Bundle/FrameworkBundle/Templating/HtmlGenerator.php similarity index 67% rename from src/Symfony/Component/Form/HtmlGenerator.php rename to src/Symfony/Bundle/FrameworkBundle/Templating/HtmlGenerator.php index 2030ea341f455..ebd40a9fbc720 100644 --- a/src/Symfony/Component/Form/HtmlGenerator.php +++ b/src/Symfony/Bundle/FrameworkBundle/Templating/HtmlGenerator.php @@ -1,6 +1,6 @@ doChoices(array('' => $empty), $selected)."\n"; + } + + if (count($preferredChoices) > 0) { + $html .= $this->doChoices($preferredChoices, $selected)."\n"; + $html .= $this->contentTag('option', $origin->getOption('separator'), array('disabled' => true))."\n"; + } + + $html .= $this->doChoices($choices, $selected)."\n"; + + return $html; + } + + protected function doChoices(array $choices, array $selected) + { + $options = array(); + foreach ($choices as $key => $option) { + if (is_array($option)) { + $options[] = $this->contentTag( + 'optgroup', + "\n".renderChoices($option, $selected)."\n", + array('label' => $this->escape($key)) + ); + } else { + $attributes = array('value' => $this->escape($key)); + + if (isset($selected[strval($key)])) { + $attributes['selected'] = true; + } + + $options[] = $this->contentTag( + 'option', + $this->escape($option), + $attributes + ); + } + } + + return implode("\n", $options); + } + /** * Prepares an attribute key and value for HTML representation. * diff --git a/src/Symfony/Component/Form/HtmlGeneratorInterface.php b/src/Symfony/Bundle/FrameworkBundle/Templating/HtmlGeneratorInterface.php similarity index 97% rename from src/Symfony/Component/Form/HtmlGeneratorInterface.php rename to src/Symfony/Bundle/FrameworkBundle/Templating/HtmlGeneratorInterface.php index 266b1c06029b9..d216b482166c6 100644 --- a/src/Symfony/Component/Form/HtmlGeneratorInterface.php +++ b/src/Symfony/Bundle/FrameworkBundle/Templating/HtmlGeneratorInterface.php @@ -1,6 +1,6 @@ setParameter('twig.options', array_replace($container->getParameter('twig.options'), $config)); + + // form resources + foreach (array('resources', 'resource') as $key) { + if (isset($config['form'][$key])) { + $resources = $config['form'][$key]; + if (!is_array($resources)) { + $resources = array($resources); + } + $container->setParameter('twig.form.resources', array_merge($container->getParameter('twig.form.resources'), $resources)); + } + } } /** diff --git a/src/Symfony/Bundle/TwigBundle/Extension/FormExtension.php b/src/Symfony/Bundle/TwigBundle/Extension/FormExtension.php new file mode 100644 index 0000000000000..39933e13264bf --- /dev/null +++ b/src/Symfony/Bundle/TwigBundle/Extension/FormExtension.php @@ -0,0 +1,240 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * + * @author Fabien Potencier + */ +class FormExtension extends \Twig_Extension +{ + static protected $cache = array(); + + protected $resources; + protected $templates; + protected $environment; + protected $themes; + protected $generator; + + public function __construct(HtmlGeneratorInterface $generator, array $resources = array()) + { + $this->generator = $generator; + $this->themes = new \SplObjectStorage(); + $this->resources = array_merge(array( + 'TwigBundle::form.twig', + 'TwigBundle::widgets.twig', + ), $resources); + } + + /** + * {@inheritdoc} + */ + public function initRuntime(\Twig_Environment $environment) + { + $this->environment = $environment; + + $this->templates = $this->resolveResources($this->resources); + } + + public function setTheme(FieldGroupInterface $group, array $resources) + { + $this->themes->attach($group, $resources); + } + + /** + * Returns the token parser instance to add to the existing list. + * + * @return array An array of Twig_TokenParser instances + */ + public function getTokenParsers() + { + return array( + // {% form_theme form "SomeBungle::widgets.twig" %} + new FormThemeTokenParser(), + ); + } + + /** + * {@inheritdoc} + */ + public function getFilters() + { + return array( + 'render_enctype' => new \Twig_Filter_Method($this, 'renderEnctype', array('is_escaper' => true)), + 'render' => new \Twig_Filter_Method($this, 'render', array('is_escaper' => true)), + 'render_hidden' => new \Twig_Filter_Method($this, 'renderHidden', array('is_escaper' => true)), + 'render_errors' => new \Twig_Filter_Method($this, 'renderErrors', array('is_escaper' => true)), + 'render_widget' => new \Twig_Filter_Method($this, 'renderWidget', array('is_escaper' => true)), + 'render_label' => new \Twig_Filter_Method($this, 'renderLabel', array('is_escaper' => true)), + 'render_data' => new \Twig_Filter_Method($this, 'renderData', array('is_escaper' => true)), + 'render_choices' => new \Twig_Filter_Method($this, 'renderChoices', array('is_escaper' => true)), + ); + } + + public function renderEnctype(Form $form) + { + return $form->isMultipart() ? 'enctype="multipart/form-data"' : ''; + } + + public function render(FieldInterface $field, array $attributes = array()) + { + if ($field instanceof Form || get_class($field) === 'Symfony\Component\Form\FieldGroup') { + return $this->templates['group']->getBlock('group', array( + 'group' => $field, + 'attributes' => $attributes, + )); + } + + return $this->templates['field']->getBlock('field', array( + 'field' => $field, + 'attributes' => $attributes, + )); + } + + public function renderHidden(FieldGroupInterface $form) + { + return $this->templates['hidden']->getBlock('hidden', array( + 'fields' => $form->getHiddenFields() + )); + } + + public function renderErrors($formOrField) + { + return $this->templates['errors']->getBlock('errors', array( + 'errors' => $formOrField->getErrors() + )); + } + + public function renderLabel(FieldInterface $field, $label = null, array $attributes = array()) + { + return $this->templates['label']->getBlock('label', array( + 'id' => $field->getId(), + 'key' => $field->getKey(), + 'label' => null !== $label ? $label : ucfirst(strtolower(str_replace('_', ' ', $field->getKey()))), + 'attributes' => $attributes, + )); + } + + public function renderWidget(FieldInterface $field, array $attributes = array(), $resources = null) + { + if (null === $resources) { + $parent = $field; + $resources = array(); + while ($parent = $parent->getParent()) { + if (isset($this->themes[$parent])) { + $resources = $this->themes[$parent]; + } + } + } else { + $resources = array($resources); + } + + list($widget, $template) = $this->getWidget($field, $resources); + + return $template->getBlock($widget, array( + 'field' => $field, + 'attributes' => array_merge($field->getAttributes(), $attributes), + )); + } + + public function renderData(FieldInterface $field) + { + return $field->getData(); + } + + public function renderChoices(FieldInterface $field) + { + return $this->generator->choices( + $field->getPreferredChoices(), + $field->getOtherChoices(), + $field->getEmptyValue(), + $field->getSelected() + ); + } + + protected function getWidget(FieldInterface $field, array $resources = array()) + { + $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]; + } + + // find a template for the given class or one of its parents + do { + $parts = explode('\\', $class); + $c = array_pop($parts); + + $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)); + + throw new \RuntimeException(sprintf('Unable to render the "%s" field.', $field->getKey())); + } + + protected function resolveResources(array $resources) + { + $templates = array(); + foreach ($resources as $resource) + { + $blocks = $this->resolveTemplate($this->environment->loadTemplate($resource)); + + $templates = array_replace($templates, $blocks); + } + + 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. + * + * @return string The extension name + */ + public function getName() + { + return 'form'; + } +} diff --git a/src/Symfony/Bundle/TwigBundle/Extension/HtmlExtension.php b/src/Symfony/Bundle/TwigBundle/Extension/HtmlExtension.php new file mode 100644 index 0000000000000..32633aa7c5a64 --- /dev/null +++ b/src/Symfony/Bundle/TwigBundle/Extension/HtmlExtension.php @@ -0,0 +1,62 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * + * @author Fabien Potencier + */ +class HtmlExtension extends \Twig_Extension +{ + protected $generator; + + public function __construct(HtmlGeneratorInterface $generator) + { + $this->generator = $generator; + } + + public function getGenerator() + { + return $this->generator; + } + + /** + * Returns the token parser instance to add to the existing list. + * + * @return array An array of Twig_TokenParser instances + */ + public function getTokenParsers() + { + return array( + // {% tag "input" with attributes %} + new TagTokenParser(), + + // {% contenttag "textarea" with attributes %}content{% endcontenttag %} + new ContentTagTokenParser(), + ); + } + + /** + * Returns the name of the extension. + * + * @return string The extension name + */ + public function getName() + { + return 'html'; + } +} diff --git a/src/Symfony/Bundle/TwigBundle/Node/FormThemeNode.php b/src/Symfony/Bundle/TwigBundle/Node/FormThemeNode.php new file mode 100644 index 0000000000000..d697bd620d460 --- /dev/null +++ b/src/Symfony/Bundle/TwigBundle/Node/FormThemeNode.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * + * + * @author Fabien Potencier + */ +class FormThemeNode extends \Twig_Node +{ + public function __construct(\Twig_NodeInterface $form, \Twig_NodeInterface $resources, $lineno, $tag = null) + { + parent::__construct(array('form' => $form, 'resources' => $resources), array(), $lineno, $tag); + } + + /** + * Compiles the node to PHP. + * + * @param \Twig_Compiler A Twig_Compiler instance + */ + public function compile($compiler) + { + $compiler + ->addDebugInfo($this) + ->write('echo $this->env->getExtension(\'form\')->setTheme(') + ->subcompile($this->getNode('form')) + ->raw(', array(') + ; + + foreach ($this->getNode('resources') as $resource) { + $compiler + ->subcompile($resource) + ->raw(', ') + ; + } + + $compiler->raw('));'); + } +} diff --git a/src/Symfony/Bundle/TwigBundle/Node/HelperNode.php b/src/Symfony/Bundle/TwigBundle/Node/HelperNode.php index a4d8d4eb0c380..eba6b5ca66ca5 100644 --- a/src/Symfony/Bundle/TwigBundle/Node/HelperNode.php +++ b/src/Symfony/Bundle/TwigBundle/Node/HelperNode.php @@ -35,15 +35,15 @@ public function compile($compiler) ->raw("\$this->env->getExtension(") ->string('symfony.helpers') ->raw(")->getContainer()->get(") - ->string($this['helper']) + ->string($this->getAttribute('helper')) ->raw(")->") - ->raw($this['method']) + ->raw($this->getAttribute('method')) ->raw("(") ; - foreach ($this->values as $i => $value) { + foreach ($this->getNode('values') as $i => $value) { $compiler->subcompile($value); - if ($i !== count($this->values) - 1) { + if ($i !== count($this->getNode('values')) - 1) { $compiler->raw(', '); } } diff --git a/src/Symfony/Bundle/TwigBundle/Node/TagNode.php b/src/Symfony/Bundle/TwigBundle/Node/TagNode.php new file mode 100644 index 0000000000000..8bad2b95f382a --- /dev/null +++ b/src/Symfony/Bundle/TwigBundle/Node/TagNode.php @@ -0,0 +1,62 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * + * + * @author Fabien Potencier + */ +class TagNode extends \Twig_Node +{ + public function __construct(\Twig_NodeInterface $htmlTag, \Twig_NodeInterface $content = null, \Twig_Node_Expression $attributes = null, $lineno, $tag = null) + { + parent::__construct(array('html_tag' => $htmlTag, 'content' => $content, 'html_attributes' => $attributes), array(), $lineno, $tag); + } + + /** + * Compiles the node to PHP. + * + * @param \Twig_Compiler A Twig_Compiler instance + */ + public function compile($compiler) + { + $compiler->addDebugInfo($this); + + $method = null === $this->getNode('content') ? 'tag' : 'contentTag'; + + if (null !== $this->getNode('content')) { + $compiler + ->write("ob_start();\n") + ->subcompile($this->getNode('content')) + ->write('$content = ob_get_clean();') + ; + } + + $compiler + ->write('echo $this->env->getExtension(\'html\')->getGenerator()->'.$method.'(') + ->subcompile($this->getNode('html_tag')) + ->raw(', ') + ; + + if (null !== $this->getNode('content')) { + $compiler + ->raw('$content, ') + ; + } + + $compiler + ->subcompile($this->getNode('html_attributes')) + ->raw(');') + ; + } +} diff --git a/src/Symfony/Bundle/TwigBundle/Resources/config/schema/twig-1.0.xsd b/src/Symfony/Bundle/TwigBundle/Resources/config/schema/twig-1.0.xsd index 68fe823855b4a..024d2580d5532 100644 --- a/src/Symfony/Bundle/TwigBundle/Resources/config/schema/twig-1.0.xsd +++ b/src/Symfony/Bundle/TwigBundle/Resources/config/schema/twig-1.0.xsd @@ -5,14 +5,24 @@ targetNamespace="http://www.symfony-project.org/schema/dic/twig" elementFormDefault="qualified"> - + - - - - - - - - + + + + + + + + + + + + + + + + + + diff --git a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml index 1ca4e88e66825..8c8368e8a2552 100644 --- a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml +++ b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml @@ -13,6 +13,7 @@ Symfony\Bundle\TwigBundle\Loader\Loader Symfony\Bundle\TwigBundle\Renderer\Renderer + @@ -42,9 +43,20 @@
+ + + + + + + + + + %twig.form.resources% +
diff --git a/src/Symfony/Bundle/TwigBundle/Resources/views/form.twig b/src/Symfony/Bundle/TwigBundle/Resources/views/form.twig new file mode 100644 index 0000000000000..ba3b2c732e5ac --- /dev/null +++ b/src/Symfony/Bundle/TwigBundle/Resources/views/form.twig @@ -0,0 +1,41 @@ +{% block group %} + {{ group|render_errors }} + + {% for field in group %} + {% if not field.ishidden %} + {{ field|render }} + {% endif %} + {% endfor %} +
+ {{ group|render_hidden }} +{% endblock group %} + +{% block field %} + + {{ field|render_label }} + + {{ field|render_errors }} + {{ field|render_widget }} + + +{% endblock field %} + +{% block errors %} + {% if errors %} +
    + {% for error in errors %} +
  • {% trans error.0 with error.1 from validators %}
  • + {% endfor %} +
+ {% endif %} +{% endblock errors %} + +{% block hidden %} + {% for field in fields %} + {{ field|render_widget }} + {% endfor %} +{% endblock hidden %} + +{% block label %} + +{% endblock label %} diff --git a/src/Symfony/Bundle/TwigBundle/Resources/views/widgets.twig b/src/Symfony/Bundle/TwigBundle/Resources/views/widgets.twig new file mode 100644 index 0000000000000..f7d104f2bc3ba --- /dev/null +++ b/src/Symfony/Bundle/TwigBundle/Resources/views/widgets.twig @@ -0,0 +1,57 @@ +{% block input_field %} + {% tag "input" with attributes %} +{% endblock input_field %} + +{% block textarea_field %} + {% contenttag "textarea" with attributes %}{{ field.displayedData }}{% endcontenttag %} +{% endblock textarea_field %} + +{% block choice_field %} + {% if field.options.expanded %} + {% for child in field %} + {{ child|render_widget }} + {% endfor %} + {% else %} + {% contenttag "select" with attributes %} + {{ field|render_choices }} + {% endcontenttag %} + {% endif %} +{% endblock choice_field %} + +{% block toggle_field %} + {% display input_field %} + {% if field.options.label %} + {% contenttag "label" with ['for': field.id] %}{% trans field.options.label %}{% endcontenttag %} + {% endif %} +{% endblock toggle_field %} + +{% block date_time_field %} + {{ field.date|render_widget }} + {{ field.time|render_widget }} +{% endblock date_time_field %} + +{% block date_field %} + {% if field.field %} + {% display input_field %} + {% else %} + {{ field.pattern|replace(['{{ year }}': field.year|render_widget, '{{ month }}': field.month|render_widget, '{{ day }}': field.day|render_widget,]) }} + {% endif %} +{% endblock date_field %} + +{% block time_field %} + {% if field.isfield %} + {% display input_field %} + {% else %} + {{ field.hour|render_widget }}:{{ field.minute|render_widget }} + {% if field.options.with_seconds %}:{{ field.second|render_widget }}{% endif %} + {% endif %} +{% endblock time_field %} + +{% block money_field %} + {% set widget %}{% display input_field %}{% endset %} + {{ field.pattern|replace(['{{ widget }}': widget]) }} +{% endblock money_field %} + +{% block percent_field %} + {% display input_field %} % +{% endblock percent_field %} diff --git a/src/Symfony/Bundle/TwigBundle/TokenParser/ContentTagTokenParser.php b/src/Symfony/Bundle/TwigBundle/TokenParser/ContentTagTokenParser.php new file mode 100644 index 0000000000000..d4ba0eecaf64f --- /dev/null +++ b/src/Symfony/Bundle/TwigBundle/TokenParser/ContentTagTokenParser.php @@ -0,0 +1,66 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * + * + * @author Fabien Potencier + */ +class ContentTagTokenParser extends \Twig_TokenParser +{ + /** + * Parses a token and returns a node. + * + * @param \Twig_Token $token A Twig_Token instance + * + * @return \Twig_NodeInterface A Twig_NodeInterface instance + */ + public function parse(\Twig_Token $token) + { + $lineno = $token->getLine(); + $stream = $this->parser->getStream(); + + $tag = $this->parser->getExpressionParser()->parseExpression(); + + $attributes = null; + if ($stream->test('with')) { + $stream->next(); + $attributes = $this->parser->getExpressionParser()->parseExpression(); + } + + $stream->expect(\Twig_Token::BLOCK_END_TYPE); + + $content = $this->parser->subparse(array($this, 'decideContentTagFork'), true); + + $stream->expect(\Twig_Token::BLOCK_END_TYPE); + + return new TagNode($tag, $content, $attributes, $lineno, $this->getTag()); + } + + public function decideContentTagFork($token) + { + return $token->test(array('endcontenttag')); + } + + /** + * Gets the tag name associated with this token parser. + * + * @param string The tag name + */ + public function getTag() + { + return 'contenttag'; + } +} diff --git a/src/Symfony/Bundle/TwigBundle/TokenParser/FormThemeTokenParser.php b/src/Symfony/Bundle/TwigBundle/TokenParser/FormThemeTokenParser.php new file mode 100644 index 0000000000000..7fd3974bc6b14 --- /dev/null +++ b/src/Symfony/Bundle/TwigBundle/TokenParser/FormThemeTokenParser.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * + * + * @author Fabien Potencier + */ +class FormThemeTokenParser extends \Twig_TokenParser +{ + /** + * Parses a token and returns a node. + * + * @param \Twig_Token $token A Twig_Token instance + * + * @return \Twig_NodeInterface A Twig_NodeInterface instance + */ + public function parse(\Twig_Token $token) + { + $lineno = $token->getLine(); + $stream = $this->parser->getStream(); + + $form = $this->parser->getExpressionParser()->parseExpression(); + $resources = array(); + do { + $resources[] = $this->parser->getExpressionParser()->parseExpression(); + } while (!$stream->test(\Twig_Token::BLOCK_END_TYPE)); + + $stream->expect(\Twig_Token::BLOCK_END_TYPE); + + return new FormThemeNode($form, new \Twig_Node($resources), $lineno, $this->getTag()); + } + + /** + * Gets the tag name associated with this token parser. + * + * @param string The tag name + */ + public function getTag() + { + return 'form_theme'; + } +} diff --git a/src/Symfony/Bundle/TwigBundle/TokenParser/TagTokenParser.php b/src/Symfony/Bundle/TwigBundle/TokenParser/TagTokenParser.php new file mode 100644 index 0000000000000..43222c3346ac9 --- /dev/null +++ b/src/Symfony/Bundle/TwigBundle/TokenParser/TagTokenParser.php @@ -0,0 +1,57 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * + * + * @author Fabien Potencier + */ +class TagTokenParser extends \Twig_TokenParser +{ + /** + * Parses a token and returns a node. + * + * @param \Twig_Token $token A Twig_Token instance + * + * @return \Twig_NodeInterface A Twig_NodeInterface instance + */ + public function parse(\Twig_Token $token) + { + $lineno = $token->getLine(); + $stream = $this->parser->getStream(); + + $tag = $this->parser->getExpressionParser()->parseExpression(); + + $attributes = null; + if ($stream->test('with')) { + $stream->next(); + $attributes = $this->parser->getExpressionParser()->parseExpression(); + } + + $stream->expect(\Twig_Token::BLOCK_END_TYPE); + + return new TagNode($tag, null, $attributes, $lineno, $this->getTag()); + } + + /** + * Gets the tag name associated with this token parser. + * + * @param string The tag name + */ + public function getTag() + { + return 'tag'; + } +} diff --git a/src/Symfony/Component/Form/CheckboxField.php b/src/Symfony/Component/Form/CheckboxField.php index 6fd3971725062..6fed502f4f745 100644 --- a/src/Symfony/Component/Form/CheckboxField.php +++ b/src/Symfony/Component/Form/CheckboxField.php @@ -21,10 +21,10 @@ class CheckboxField extends ToggleField /** * {@inheritDoc} */ - public function render(array $attributes = array()) + public function getAttributes() { - return parent::render(array_merge(array( + return array_merge(parent::getAttributes(), array( 'type' => 'checkbox', - ), $attributes)); + )); } } \ No newline at end of file diff --git a/src/Symfony/Component/Form/ChoiceField.php b/src/Symfony/Component/Form/ChoiceField.php index e05bbcd7d8969..adc309cfa1058 100644 --- a/src/Symfony/Component/Form/ChoiceField.php +++ b/src/Symfony/Component/Form/ChoiceField.php @@ -37,7 +37,6 @@ protected function configure() $this->addOption('multiple', false); $this->addOption('expanded', false); $this->addOption('empty_value', ''); - $this->addOption('translate_choices', false); if (!is_array($this->getOption('choices'))) { throw new UnexpectedTypeException('The choices option must be an array'); @@ -70,6 +69,51 @@ protected function configure() } } + /** + * {@inheritDoc} + */ + public function getAttributes() + { + $attributes = array( + 'id' => $this->getId(), + 'name' => $this->getName(), + 'disabled' => $this->isDisabled(), + ); + + // Add "[]" to the name in case a select tag with multiple options is + // displayed. Otherwise only one of the selected options is sent in the + // POST request. + if ($this->getOption('multiple') && !$this->getOption('expanded')) { + $attributes['name'] .= '[]'; + } + + if ($this->getOption('multiple')) { + $attributes['multiple'] = 'multiple'; + } + + return array_merge(parent::getAttributes(), $attributes); + } + + public function getSelected() + { + return array_flip(array_map('strval', (array) $this->getDisplayedData())); + } + + public function getPreferredChoices() + { + return array_intersect_key($this->getOption('choices'), $this->preferredChoices); + } + + public function getOtherChoices() + { + return array_diff_key($this->getOption('choices'), $this->preferredChoices); + } + + public function getEmptyValue() + { + return $this->isRequired() ? false : $this->getOption('empty_value'); + } + /** * Returns a new field of type radio button or checkbox. * @@ -82,13 +126,11 @@ protected function newChoiceField($choice, $label) return new CheckboxField($choice, array( 'value' => $choice, 'label' => $label, - 'translate_label' => $this->getOption('translate_choices'), )); } else { return new RadioField($choice, array( 'value' => $choice, 'label' => $label, - 'translate_label' => $this->getOption('translate_choices'), )); } } @@ -171,91 +213,4 @@ protected function reverseTransform($value) return parent::reverseTransform($value); } } - - /** - * {@inheritDoc} - */ - public function render(array $attributes = array()) - { - if ($this->getOption('expanded')) { - $html = ""; - - foreach ($this as $field) { - $html .= $field->render()."\n"; - } - - return $html; - } else { - $attrs['id'] = $this->getId(); - $attrs['name'] = $this->getName(); - $attrs['disabled'] = $this->isDisabled(); - - // Add "[]" to the name in case a select tag with multiple options is - // displayed. Otherwise only one of the selected options is sent in the - // POST request. - if ($this->getOption('multiple') && !$this->getOption('expanded')) { - $attrs['name'] .= '[]'; - } - - if ($this->getOption('multiple')) { - $attrs['multiple'] = 'multiple'; - } - - $selected = array_flip(array_map('strval', (array)$this->getDisplayedData())); - $html = "\n"; - - if (!$this->isRequired()) { - $html .= $this->renderChoices(array('' => $this->getOption('empty_value')), $selected)."\n"; - } - - $choices = $this->getOption('choices'); - - if (count($this->preferredChoices) > 0) { - $html .= $this->renderChoices(array_intersect_key($choices, $this->preferredChoices), $selected)."\n"; - $html .= $this->generator->contentTag('option', $this->getOption('separator'), array('disabled' => true))."\n"; - } - - $html .= $this->renderChoices(array_diff_key($choices, $this->preferredChoices), $selected)."\n"; - - return $this->generator->contentTag('select', $html, array_merge($attrs, $attributes)); - } - } - - /** - * Returns an array of option tags for the choice field - * - * @return array An array of option tags - */ - protected function renderChoices(array $choices, array $selected) - { - $options = array(); - - foreach ($choices as $key => $option) { - if (is_array($option)) { - $options[] = $this->generator->contentTag( - 'optgroup', - "\n".$this->renderChoices($option, $selected)."\n", - array('label' => $this->generator->escape($key)) - ); - } else { - $attributes = array('value' => $this->generator->escape($key)); - - if (isset($selected[strval($key)])) { - $attributes['selected'] = true; - } - - if ($this->getOption('translate_choices')) { - $option = $this->translate($option); - } - - $options[] = $this->generator->contentTag( - 'option', - $this->generator->escape($option), - $attributes - ); - } - } - - return implode("\n", $options); - } } diff --git a/src/Symfony/Component/Form/Configurable.php b/src/Symfony/Component/Form/Configurable.php index 455286d7dbe86..e956b3354c635 100644 --- a/src/Symfony/Component/Form/Configurable.php +++ b/src/Symfony/Component/Form/Configurable.php @@ -143,4 +143,9 @@ public function hasOption($name) { return isset($this->options[$name]); } + + public function getOptions() + { + return $this->options; + } } diff --git a/src/Symfony/Component/Form/DateField.php b/src/Symfony/Component/Form/DateField.php index 399986f56243a..688c6e41566a2 100644 --- a/src/Symfony/Component/Form/DateField.php +++ b/src/Symfony/Component/Form/DateField.php @@ -79,7 +79,7 @@ class DateField extends HybridField * * data_timezone: The timezone of the data * * user_timezone: The timezone of the user entering a new value * * pattern: The pattern for the select boxes when "widget" is "select". - * You can use the placeholders "%year%", "%month%" and "%day%". + * You can use the placeholders "{{ year }}", "{{ month }}" and "{{ day }}". * Default: locale dependent * * @param array $options Options for this field @@ -145,6 +145,23 @@ protected function configure() } } + /** + * {@inheritDoc} + */ + public function getAttributes() + { + if ($this->isField()) { + return array_merge(parent::getAttributes(), array( + 'id' => $this->getId(), + 'name' => $this->getName(), + 'value' => $this->getDisplayedData(), + 'type' => 'text', + )); + } + + return parent::getAttributes(); + } + /** * Generates an array of choices for the given values * @@ -194,41 +211,22 @@ protected function generateMonthChoices(array $months) return $choices; } - /** - * {@inheritDoc} - */ - public function render(array $attributes = array()) + public function getPattern() { - if ($this->getOption('widget') === self::INPUT) { - return $this->generator->tag('input', array_merge(array( - 'id' => $this->getId(), - 'name' => $this->getName(), - 'value' => $this->getDisplayedData(), - 'type' => 'text', - ), $attributes)); - } else { - // set order as specified in the pattern - if ($this->getOption('pattern')) { - $pattern = $this->getOption('pattern'); - } - // set right order with respect to locale (e.g.: de_DE=dd.MM.yy; en_US=M/d/yy) - // lookup various formats at http://userguide.icu-project.org/formatparse/datetime - else if (preg_match('/^([yMd]+).+([yMd]+).+([yMd]+)$/', $this->formatter->getPattern())) { - $pattern = preg_replace(array('/y+/', '/M+/', '/d+/'), array('%year%', '%month%', '%day%'), $this->formatter->getPattern()); - } - // default fallback - else { - $pattern = '%year%-%month%-%day%'; - } + // set order as specified in the pattern + if ($this->getOption('pattern')) { + return $this->getOption('pattern'); + } - return str_replace(array('%year%', '%month%', '%day%'), array( - $this->get('year')->render($attributes), - $this->get('month')->render($attributes), - $this->get('day')->render($attributes), - ), $pattern); + // set right order with respect to locale (e.g.: de_DE=dd.MM.yy; en_US=M/d/yy) + // lookup various formats at http://userguide.icu-project.org/formatparse/datetime + if (preg_match('/^([yMd]+).+([yMd]+).+([yMd]+)$/', $this->formatter->getPattern())) { + return preg_replace(array('/y+/', '/M+/', '/d+/'), array('{{ year }}', '{{ month }}', '{{ day }}'), $this->formatter->getPattern()); } - } + // default fallback + return '{{ year }}-{{ month }}-{{ day }}'; + } /** * Sets the locale of this field. diff --git a/src/Symfony/Component/Form/DateTimeField.php b/src/Symfony/Component/Form/DateTimeField.php index 1bc373cac8967..7b9c63188dbe5 100644 --- a/src/Symfony/Component/Form/DateTimeField.php +++ b/src/Symfony/Component/Form/DateTimeField.php @@ -120,15 +120,4 @@ protected function reverseTransform($value) { return parent::reverseTransform(array_merge($value['date'], $value['time'])); } - - /** - * {@inheritDoc} - */ - public function render(array $attributes = array()) - { - $html = $this->get('date')->render($attributes)."\n"; - $html .= $this->get('time')->render($attributes); - - return $html; - } } diff --git a/src/Symfony/Component/Form/Field.php b/src/Symfony/Component/Form/Field.php index fc0aca3b2c0e1..8b2734b58e54c 100644 --- a/src/Symfony/Component/Form/Field.php +++ b/src/Symfony/Component/Form/Field.php @@ -15,24 +15,15 @@ use Symfony\Component\Form\Exception\PropertyAccessDeniedException; use Symfony\Component\Form\ValueTransformer\ValueTransformerInterface; use Symfony\Component\Form\ValueTransformer\TransformationFailedException; -use Symfony\Component\I18N\TranslatorInterface; abstract class Field extends Configurable implements FieldInterface { - /** - * The object used for generating HTML code - * @var HtmlGeneratorInterface - */ - protected $generator = null; - protected $taintedData = null; protected $locale = null; - protected $translator = null; private $errors = array(); private $key = ''; private $parent = null; - private $renderer = null; private $bound = false; private $required = null; private $data = null; @@ -48,7 +39,6 @@ public function __construct($key, array $options = array()) $this->addOption('property_path', (string)$key); $this->key = (string)$key; - $this->generator = new HtmlGenerator(); if ($this->locale === null) { $this->locale = class_exists('\Locale', false) ? \Locale::getDefault() : 'en'; @@ -70,6 +60,11 @@ public function __clone() // TODO } + public function getAttributes() + { + return array(); + } + /** * Returns the data of the field as it is displayed to the user. * @@ -172,14 +167,6 @@ public function isDisabled() } } - /** - * {@inheritDoc} - */ - public function setGenerator(HtmlGeneratorInterface $generator) - { - $this->generator = $generator; - } - /** * {@inheritDoc} */ @@ -287,9 +274,9 @@ public function getData() * * @see FieldInterface */ - public function addError($message, PropertyPath $path = null, $type = null) + public function addError($messageTemplate, array $messageParameters = array(), PropertyPath $path = null, $type = null) { - $this->errors[] = $message; + $this->errors[] = array($messageTemplate, $messageParameters); } /** @@ -347,55 +334,17 @@ public function setLocale($locale) } /** - * Sets the translator of this field. + * Injects the locale into the given object, if set. * - * @see Translatable - */ - public function setTranslator(TranslatorInterface $translator) - { - $this->translator = $translator; - - if ($this->valueTransformer !== null && $this->valueTransformer instanceof Translatable) { - $this->valueTransformer->setTranslator($translator); - } - } - - /** - * Translates the text using the associated translator, if available - * - * If no translator is available, the original text is returned without - * modification. - * - * @param string $text The text to translate - * @param array $parameters The parameters to insert in the text - * @return string The translated text - */ - protected function translate($text, array $parameters = array()) - { - if ($this->translator !== null) { - $text = $this->translator->translate($text, $parameters); - } - - return $text; - } - - /** - * Injects the locale and the translator into the given object, if set. - * - * The locale is injected only if the object implements Localizable. The - * translator is injected only if the object implements Translatable. + * The locale is injected only if the object implements Localizable. * * @param object $object */ - protected function injectLocaleAndTranslator($object) + protected function injectLocale($object) { if ($object instanceof Localizable) { $object->setLocale($this->locale); } - - if (!is_null($this->translator) && $object instanceof Translatable) { - $object->setTranslator($this->translator); - } } /** @@ -405,7 +354,7 @@ protected function injectLocaleAndTranslator($object) */ public function setValueTransformer(ValueTransformerInterface $valueTransformer) { - $this->injectLocaleAndTranslator($valueTransformer); + $this->injectLocale($valueTransformer); $this->valueTransformer = $valueTransformer; } @@ -630,24 +579,4 @@ protected function updateProperty(&$objectOrArray, PropertyPath $propertyPath) $objectOrArray[$propertyPath->getCurrent()] = $this->getData(); } } - - /** - * {@inheritDoc} - */ - public function renderErrors() - { - $html = ''; - - if ($this->hasErrors()) { - $html .= "
    \n"; - - foreach ($this->getErrors() as $error) { - $html .= "
  • " . $error . "
  • \n"; - } - - $html .= "
\n"; - } - - return $html; - } } diff --git a/src/Symfony/Component/Form/FieldGroup.php b/src/Symfony/Component/Form/FieldGroup.php index 97cf3f90f2f4b..156028cdc6193 100644 --- a/src/Symfony/Component/Form/FieldGroup.php +++ b/src/Symfony/Component/Form/FieldGroup.php @@ -13,10 +13,7 @@ use Symfony\Component\Form\Exception\AlreadyBoundException; use Symfony\Component\Form\Exception\UnexpectedTypeException; -use Symfony\Component\Form\Renderer\RendererInterface; -use Symfony\Component\Form\Renderer\TableRenderer; use Symfony\Component\Form\Iterator\RecursiveFieldsWithPropertyPathIterator; -use Symfony\Component\I18N\TranslatorInterface; /** * FieldGroup represents an array of widgets bind to names and values. @@ -37,19 +34,6 @@ class FieldGroup extends Field implements \IteratorAggregate, FieldGroupInterfac */ protected $extraFields = array(); - /** - * Constructor - * - * @see FieldInterface::__construct() - */ - public function __construct($key, array $options = array()) - { - // set the default renderer before calling the configure() method - $this->setRenderer(new TableRenderer()); - - parent::__construct($key, $options); - } - /** * Clones this group */ @@ -109,11 +93,6 @@ public function add(FieldInterface $field) $field->setParent($this); $field->setLocale($this->locale); - $field->setGenerator($this->generator); - - if ($this->translator !== null) { - $field->setTranslator($this->translator); - } $data = $this->getTransformedData(); @@ -367,7 +346,7 @@ public function isValid() /** * {@inheritDoc} */ - public function addError($message, PropertyPath $path = null, $type = null) + public function addError($messageTemplate, array $messageParameters = array(), PropertyPath $path = null, $type = null) { if ($path !== null) { if ($type === self::FIELD_ERROR && $path->hasNext()) { @@ -378,7 +357,7 @@ public function addError($message, PropertyPath $path = null, $type = null) } if ($this->has($path->getCurrent()) && !$this->get($path->getCurrent())->isHidden()) { - $this->get($path->getCurrent())->addError($message, $path, $type); + $this->get($path->getCurrent())->addError($messageTemplate, $messageParameters, $path, $type); return; } @@ -395,7 +374,7 @@ public function addError($message, PropertyPath $path = null, $type = null) $path->next(); } - $field->addError($message, $path, $type); + $field->addError($messageTemplate, $messageParameters, $path, $type); return; } @@ -404,7 +383,7 @@ public function addError($message, PropertyPath $path = null, $type = null) } } - parent::addError($message); + parent::addError($messageTemplate, $messageParameters); } /** @@ -423,67 +402,6 @@ public function isMultipart() return false; } - /** - * Sets the renderer. - * - * @param RendererInterface $renderer - */ - public function setRenderer(RendererInterface $renderer) - { - $this->renderer = $renderer; - } - - /** - * Returns the current renderer. - * - * @return RendererInterface - */ - public function getRenderer() - { - return $this->renderer; - } - - /** - * Delegates the rendering of the field to the renderer set. - * - * @return string The rendered widget - */ - public function render(array $attributes = array()) - { - $this->injectLocaleAndTranslator($this->renderer); - - return $this->renderer->render($this, $attributes); - } - - /** - * Delegates the rendering of the field to the renderer set. - * - * @return string The rendered widget - */ - public function renderErrors() - { - $this->injectLocaleAndTranslator($this->renderer); - - return $this->renderer->renderErrors($this); - } - /** - * Renders hidden form fields. - * - * @param boolean $recursive False will prevent hidden fields from embedded forms from rendering - * - * @return string - */ - public function renderHiddenFields($recursive = true) - { - $output = ''; - - foreach ($this->getHiddenFields($recursive) as $field) { - $output .= $field->render(); - } - - return $output; - } - /** * Returns true if the bound field exists (implements the \ArrayAccess interface). * @@ -566,33 +484,4 @@ public function setLocale($locale) $field->setLocale($locale); } } - - /** - * Sets the translator of this field. - * - * @see Translatable - */ - public function setTranslator(TranslatorInterface $translator) - { - parent::setTranslator($translator); - - foreach ($this->fields as $field) { - $field->setTranslator($translator); - } - } - - /** - * Distributes the generator among all nested fields - * - * @param HtmlGeneratorInterface $generator - */ - public function setGenerator(HtmlGeneratorInterface $generator) - { - parent::setGenerator($generator); - - // TESTME - foreach ($this->fields as $field) { - $field->setGenerator($generator); - } - } } diff --git a/src/Symfony/Component/Form/FieldInterface.php b/src/Symfony/Component/Form/FieldInterface.php index b076209a078df..e6c3ed4e614bb 100644 --- a/src/Symfony/Component/Form/FieldInterface.php +++ b/src/Symfony/Component/Form/FieldInterface.php @@ -18,7 +18,7 @@ * * @author Bernhard Schussek */ -interface FieldInterface extends Localizable, Translatable +interface FieldInterface extends Localizable { /** * Marks a constraint violation in a form field @@ -185,23 +185,7 @@ public function bind($taintedData); * @param PropertyPath $path * @param ConstraintViolation$violation */ - public function addError($message, PropertyPath $path = null, $type = null); - - /** - * Renders this field. - * - * @param array $attributes The attributes to include in the rendered - * output - * @return string The rendered output of this field - */ - public function render(array $attributes = array()); - - /** - * Renders the errors of this field. - * - * @return string The rendered output of the field errors - */ - public function renderErrors(); + function addError($messageTemplate, array $messageParameters = array(), PropertyPath $path = null, $type = null); /** * Returns whether the field is bound. @@ -261,14 +245,4 @@ public function isHidden(); * @param boolean $required */ public function setRequired($required); - - /** - * Sets the generator used for rendering HTML. - * - * Usually there is one generator instance shared between all fields of a - * form. - * - * @param string $charset - */ - public function setGenerator(HtmlGeneratorInterface $generator); } diff --git a/src/Symfony/Component/Form/FileField.php b/src/Symfony/Component/Form/FileField.php index e712f4a14f356..27f50553d5a6e 100644 --- a/src/Symfony/Component/Form/FileField.php +++ b/src/Symfony/Component/Form/FileField.php @@ -19,11 +19,11 @@ class FileField extends InputField /** * {@inheritDoc} */ - public function render(array $attributes = array()) + public function getAttributes() { - return parent::render(array_merge(array( + return array_merge(parent::getAttributes(), array( 'type' => 'file', - ), $attributes)); + )); } /** diff --git a/src/Symfony/Component/Form/Form.php b/src/Symfony/Component/Form/Form.php index b8809f5779a05..9994325dc7de0 100644 --- a/src/Symfony/Component/Form/Form.php +++ b/src/Symfony/Component/Form/Form.php @@ -12,7 +12,6 @@ */ use Symfony\Component\Validator\ValidatorInterface; -use Symfony\Component\I18N\TranslatorInterface; /** * Form represents a form. @@ -34,7 +33,6 @@ class Form extends FieldGroup protected static $defaultCsrfProtection = false; protected static $defaultCsrfFieldName = '_token'; protected static $defaultLocale = null; - protected static $defaultTranslator = null; protected $validator = null; protected $validationGroups = null; @@ -51,7 +49,6 @@ class Form extends FieldGroup */ public function __construct($name, $object, ValidatorInterface $validator, array $options = array()) { - $this->generator = new HtmlGenerator(); $this->validator = $validator; $this->setData($object); @@ -71,26 +68,9 @@ public function __construct($name, $object, ValidatorInterface $validator, array $this->setLocale(self::$defaultLocale); } - if (self::$defaultTranslator !== null) { - $this->setTranslator(self::$defaultTranslator); - } - parent::__construct($name, $options); } - /** - * Sets the charset used for rendering HTML - * - * This method overrides the internal HTML generator! If you want to use - * your own generator, use setGenerator() instead. - * - * @param string $charset - */ - public function setCharset($charset) - { - $this->setGenerator(new HtmlGenerator($charset)); - } - /** * Sets the validation groups for this form. * @@ -131,26 +111,6 @@ static public function getDefaultLocale() return self::$defaultLocale; } - /** - * Sets the default translator for newly created forms. - * - * @param TranslatorInterface $defaultTranslator - */ - static public function setDefaultTranslator(TranslatorInterface $defaultTranslator) - { - self::$defaultTranslator = $defaultTranslator; - } - - /** - * Returns the default translator for newly created forms. - * - * @return TranslatorInterface - */ - static public function getDefaultTranslator() - { - return self::$defaultTranslator; - } - /** * Binds the form with values and files. * @@ -191,7 +151,7 @@ final public function bind($taintedValues, array $taintedFiles = null) $type = self::FIELD_ERROR; } - $this->addError($violation->getMessage(), $propertyPath, $type); + $this->addError($violation->getMessageTemplate(), $violation->getMessageParameters(), $propertyPath, $type); } } } @@ -208,26 +168,6 @@ protected function doBind(array $taintedData) parent::bind($taintedData); } - /** - * Gets the stylesheet paths associated with the form. - * - * @return array An array of stylesheet paths - */ - public function getStylesheets() - { - return $this->getWidget()->getStylesheets(); - } - - /** - * Gets the JavaScript paths associated with the form. - * - * @return array An array of JavaScript paths - */ - public function getJavaScripts() - { - return $this->getWidget()->getJavaScripts(); - } - /** * Returns a CSRF token for the set CSRF secret * @@ -385,28 +325,6 @@ static public function getDefaultCsrfSecret() return self::$defaultCsrfSecret; } - /** - * Renders the form tag. - * - * This method only renders the opening form tag. - * You need to close it after the form rendering. - * - * This method takes into account the multipart widgets. - * - * @param string $url The URL for the action - * @param array $attributes An array of HTML attributes - * - * @return string An HTML representation of the opening form tag - */ - public function renderFormTag($url, array $attributes = array()) - { - return sprintf('', $this->generator->attributes(array_merge(array( - 'action' => $url, - 'method' => isset($attributes['method']) ? strtolower($attributes['method']) : 'post', - 'enctype' => $this->isMultipart() ? 'multipart/form-data' : null, - ), $attributes))); - } - /** * Returns whether the maximum POST size was reached in this request. * diff --git a/src/Symfony/Component/Form/HiddenField.php b/src/Symfony/Component/Form/HiddenField.php index 0cff38a16e34e..4e68b51c56a1b 100644 --- a/src/Symfony/Component/Form/HiddenField.php +++ b/src/Symfony/Component/Form/HiddenField.php @@ -21,11 +21,11 @@ class HiddenField extends InputField /** * {@inheritDoc} */ - public function render(array $attributes = array()) + public function getAttributes() { - return parent::render(array_merge(array( - 'type' => 'hidden', - ), $attributes)); + return array_merge(parent::getAttributes(), array( + 'type' => 'hidden', + )); } /** diff --git a/src/Symfony/Component/Form/HybridField.php b/src/Symfony/Component/Form/HybridField.php index 616320905c4a6..4214dfa6ed4f3 100644 --- a/src/Symfony/Component/Form/HybridField.php +++ b/src/Symfony/Component/Form/HybridField.php @@ -48,6 +48,21 @@ public function setFieldMode($mode) $this->mode = $mode; } + public function isField() + { + return self::FIELD === $this->mode; + } + + public function isGroup() + { + return self::GROUP === $this->mode; + } + + public function getFieldMode() + { + return $this->mode; + } + /** * {@inheritDoc} * diff --git a/src/Symfony/Component/Form/InputField.php b/src/Symfony/Component/Form/InputField.php index b98e73b68ab4d..96e217c4f1517 100644 --- a/src/Symfony/Component/Form/InputField.php +++ b/src/Symfony/Component/Form/InputField.php @@ -21,13 +21,13 @@ abstract class InputField extends Field /** * {@inheritDoc} */ - public function render(array $attributes = array()) + public function getAttributes() { - return $this->generator->tag('input', array_merge(array( - 'id' => $this->getId(), - 'name' => $this->getName(), - 'value' => $this->getDisplayedData(), - 'disabled' => $this->isDisabled(), - ), $attributes)); + return array_merge(parent::getAttributes(), array( + 'id' => $this->getId(), + 'name' => $this->getName(), + 'value' => $this->getDisplayedData(), + 'disabled' => $this->isDisabled(), + )); } } diff --git a/src/Symfony/Component/Form/MoneyField.php b/src/Symfony/Component/Form/MoneyField.php index 06c50547f89ac..f603bf143af89 100644 --- a/src/Symfony/Component/Form/MoneyField.php +++ b/src/Symfony/Component/Form/MoneyField.php @@ -47,37 +47,25 @@ protected function configure() ))); } - /** - * {@inheritDoc} - */ - public function render(array $attributes = array()) - { - $input = parent::render($attributes); - - if ($this->getOption('currency')) { - return str_replace('%widget%', $input, $this->getPattern($this->locale, $this->getOption('currency'))); - } else { - return $input; - } - } - /** * Returns the pattern for this locale * - * The pattern contains the placeholder "%widget%" where the HTML tag should + * The pattern contains the placeholder "{{ widget }}" where the HTML tag should * be inserted - * - * @param string $locale */ - protected static function getPattern($locale, $currency) + protected function getPattern() { - if (!isset(self::$patterns[$locale])) { - self::$patterns[$locale] = array(); + if (!$this->getOption('currency')) { + return '{{ widget }}'; + } + + if (!isset(self::$patterns[$this->locale])) { + self::$patterns[$this->locale] = array(); } - if (!isset(self::$patterns[$locale][$currency])) { - $format = new \NumberFormatter($locale, \NumberFormatter::CURRENCY); - $pattern = $format->formatCurrency('123', $currency); + if (!isset(self::$patterns[$this->locale][$this->getOption('currency')])) { + $format = new \NumberFormatter($this->locale, \NumberFormatter::CURRENCY); + $pattern = $format->formatCurrency('123', $this->getOption('currency')); // the spacings between currency symbol and number are ignored, because // a single space leads to better readability in combination with input @@ -88,14 +76,14 @@ protected static function getPattern($locale, $currency) preg_match('/^([^\s\xc2\xa0]*)[\s\xc2\xa0]*123[,.]00[\s\xc2\xa0]*([^\s\xc2\xa0]*)$/', $pattern, $matches); if (!empty($matches[1])) { - self::$patterns[$locale] = $matches[1].' %widget%'; + self::$patterns[$this->locale] = $matches[1].' {{ widget }}'; } else if (!empty($matches[2])) { - self::$patterns[$locale] = '%widget% '.$matches[2]; + self::$patterns[$this->locale] = '{{ widget }} '.$matches[2]; } else { - self::$patterns[$locale] = '%widget%'; + self::$patterns[$this->locale] = '{{ widget }}'; } } - return self::$patterns[$locale]; + return self::$patterns[$this->locale]; } -} \ No newline at end of file +} diff --git a/src/Symfony/Component/Form/NumberField.php b/src/Symfony/Component/Form/NumberField.php index 46169bf33945b..24a45b25a773a 100644 --- a/src/Symfony/Component/Form/NumberField.php +++ b/src/Symfony/Component/Form/NumberField.php @@ -40,10 +40,10 @@ protected function configure() /** * {@inheritDoc} */ - public function render(array $attributes = array()) + public function getAttributes(array $attributes = array()) { - return parent::render(array_merge(array( + return array_merge(parent::getAttributes(), array( 'type' => 'text', - ), $attributes)); + )); } } diff --git a/src/Symfony/Component/Form/PasswordField.php b/src/Symfony/Component/Form/PasswordField.php index 01817deabb834..83698c66d2077 100644 --- a/src/Symfony/Component/Form/PasswordField.php +++ b/src/Symfony/Component/Form/PasswordField.php @@ -31,11 +31,11 @@ protected function configure() /** * {@inheritDoc} */ - public function render(array $attributes = array()) + public function getAttributes() { - return parent::render(array_merge(array( + return array_merge(parent::getAttributes(), array( 'value' => $this->getOption('always_empty') && !$this->isBound() ? '' : $this->getDisplayedData(), 'type' => 'password', - ), $attributes)); + )); } } \ No newline at end of file diff --git a/src/Symfony/Component/Form/PercentField.php b/src/Symfony/Component/Form/PercentField.php index 88075f8132f3a..4d3467a568d69 100644 --- a/src/Symfony/Component/Form/PercentField.php +++ b/src/Symfony/Component/Form/PercentField.php @@ -36,12 +36,4 @@ protected function configure() 'type' => $this->getOption('type'), ))); } - - /** - * {@inheritDoc} - */ - public function render(array $attributes = array()) - { - return parent::render($attributes).' %'; - } } diff --git a/src/Symfony/Component/Form/RadioField.php b/src/Symfony/Component/Form/RadioField.php index 56c5617f8bde7..e2546a5c27c22 100644 --- a/src/Symfony/Component/Form/RadioField.php +++ b/src/Symfony/Component/Form/RadioField.php @@ -21,11 +21,11 @@ class RadioField extends ToggleField /** * {@inheritDoc} */ - public function render(array $attributes = array()) + public function getAttributes() { - return parent::render(array_merge(array( + return array_merge(parent::getAttributes(), array( 'type' => 'radio', 'name' => $this->getParent() ? $this->getParent()->getName() : $this->getName(), - ), $attributes)); + )); } } diff --git a/src/Symfony/Component/Form/Renderer/Renderer.php b/src/Symfony/Component/Form/Renderer/Renderer.php deleted file mode 100644 index 76705334f7fef..0000000000000 --- a/src/Symfony/Component/Form/Renderer/Renderer.php +++ /dev/null @@ -1,88 +0,0 @@ - 'all', '/another/file.css' => 'screen,print') - * - * @return array An array of stylesheet paths - */ - public function getStylesheets() - { - return array(); - } - - /** - * Gets the JavaScript paths associated with the renderer. - * - * @return array An array of JavaScript paths - */ - public function getJavaScripts() - { - return array(); - } - - /** - * {@inheritDoc} - */ - public function renderErrors(FieldInterface $field) - { - $html = ''; - - if ($field->hasErrors()) { - $html .= "
    \n"; - - foreach ($field->getErrors() as $error) { - $html .= "
  • " . $error . "
  • \n"; - } - - $html .= "
\n"; - } - - return $html; - } - - /** - * {@inheritDoc} - */ - public function setTranslator(TranslatorInterface $translator) - { - // TODO - } - - /** - * {@inheritDoc} - */ - public function setLocale($locale) - { - // TODO - } - - /** - * {@inheritDoc} - */ - public function setGenerator(HtmlGeneratorInterface $generator) - { - $this->generator = $generator; - } -} diff --git a/src/Symfony/Component/Form/Renderer/RendererInterface.php b/src/Symfony/Component/Form/Renderer/RendererInterface.php deleted file mode 100644 index e7186259c805e..0000000000000 --- a/src/Symfony/Component/Form/Renderer/RendererInterface.php +++ /dev/null @@ -1,45 +0,0 @@ - - */ -interface RendererInterface extends Localizable, Translatable -{ - /** - * Sets the generator used for rendering the HTML - * - * @param HtmlGeneratorInterface $generator - */ - public function setGenerator(HtmlGeneratorInterface $generator); - - /** - * Returns the textual representation of the given field. - * - * @param FieldInterface $field The form field - * @param array $attributes The attributes to include in the - * rendered output - * @return string The rendered output - * @throws InvalidArgumentException If the $field is not instance of the - * expected class - */ - public function render(FieldInterface $field, array $attributes = array()); - - /** - * Returns the textual representation of the errors of the given field. - * - * @param FieldInterface $field The form field - * @return string The rendered output - * @throws InvalidArgumentException If the $field is not instance of the - * expected class - */ - public function renderErrors(FieldInterface $field); -} \ No newline at end of file diff --git a/src/Symfony/Component/Form/Renderer/TableRenderer.php b/src/Symfony/Component/Form/Renderer/TableRenderer.php deleted file mode 100644 index 23adfe9235ea0..0000000000000 --- a/src/Symfony/Component/Form/Renderer/TableRenderer.php +++ /dev/null @@ -1,52 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * Renders a field group as HTML table - * - * @author Bernhard Schussek - */ -class TableRenderer extends Renderer -{ - /** - * {@inheritDoc} - */ - public function render(FieldInterface $group, array $attributes = array()) - { - $html = "\n"; - - foreach ($group as $field) { - $label = self::humanize($field->getKey()); - - $html .= "\n"; - $html .= "\n"; - $html .= ""; - $html .= "\n"; - } - - $html .= "
\n"; - if ($field->hasErrors()) { - $html .= $field->renderErrors()."\n"; - } - $html .= $field->render()."\n"; - $html .= "
\n"; - - return $html; - } - - protected static function humanize($text) - { - return ucfirst(strtolower(str_replace('_', ' ', $text))); - } -} diff --git a/src/Symfony/Component/Form/TextField.php b/src/Symfony/Component/Form/TextField.php index 973be1e24d16c..7f994124db8cd 100644 --- a/src/Symfony/Component/Form/TextField.php +++ b/src/Symfony/Component/Form/TextField.php @@ -31,11 +31,11 @@ protected function configure() /** * {@inheritDoc} */ - public function render(array $attributes = array()) + public function getAttributes() { - return parent::render(array_merge(array( + return array_merge(parent::getAttributes(), array( 'type' => 'text', 'maxlength' => $this->getOption('max_length'), - ), $attributes)); + )); } } diff --git a/src/Symfony/Component/Form/TextareaField.php b/src/Symfony/Component/Form/TextareaField.php index e553da54a9a9a..369b7cfc7de6d 100644 --- a/src/Symfony/Component/Form/TextareaField.php +++ b/src/Symfony/Component/Form/TextareaField.php @@ -21,15 +21,13 @@ class TextareaField extends Field /** * {@inheritDoc} */ - public function render(array $attributes = array()) + public function getAttributes() { - $content = $this->generator->escape($this->getDisplayedData()); - - return $this->generator->contentTag('textarea', $content, array_merge(array( + return array_merge(parent::getAttributes(), array( 'id' => $this->getId(), 'name' => $this->getName(), 'rows' => 4, 'cols' => 30, - ), $attributes)); + )); } } diff --git a/src/Symfony/Component/Form/TimeField.php b/src/Symfony/Component/Form/TimeField.php index 2a2bf56cdb06a..63bcae43fd564 100644 --- a/src/Symfony/Component/Form/TimeField.php +++ b/src/Symfony/Component/Form/TimeField.php @@ -107,25 +107,23 @@ protected function configure() $this->setValueTransformer(new ValueTransformerChain($transformers)); } + public function isField() + { + return self::INPUT === $this->getOption('widget'); + } + /** * {@inheritDoc} */ - public function render(array $attributes = array()) + public function getAttributes() { - if ($this->getOption('widget') == self::INPUT) { - $attributes = array_merge(array( + if ($this->isField()) { + return array_merge(parent::getAttributes(), array( 'size' => '1', - ), $attributes); - } - - $html = $this->get('hour')->render($attributes); - $html .= ':' . $this->get('minute')->render($attributes); - - if ($this->getOption('with_seconds')) { - $html .= ':' . $this->get('second')->render($attributes); + )); } - return $html; + return parent::getAttributes(); } /** diff --git a/src/Symfony/Component/Form/ToggleField.php b/src/Symfony/Component/Form/ToggleField.php index 4c7064bd96059..ff6e89d369f04 100644 --- a/src/Symfony/Component/Form/ToggleField.php +++ b/src/Symfony/Component/Form/ToggleField.php @@ -27,7 +27,6 @@ protected function configure() { $this->addOption('value'); $this->addOption('label'); - $this->addOption('translate_label', false); $this->setValueTransformer(new BooleanToStringTransformer()); } @@ -35,23 +34,11 @@ protected function configure() /** * {@inheritDoc} */ - public function render(array $attributes = array()) + public function getAttributes() { - $html = parent::render(array_merge(array( - 'value' => $this->getOption('value'), - 'checked' => ((string)$this->getDisplayedData() !== '' && $this->getDisplayedData() !== 0), - ), $attributes)); - - if ($label = $this->getOption('label')) { - if ($this->getOption('translate_label')) { - $label = $this->translate($label); - } - - $html .= ' '.$this->generator->contentTag('label', $label, array( - 'for' => $this->getId(), - )); - } - - return $html; + return array_merge(parent::getAttributes(), array( + 'value' => $this->getOption('value'), + 'checked' => (string) $this->getDisplayedData() !== '' && $this->getDisplayedData() !== 0, + )); } } diff --git a/src/Symfony/Component/Form/Translatable.php b/src/Symfony/Component/Form/Translatable.php deleted file mode 100644 index 275d801564362..0000000000000 --- a/src/Symfony/Component/Form/Translatable.php +++ /dev/null @@ -1,20 +0,0 @@ - - */ -interface Translatable -{ - /** - * Sets the translator unit of the class. - * - * @param TranslatorInterface $translator - */ - public function setTranslator(TranslatorInterface $translator); -} diff --git a/src/Symfony/Component/I18N/TranslatorInterface.php b/src/Symfony/Component/I18N/TranslatorInterface.php deleted file mode 100644 index d94954abc33ad..0000000000000 --- a/src/Symfony/Component/I18N/TranslatorInterface.php +++ /dev/null @@ -1,22 +0,0 @@ - - */ -interface TranslatorInterface -{ - /** - * Translates a given text string. - * - * @param string $text The text to translate - * @param array $parameters The parameters to inject into the text - * @param string $locale The locale of the translated text. If null, - * the preconfigured locale of the translator - * or the system's default culture is used. - */ - public function translate($text, array $parameters = array(), $locale = null); -} \ No newline at end of file diff --git a/tests/Symfony/Tests/Component/Form/CheckboxFieldTest.php b/tests/Symfony/Tests/Component/Form/CheckboxFieldTest.php deleted file mode 100644 index 9147cff5ee181..0000000000000 --- a/tests/Symfony/Tests/Component/Form/CheckboxFieldTest.php +++ /dev/null @@ -1,20 +0,0 @@ -setData(true); - - $html = ''; - - $this->assertEquals($html, $field->render(array( - 'class' => 'foobar', - ))); - } -} \ No newline at end of file diff --git a/tests/Symfony/Tests/Component/Form/ChoiceFieldTest.php b/tests/Symfony/Tests/Component/Form/ChoiceFieldTest.php index 1d5405107652c..00450df19c9ae 100644 --- a/tests/Symfony/Tests/Component/Form/ChoiceFieldTest.php +++ b/tests/Symfony/Tests/Component/Form/ChoiceFieldTest.php @@ -72,165 +72,6 @@ public function testBindSingleNonExpanded() $this->assertEquals('b', $field->getDisplayedData()); } - public function testRenderSingleNonExpanded() - { - $field = new ChoiceField('name', array( - 'multiple' => false, - 'expanded' => false, - 'choices' => $this->choices, - )); - - $field->setData('b'); - - $html = << - - - - - - -EOF; - - $this->assertEquals($html, $field->render(array( - 'class' => 'foobar', - ))); - } - - public function testRenderSingleNonExpanded_translateChoices() - { - $translator = $this->getMock('Symfony\Component\I18N\TranslatorInterface'); - $translator->expects($this->any()) - ->method('translate') - ->will($this->returnCallback(function($text) { - return 'translated['.$text.']'; - })); - - $field = new ChoiceField('name', array( - 'multiple' => false, - 'expanded' => false, - 'choices' => $this->choices, - 'translate_choices' => true, - )); - - $field->setTranslator($translator); - $field->setData('b'); - - $html = << - - - - - - -EOF; - - $this->assertEquals($html, $field->render(array( - 'class' => 'foobar', - ))); - } - - public function testRenderSingleNonExpanded_disabled() - { - $field = new ChoiceField('name', array( - 'multiple' => false, - 'expanded' => false, - 'choices' => $this->choices, - 'disabled' => true, - )); - - - $html = << - - - - - - -EOF; - - $this->assertEquals($html, $field->render()); - } - - public function testRenderSingleNonExpandedWithPreferred() - { - $field = new ChoiceField('name', array( - 'multiple' => false, - 'expanded' => false, - 'choices' => $this->choices, - 'preferred_choices' => $this->preferredChoices, - 'separator' => '---', - )); - - $field->setData('d'); - - $html = << - - - - - - - -EOF; - - $this->assertEquals($html, $field->render()); - } - - public function testRenderSingleNonExpandedWithGroups() - { - $field = new ChoiceField('name', array( - 'multiple' => false, - 'expanded' => false, - 'choices' => $this->groupedChoices, - )); - - $html = << - - - - - - - - - - -EOF; - - $this->assertEquals($html, $field->render()); - } - - public function testRenderSingleNonExpandedNonRequired() - { - $field = new ChoiceField('name', array( - 'multiple' => false, - 'expanded' => false, - 'choices' => $this->choices, - 'empty_value' => 'empty', - )); - - $field->setData(null); - $field->setRequired(false); - - $html = << - - - - - - - -EOF; - - $this->assertEquals($html, $field->render()); - } - public function testBindMultipleNonExpanded() { $field = new ChoiceField('name', array( @@ -245,29 +86,6 @@ public function testBindMultipleNonExpanded() $this->assertEquals(array('a', 'b'), $field->getDisplayedData()); } - public function testRenderMultipleNonExpanded() - { - $field = new ChoiceField('name', array( - 'multiple' => true, - 'expanded' => false, - 'choices' => $this->choices, - )); - - $field->setData(array('a', 'b')); - - $html = << - - - - - - -EOF; - - $this->assertEquals($html, $field->render()); - } - public function testBindSingleExpanded() { $field = new ChoiceField('name', array( @@ -316,80 +134,6 @@ public function testBindSingleExpandedNumericChoices() $this->assertSame(array(0 => '', 1 => '1', 2 => '', 3 => '', 4 => ''), $field->getDisplayedData()); } - public function testRenderSingleExpanded() - { - $field = new ChoiceField('name', array( - 'multiple' => false, - 'expanded' => true, - 'choices' => $this->choices, - )); - - $field->setData('b'); - - $html = << - - - - - -EOF; - - $this->assertEquals($html, $field->render()); - } - - public function testRenderSingleExpanded_translateChoices() - { - $translator = $this->getMock('Symfony\Component\I18N\TranslatorInterface'); - $translator->expects($this->any()) - ->method('translate') - ->will($this->returnCallback(function($text) { - return 'translated['.$text.']'; - })); - - $field = new ChoiceField('name', array( - 'multiple' => false, - 'expanded' => true, - 'choices' => $this->choices, - 'translate_choices' => true, - )); - - $field->setTranslator($translator); - $field->setData('b'); - - $html = << - - - - - -EOF; - - $this->assertEquals($html, $field->render()); - } - - public function testRenderSingleExpandedWithPreferred() - { - $field = new ChoiceField('name', array( - 'multiple' => false, - 'expanded' => true, - 'choices' => $this->choices, - 'preferred_choices' => $this->preferredChoices, - )); - - $html = << - - - - - -EOF; - - $this->assertEquals($html, $field->render()); - } - public function testBindMultipleExpanded() { $field = new ChoiceField('name', array( @@ -437,26 +181,4 @@ public function testBindMultipleExpandedNumericChoices() $this->assertSame('', $field[4]->getDisplayedData()); $this->assertSame(array(0 => '', 1 => '1', 2 => '1', 3 => '', 4 => ''), $field->getDisplayedData()); } - - public function testRenderMultipleExpanded() - { - $field = new ChoiceField('name', array( - 'multiple' => true, - 'expanded' => true, - 'choices' => $this->choices, - )); - - $field->setData(array('a', 'b')); - - $html = << - - - - - -EOF; - - $this->assertEquals($html, $field->render()); - } } \ No newline at end of file diff --git a/tests/Symfony/Tests/Component/Form/DateFieldTest.php b/tests/Symfony/Tests/Component/Form/DateFieldTest.php index c313e5c41f1e1..10c1cf221a339 100644 --- a/tests/Symfony/Tests/Component/Form/DateFieldTest.php +++ b/tests/Symfony/Tests/Component/Form/DateFieldTest.php @@ -99,119 +99,4 @@ public function testSetData_differentTimezones() $this->assertEquals('01.06.2010', $field->getDisplayedData()); } - - public function testRenderAsInput() - { - $field = new DateField('name', array('widget' => 'input')); - - $field->setLocale('de_AT'); - $field->setData(new \DateTime('2010-06-02 UTC')); - - $html = ''; - - $this->assertEquals($html, $field->render(array( - 'class' => 'foobar', - ))); - } - - public function testRenderAsInputWithFormat() - { - $field = new DateField('name', array('widget' => 'input', 'format' => 'short')); - - $field->setLocale('de_AT'); - $field->setData(new \DateTime('2010-06-02 UTC')); - - $html = ''; - - $this->assertEquals($html, $field->render()); - } - - public function testRenderAsChoice() - { - $field = new DateField('name', array( - 'years' => array(2010, 2011), - 'months' => array(6, 7), - 'days' => array(1, 2), - 'widget' => DateField::CHOICE, - )); - - $field->setLocale('de_AT'); - $field->setData(new \DateTime('2010-06-02 UTC')); - - $html = << - - -.. -EOF; - - $this->assertEquals($html, $field->render(array( - 'class' => 'foobar', - ))); - } - - public function testRenderAsChoiceNonRequired() - { - $field = new DateField('name', array( - 'years' => array(2010, 2011), - 'months' => array(6, 7), - 'days' => array(1, 2), - 'widget' => DateField::CHOICE, - )); - - $field->setLocale('de_AT'); - $field->setRequired(false); - - $html = << - - - -.. -EOF; - - $this->assertEquals($html, $field->render()); - } - - public function testRenderAsChoiceWithPattern() - { - $field = new DateField('name', array( - 'years' => array(2010, 2011), - 'months' => array(6, 7), - 'days' => array(1, 2), - 'widget' => DateField::CHOICE, - 'pattern' => '%day%---%month%---%year%', - )); - - $field->setLocale('de_AT'); - - $html = << - - ------- -EOF; - - $this->assertEquals($html, $field->render()); - } } \ No newline at end of file diff --git a/tests/Symfony/Tests/Component/Form/DateTimeFieldTest.php b/tests/Symfony/Tests/Component/Form/DateTimeFieldTest.php index 270dd0db9cef9..f25cd7fc924d5 100644 --- a/tests/Symfony/Tests/Component/Form/DateTimeFieldTest.php +++ b/tests/Symfony/Tests/Component/Form/DateTimeFieldTest.php @@ -151,50 +151,4 @@ public function testBind_differentTimezones() $this->assertEquals($dateTime->format('Y-m-d H:i:s'), $field->getData()); } - - public function testRender() - { - $field = new DateTimeField('name', array( - 'years' => array(2010, 2011), - 'months' => array(6, 7), - 'days' => array(1, 2), - 'hours' => array(3, 4), - 'minutes' => array(5, 6), - 'seconds' => array(7, 8), - 'data_timezone' => 'UTC', - 'user_timezone' => 'UTC', - 'date_widget' => DateField::CHOICE, - 'time_widget' => TimeField::CHOICE, - 'type' => DateTimeField::DATETIME, - 'with_seconds' => true, - )); - - $field->setLocale('de_AT'); - $field->setData(new \DateTime('2010-06-02 03:04:05 UTC')); - - $html = << - - -.. -:: -EOF; - - $this->assertEquals($html, $field->render(array('class' => 'foobar'))); - } } \ No newline at end of file diff --git a/tests/Symfony/Tests/Component/Form/FieldGroupTest.php b/tests/Symfony/Tests/Component/Form/FieldGroupTest.php index af0c3c4dc8659..79d2e4a723c32 100644 --- a/tests/Symfony/Tests/Component/Form/FieldGroupTest.php +++ b/tests/Symfony/Tests/Component/Form/FieldGroupTest.php @@ -153,7 +153,7 @@ public function testAddErrorMapsFieldValidationErrorsOntoFields() $group = new FieldGroup('author'); $group->add($field); - $group->addError('Message', new PropertyPath('fields[firstName].data'), FieldGroup::FIELD_ERROR); + $group->addError('Message', array(), new PropertyPath('fields[firstName].data'), FieldGroup::FIELD_ERROR); } public function testAddErrorMapsFieldValidationErrorsOntoFieldsWithinNestedFieldGroups() @@ -168,7 +168,7 @@ public function testAddErrorMapsFieldValidationErrorsOntoFieldsWithinNestedField $innerGroup->add($field); $group->add($innerGroup); - $group->addError('Message', new PropertyPath('fields[names].fields[firstName].data'), FieldGroup::FIELD_ERROR); + $group->addError('Message', array(), new PropertyPath('fields[names].fields[firstName].data'), FieldGroup::FIELD_ERROR); } public function testAddErrorKeepsFieldValidationErrorsIfFieldNotFound() @@ -180,9 +180,9 @@ public function testAddErrorKeepsFieldValidationErrorsIfFieldNotFound() $group = new FieldGroup('author'); $group->add($field); - $group->addError('Message', new PropertyPath('fields[bar].data'), FieldGroup::FIELD_ERROR); + $group->addError('Message', array(), new PropertyPath('fields[bar].data'), FieldGroup::FIELD_ERROR); - $this->assertEquals(array('Message'), $group->getErrors()); + $this->assertEquals(array(array('Message', array())), $group->getErrors()); } public function testAddErrorKeepsFieldValidationErrorsIfFieldIsHidden() @@ -197,9 +197,9 @@ public function testAddErrorKeepsFieldValidationErrorsIfFieldIsHidden() $group = new FieldGroup('author'); $group->add($field); - $group->addError('Message', new PropertyPath('fields[firstName].data'), FieldGroup::FIELD_ERROR); + $group->addError('Message', array(), new PropertyPath('fields[firstName].data'), FieldGroup::FIELD_ERROR); - $this->assertEquals(array('Message'), $group->getErrors()); + $this->assertEquals(array(array('Message', array())), $group->getErrors()); } public function testAddErrorMapsDataValidationErrorsOntoFields() @@ -213,12 +213,12 @@ public function testAddErrorMapsDataValidationErrorsOntoFields() ->will($this->returnValue(new PropertyPath('firstName'))); $field->expects($this->once()) ->method('addError') - ->with($this->equalTo('Message'), $this->equalTo($expectedPath), $this->equalTo(FieldGroup::DATA_ERROR)); + ->with($this->equalTo('Message'), array(), $this->equalTo($expectedPath), $this->equalTo(FieldGroup::DATA_ERROR)); $group = new FieldGroup('author'); $group->add($field); - $group->addError('Message', new PropertyPath('firstName'), FieldGroup::DATA_ERROR); + $group->addError('Message', array(), new PropertyPath('firstName'), FieldGroup::DATA_ERROR); } public function testAddErrorKeepsDataValidationErrorsIfFieldNotFound() @@ -233,7 +233,7 @@ public function testAddErrorKeepsDataValidationErrorsIfFieldNotFound() $group = new FieldGroup('author'); $group->add($field); - $group->addError('Message', new PropertyPath('bar'), FieldGroup::DATA_ERROR); + $group->addError('Message', array(), new PropertyPath('bar'), FieldGroup::DATA_ERROR); } public function testAddErrorKeepsDataValidationErrorsIfFieldIsHidden() @@ -251,7 +251,7 @@ public function testAddErrorKeepsDataValidationErrorsIfFieldIsHidden() $group = new FieldGroup('author'); $group->add($field); - $group->addError('Message', new PropertyPath('firstName'), FieldGroup::DATA_ERROR); + $group->addError('Message', array(), new PropertyPath('firstName'), FieldGroup::DATA_ERROR); } public function testAddErrorMapsDataValidationErrorsOntoNestedFields() @@ -266,12 +266,12 @@ public function testAddErrorMapsDataValidationErrorsOntoNestedFields() ->will($this->returnValue(new PropertyPath('address'))); $field->expects($this->once()) ->method('addError') - ->with($this->equalTo('Message'), $this->equalTo($expectedPath), $this->equalTo(FieldGroup::DATA_ERROR)); + ->with($this->equalTo('Message'), array(), $this->equalTo($expectedPath), $this->equalTo(FieldGroup::DATA_ERROR)); $group = new FieldGroup('author'); $group->add($field); - $group->addError('Message', new PropertyPath('address.street'), FieldGroup::DATA_ERROR); + $group->addError('Message', array(), new PropertyPath('address.street'), FieldGroup::DATA_ERROR); } public function testAddErrorMapsErrorsOntoFieldsInAnonymousGroups() @@ -285,14 +285,14 @@ public function testAddErrorMapsErrorsOntoFieldsInAnonymousGroups() ->will($this->returnValue(new PropertyPath('address'))); $field->expects($this->once()) ->method('addError') - ->with($this->equalTo('Message'), $this->equalTo($expectedPath), $this->equalTo(FieldGroup::DATA_ERROR)); + ->with($this->equalTo('Message'), array(), $this->equalTo($expectedPath), $this->equalTo(FieldGroup::DATA_ERROR)); $group = new FieldGroup('author'); $group2 = new FieldGroup('anonymous', array('property_path' => null)); $group2->add($field); $group->add($group2); - $group->addError('Message', new PropertyPath('address'), FieldGroup::DATA_ERROR); + $group->addError('Message', array(), new PropertyPath('address'), FieldGroup::DATA_ERROR); } public function testAddThrowsExceptionIfAlreadyBound() @@ -540,80 +540,6 @@ public function testIsNotMultipartIfNoFieldIsMultipart() $this->assertFalse($group->isMultipart()); } - public function testRenderForwardsToRenderer() - { - $group = new FieldGroup('author'); - - $renderer = $this->createMockRenderer(); - $renderer->expects($this->once()) - ->method('render') - ->with($this->equalTo($group), $this->equalTo(array('foo' => 'bar'))) - ->will($this->returnValue('HTML')); - - $group->setRenderer($renderer); - - // test - $output = $group->render(array('foo' => 'bar')); - - $this->assertEquals('HTML', $output); - } - - public function testRenderErrorsForwardsToRenderer() - { - $group = new FieldGroup('author'); - - $renderer = $this->createMockRenderer(); - $renderer->expects($this->once()) - ->method('renderErrors') - ->with($this->equalTo($group)) - ->will($this->returnValue('HTML')); - - $group->setRenderer($renderer); - - // test - $output = $group->renderErrors(); - - $this->assertEquals('HTML', $output); - } - - public function testLocaleIsPassedToRenderer() - { - $renderer = $this->getMock('Symfony\Component\Form\Renderer\RendererInterface'); - $renderer->expects($this->once()) - ->method('setLocale') - ->with($this->equalTo('de_DE')); - - $group = new FieldGroup('author'); - $group->setRenderer($renderer); - $group->setLocale('de_DE'); - $group->render(); - } - - public function testTranslatorIsPassedToRenderer() - { - $translator = $this->getMock('Symfony\Component\I18N\TranslatorInterface'); - $renderer = $this->getMock('Symfony\Component\Form\Renderer\RendererInterface'); - $renderer->expects($this->once()) - ->method('setTranslator') - ->with($this->equalTo($translator)); - - $group = new FieldGroup('author'); - $group->setRenderer($renderer); - $group->setTranslator($translator); - $group->render(); - } - - public function testTranslatorIsNotPassedToRendererIfNotSet() - { - $renderer = $this->getMock('Symfony\Component\Form\Renderer\RendererInterface'); - $renderer->expects($this->never()) - ->method('setTranslator'); - - $group = new FieldGroup('author'); - $group->setRenderer($renderer); - $group->render(); - } - public function testLocaleIsPassedToField_SetBeforeAddingTheField() { $field = $this->getMock('Symfony\Component\Form\Field', array(), array(), '', false, false); @@ -651,51 +577,6 @@ public function testLocaleIsPassedToField_SetAfterAddingTheField() $this->assertEquals(array(class_exists('\Locale', false) ? \Locale::getDefault() : 'en', 'de_DE'), $field->locales); } - public function testTranslatorIsPassedToField_SetBeforeAddingTheField() - { - $translator = $this->getMock('Symfony\Component\I18N\TranslatorInterface'); - $field = $this->getMock('Symfony\Component\Form\Field', array(), array(), '', false, false); - $field->expects($this->any()) - ->method('getKey') - ->will($this->returnValue('firstName')); - $field->expects($this->once()) - ->method('setTranslator') - ->with($this->equalTo($translator)); - - $group = new FieldGroup('author'); - $group->setTranslator($translator); - $group->add($field); - } - - public function testTranslatorIsPassedToField_SetAfterAddingTheField() - { - $translator = $this->getMock('Symfony\Component\I18N\TranslatorInterface'); - $field = $this->getMock('Symfony\Component\Form\Field', array(), array(), '', false, false); - $field->expects($this->any()) - ->method('getKey') - ->will($this->returnValue('firstName')); - $field->expects($this->once()) - ->method('setTranslator') - ->with($this->equalTo($translator)); - - $group = new FieldGroup('author'); - $group->add($field); - $group->setTranslator($translator); - } - - public function testTranslatorIsNotPassedToFieldIfNotSet() - { - $field = $this->getMock('Symfony\Component\Form\Field', array(), array(), '', false, false); - $field->expects($this->any()) - ->method('getKey') - ->will($this->returnValue('firstName')); - $field->expects($this->never()) - ->method('setTranslator'); - - $group = new FieldGroup('author'); - $group->add($field); - } - public function testSupportsClone() { $group = new FieldGroup('author'); @@ -722,33 +603,6 @@ public function testBindWithoutPriorSetData() $this->assertEquals(array('firstName' => 'Bernhard'), $group->getData()); } - public function testSetGenerator_calledBeforeAdding() - { - $generator = $this->getMock('Symfony\Component\Form\HtmlGeneratorInterface'); - - $field = $this->createMockField('firstName'); - $field->expects($this->once()) - ->method('setGenerator') - ->with($this->equalTo($generator)); - - $group = new FieldGroup('author'); - $group->setGenerator($generator); - $group->add($field); - } - - public function testSetGenerator_calledAfterAdding() - { - $generator = $this->getMock('Symfony\Component\Form\HtmlGeneratorInterface'); - - $field = $this->createMockField('firstName'); - $field->expects($this->exactly(2)) // cannot test different arguments :( - ->method('setGenerator'); - - $group = new FieldGroup('author'); - $group->add($field); - $group->setGenerator($generator); - } - protected function createMockField($key) { $field = $this->getMock( @@ -807,11 +661,6 @@ protected function createMultipartMockField($key) return $field; } - protected function createMockRenderer() - { - return $this->getMock('Symfony\Component\Form\Renderer\RendererInterface'); - } - protected function createMockTransformer() { return $this->getMock('Symfony\Component\Form\ValueTransformer\ValueTransformerInterface', array(), array(), '', false, false); diff --git a/tests/Symfony/Tests/Component/Form/FormTest.php b/tests/Symfony/Tests/Component/Form/FormTest.php index f5829c8fd7acc..31831e3ef2d75 100644 --- a/tests/Symfony/Tests/Component/Form/FormTest.php +++ b/tests/Symfony/Tests/Component/Form/FormTest.php @@ -9,7 +9,6 @@ use Symfony\Component\Form\Field; use Symfony\Component\Form\HiddenField; use Symfony\Component\Form\FieldGroup; -use Symfony\Component\Form\HtmlGenerator; use Symfony\Component\Form\PropertyPath; use Symfony\Component\Validator\ConstraintViolation; use Symfony\Component\Validator\ConstraintViolationList; @@ -175,23 +174,6 @@ public function testDefaultLocaleCanBeSet() $form->add($field); } - public function testDefaultTranslatorCanBeSet() - { - $translator = $this->getMock('Symfony\Component\I18N\TranslatorInterface'); - Form::setDefaultTranslator($translator); - $form = new Form('author', new Author(), $this->validator); - - $field = $this->getMock('Symfony\Component\Form\Field', array(), array(), '', false, false); - $field->expects($this->any()) - ->method('getKey') - ->will($this->returnValue('firstName')); - $field->expects($this->once()) - ->method('setTranslator') - ->with($this->equalTo($translator)); - - $form->add($field); - } - public function testValidationGroupsCanBeSet() { $form = new Form('author', new Author(), $this->validator); @@ -241,30 +223,6 @@ public function testMultipartFormsWithParentsRequireNoFiles() $form->bind(array('file' => 'test.txt')); } - public function testRenderFormTagProducesValidXhtml() - { - $form = new Form('author', new Author(), $this->validator); - - $this->assertEquals('
', $form->renderFormTag('url')); - } - - public function testSetCharsetAdjustsGenerator() - { - $form = $this->getMock( - 'Symfony\Component\Form\Form', - array('setGenerator'), - array(), - '', - false // don't call original constructor - ); - - $form->expects($this->once()) - ->method('setGenerator') - ->with($this->equalTo(new HtmlGenerator('iso-8859-1'))); - - $form->setCharset('iso-8859-1'); - } - protected function createMockField($key) { $field = $this->getMock( diff --git a/tests/Symfony/Tests/Component/Form/HiddenFieldTest.php b/tests/Symfony/Tests/Component/Form/HiddenFieldTest.php index 2b5ba1a297947..de8ec74aaeee7 100644 --- a/tests/Symfony/Tests/Component/Form/HiddenFieldTest.php +++ b/tests/Symfony/Tests/Component/Form/HiddenFieldTest.php @@ -13,17 +13,6 @@ public function setUp() $this->field = new HiddenField('name'); } - public function testRender() - { - $this->field->setData('foobar'); - - $html = ''; - - $this->assertEquals($html, $this->field->render(array( - 'class' => 'foobar', - ))); - } - public function testIsHidden() { $this->assertTrue($this->field->isHidden()); diff --git a/tests/Symfony/Tests/Component/Form/HtmlGeneratorTest.php b/tests/Symfony/Tests/Component/Form/HtmlGeneratorTest.php deleted file mode 100644 index 087a76c374bdb..0000000000000 --- a/tests/Symfony/Tests/Component/Form/HtmlGeneratorTest.php +++ /dev/null @@ -1,91 +0,0 @@ -generator = new HtmlGenerator(); - } - - public function testEscape() - { - $this->assertEquals('<&abcd', $this->generator->escape('<&abcd')); - } - - public function testEscapeOnlyOnce() - { - $this->assertEquals('<&abcd', $this->generator->escape('<&abcd')); - } - - public function testAttribute() - { - $this->assertEquals('foo="bar"', $this->generator->attribute('foo', 'bar')); - } - - public function testEscapeAttribute() - { - $this->assertEquals('foo="<>"', $this->generator->attribute('foo', '<>')); - } - - public function testXhtmlAttribute() - { - HtmlGenerator::setXhtml(true); - $this->assertEquals('foo="foo"', $this->generator->attribute('foo', true)); - } - - public function testNonXhtmlAttribute() - { - HtmlGenerator::setXhtml(false); - $this->assertEquals('foo', $this->generator->attribute('foo', true)); - } - - public function testAttributes() - { - $html = $this->generator->attributes(array( - 'foo' => 'bar', - 'bar' => 'baz', - )); - $this->assertEquals(' foo="bar" bar="baz"', $html); - } - - public function testXhtmlTag() - { - HtmlGenerator::setXhtml(true); - $html = $this->generator->tag('input', array( - 'type' => 'text', - )); - $this->assertEquals('', $html); - } - - public function testNonXhtmlTag() - { - HtmlGenerator::setXhtml(false); - $html = $this->generator->tag('input', array( - 'type' => 'text', - )); - $this->assertEquals('', $html); - } - - public function testContentTag() - { - $html = $this->generator->contentTag('p', 'asdf', array( - 'class' => 'foo', - )); - $this->assertEquals('

asdf

', $html); - } - - // it should be possible to pass the output of the tag() method as body - // of the content tag - public function testDontEscapeContentTag() - { - $this->assertEquals('

<&

', $this->generator->contentTag('p', '<&')); - } - -} \ No newline at end of file diff --git a/tests/Symfony/Tests/Component/Form/InputFieldTest.php b/tests/Symfony/Tests/Component/Form/InputFieldTest.php deleted file mode 100644 index 79a27497586e0..0000000000000 --- a/tests/Symfony/Tests/Component/Form/InputFieldTest.php +++ /dev/null @@ -1,33 +0,0 @@ -setData('foobar'); - - $html = ''; - - $this->assertEquals($html, $field->render(array( - 'class' => 'foobar', - ))); - } - - public function testRender_disabled() - { - $field = new TestInputField('name', array('disabled' => true)); - $field->setData('foobar'); - - $html = ''; - - $this->assertEquals($html, $field->render()); - } -} \ No newline at end of file diff --git a/tests/Symfony/Tests/Component/Form/MoneyFieldTest.php b/tests/Symfony/Tests/Component/Form/MoneyFieldTest.php deleted file mode 100644 index 1208f65bff29e..0000000000000 --- a/tests/Symfony/Tests/Component/Form/MoneyFieldTest.php +++ /dev/null @@ -1,46 +0,0 @@ -setLocale('de_AT'); - $field->setData(1234); - - $html = ''; - - $this->assertEquals($html, $field->render(array('class' => 'foobar'))); - } - - public function testRenderWithCurrency_afterWidget() - { - $field = new MoneyField('name', array('currency' => 'EUR')); - - $field->setLocale('de_DE'); - $field->setData(1234); - - $html = ' €'; - - $this->assertEquals($html, $field->render()); - } - - public function testRenderWithCurrency_beforeWidget() - { - $field = new MoneyField('name', array('currency' => 'EUR')); - - $field->setLocale('en_US'); - $field->setData(1234); - - $html = '€ '; - - $this->assertEquals($html, $field->render()); - } -} \ No newline at end of file diff --git a/tests/Symfony/Tests/Component/Form/NumberFieldTest.php b/tests/Symfony/Tests/Component/Form/NumberFieldTest.php deleted file mode 100644 index d9986c3b93a1c..0000000000000 --- a/tests/Symfony/Tests/Component/Form/NumberFieldTest.php +++ /dev/null @@ -1,46 +0,0 @@ -setLocale('de_AT'); - $field->setData(1234.5678); - - $html = ''; - - $this->assertEquals($html, $field->render(array('class' => 'foobar'))); - } - - public function testRenderWithPrecision() - { - $field = new NumberField('name', array('precision' => 4)); - - $field->setLocale('de_AT'); - $field->setData(1234.5678); - - $html = ''; - - $this->assertEquals($html, $field->render()); - } - - public function testRenderWithGrouping() - { - $field = new NumberField('name', array('grouping' => true)); - - $field->setLocale('de_AT'); - $field->setData(1234.5678); - - $html = ''; - - $this->assertEquals($html, $field->render()); - } -} \ No newline at end of file diff --git a/tests/Symfony/Tests/Component/Form/PasswordFieldTest.php b/tests/Symfony/Tests/Component/Form/PasswordFieldTest.php deleted file mode 100644 index fd4099b5ea12a..0000000000000 --- a/tests/Symfony/Tests/Component/Form/PasswordFieldTest.php +++ /dev/null @@ -1,49 +0,0 @@ -setData('asdf'); - - $html = ''; - - $this->assertEquals($html, $field->render(array('class' => 'foobar'))); - } - - // when the user made an error in the form, display the value in the field - public function testRenderAfterBinding() - { - $field = new PasswordField('name'); - $field->bind('asdf'); - - $html = ''; - - $this->assertEquals($html, $field->render()); - } - - public function testRenderNotAlwaysEmpty() - { - $field = new PasswordField('name', array('always_empty' => false)); - $field->setData('asdf'); - - $html = ''; - - $this->assertEquals($html, $field->render()); - } - - public function testRenderNotAlwaysEmptyAfterBinding() - { - $field = new PasswordField('name', array('always_empty' => false)); - $field->bind('asdf'); - - $html = ''; - - $this->assertEquals($html, $field->render()); - } -} \ No newline at end of file diff --git a/tests/Symfony/Tests/Component/Form/PercentFieldTest.php b/tests/Symfony/Tests/Component/Form/PercentFieldTest.php deleted file mode 100644 index b7303760b808a..0000000000000 --- a/tests/Symfony/Tests/Component/Form/PercentFieldTest.php +++ /dev/null @@ -1,46 +0,0 @@ -setLocale('de_DE'); - $field->setData(0.12); - - $html = ' %'; - - $this->assertEquals($html, $field->render()); - } - - public function testRenderWithPrecision() - { - $field = new PercentField('name', array('precision' => 2)); - - $field->setLocale('de_DE'); - $field->setData(0.1234); - - $html = ' %'; - - $this->assertEquals($html, $field->render()); - } - - public function testRenderWithInteger() - { - $field = new PercentField('name', array('type' => 'integer')); - - $field->setLocale('de_DE'); - $field->setData(123); - - $html = ' %'; - - $this->assertEquals($html, $field->render()); - } -} \ No newline at end of file diff --git a/tests/Symfony/Tests/Component/Form/RadioFieldTest.php b/tests/Symfony/Tests/Component/Form/RadioFieldTest.php deleted file mode 100644 index 69674c92b1fa7..0000000000000 --- a/tests/Symfony/Tests/Component/Form/RadioFieldTest.php +++ /dev/null @@ -1,33 +0,0 @@ -setData(true); - - $html = ''; - - $this->assertEquals($html, $field->render(array( - 'class' => 'foobar', - ))); - } - - // when a radio button is in a field group, all radio buttons in that group - // should have the same name - public function testRenderParentName() - { - $field = new RadioField('name'); - $field->setParent(new FieldGroup('parent')); - - $html = ''; - - $this->assertEquals($html, $field->render()); - } -} \ No newline at end of file diff --git a/tests/Symfony/Tests/Component/Form/Renderer/RendererTestCase.php b/tests/Symfony/Tests/Component/Form/Renderer/RendererTestCase.php deleted file mode 100644 index 0d68b7cd47d36..0000000000000 --- a/tests/Symfony/Tests/Component/Form/Renderer/RendererTestCase.php +++ /dev/null @@ -1,23 +0,0 @@ -getMock('Symfony\Component\Form\FieldInterface'); - - $field->expects($this->any()) - ->method('getDisplayedData') - ->will($this->returnValue($displayedData)); - $field->expects($this->any()) - ->method('getName') - ->will($this->returnValue($name)); - $field->expects($this->any()) - ->method('getId') - ->will($this->returnValue($id)); - - return $field; - } -} diff --git a/tests/Symfony/Tests/Component/Form/TextFieldTest.php b/tests/Symfony/Tests/Component/Form/TextFieldTest.php deleted file mode 100644 index 2f7a00c13eeab..0000000000000 --- a/tests/Symfony/Tests/Component/Form/TextFieldTest.php +++ /dev/null @@ -1,28 +0,0 @@ -setData('asdf'); - - $html = ''; - - $this->assertEquals($html, $field->render(array('class' => 'foobar'))); - } - - public function testRenderWithMaxLength() - { - $field = new TextField('name', array('max_length' => 10)); - $field->setData('asdf'); - - $html = ''; - - $this->assertEquals($html, $field->render()); - } -} \ No newline at end of file diff --git a/tests/Symfony/Tests/Component/Form/TextareaFieldTest.php b/tests/Symfony/Tests/Component/Form/TextareaFieldTest.php deleted file mode 100644 index 15d822537d651..0000000000000 --- a/tests/Symfony/Tests/Component/Form/TextareaFieldTest.php +++ /dev/null @@ -1,28 +0,0 @@ -setData('asdf'); - - $html = ''; - - $this->assertEquals($html, $field->render(array('class' => 'foobar'))); - } - - public function testRenderEscapesValue() - { - $field = new TextareaField('name'); - $field->setData('<&&'); - - $html = ''; - - $this->assertEquals($html, $field->render()); - } -} \ No newline at end of file diff --git a/tests/Symfony/Tests/Component/Form/TimeFieldTest.php b/tests/Symfony/Tests/Component/Form/TimeFieldTest.php index c4a3d82476d05..00aaa29663638 100644 --- a/tests/Symfony/Tests/Component/Form/TimeFieldTest.php +++ b/tests/Symfony/Tests/Component/Form/TimeFieldTest.php @@ -133,128 +133,4 @@ public function testSetData_differentTimezones() $this->assertEquals($displayedData, $field->getDisplayedData()); } - - public function testRenderAsInputs() - { - $field = new TimeField('name', array( - 'widget' => TimeField::INPUT, - 'data_timezone' => 'UTC', - 'user_timezone' => 'UTC', - )); - - $field->setData(new \DateTime('04:05 UTC')); - - $html = << -: - -EOF; - - $this->assertEquals(str_replace("\n", '', $html), $field->render(array('class' => 'foobar'))); - } - - public function testRenderAsInputs_withSeconds() - { - $field = new TimeField('name', array( - 'widget' => TimeField::INPUT, - 'data_timezone' => 'UTC', - 'user_timezone' => 'UTC', - 'with_seconds' => true, - )); - - $field->setData(new \DateTime('04:05:06 UTC')); - - $html = << -: - -: - -EOF; - - $this->assertEquals(str_replace("\n", '', $html), $field->render(array('class' => 'foobar'))); - } - - public function testRenderAsChoices() - { - $field = new TimeField('name', array( - 'hours' => array(3, 4), - 'minutes' => array(5, 6), - 'widget' => TimeField::CHOICE, - 'data_timezone' => 'UTC', - 'user_timezone' => 'UTC', - )); - - $field->setData(new \DateTime('04:05 UTC')); - - $html = << - - -: -EOF; - - $this->assertEquals($html, $field->render(array('class' => 'foobar'))); - } - - public function testRenderAsChoices_withSeconds() - { - $field = new TimeField('name', array( - 'hours' => array(3, 4), - 'minutes' => array(5, 6), - 'seconds' => array(7, 8), - 'widget' => TimeField::CHOICE, - 'data_timezone' => 'UTC', - 'user_timezone' => 'UTC', - 'with_seconds' => true, - )); - - $field->setData(new \DateTime('04:05:07 UTC')); - - $html = << - - -:: -EOF; - - $this->assertEquals($html, $field->render(array('class' => 'foobar'))); - } - - public function testRenderAsChoices_nonRequired() - { - $field = new TimeField('name', array( - 'hours' => array(3, 4), - 'minutes' => array(5, 6), - 'widget' => TimeField::CHOICE, - 'data_timezone' => 'UTC', - 'user_timezone' => 'UTC', - )); - - $field->setRequired(false); - $field->setData(new \DateTime('04:05 UTC')); - - $html = << - - - -: -EOF; - - $this->assertEquals($html, $field->render(array('class' => 'foobar'))); - } } \ No newline at end of file diff --git a/tests/Symfony/Tests/Component/Form/ToggleFieldTest.php b/tests/Symfony/Tests/Component/Form/ToggleFieldTest.php deleted file mode 100644 index 7d8ef8f266ced..0000000000000 --- a/tests/Symfony/Tests/Component/Form/ToggleFieldTest.php +++ /dev/null @@ -1,67 +0,0 @@ -setData(true); - - $html = ''; - - $this->assertEquals($html, $field->render(array( - 'class' => 'foobar', - ))); - } - - public function testRender_deselected() - { - $field = new TestToggleField('name'); - $field->setData(false); - - $html = ''; - - $this->assertEquals($html, $field->render()); - } - - public function testRender_withValue() - { - $field = new TestToggleField('name', array('value' => 'foobar')); - - $html = ''; - - $this->assertEquals($html, $field->render()); - } - - public function testRender_withLabel() - { - $field = new TestToggleField('name', array('label' => 'foobar')); - - $html = ' '; - - $this->assertEquals($html, $field->render()); - } - - public function testRender_withTranslatedLabel() - { - $translator = $this->getMock('Symfony\Component\I18N\TranslatorInterface'); - $translator->expects($this->any()) - ->method('translate') - ->will($this->returnCallback(function($text) { - return 'translated['.$text.']'; - })); - - $field = new TestToggleField('name', array('label' => 'foobar', 'translate_label' => true)); - $field->setTranslator($translator); - - $html = ' '; - - $this->assertEquals($html, $field->render()); - } -} \ No newline at end of file From ff683a694e37ecf779e1a16b5058666d6443ce85 Mon Sep 17 00:00:00 2001 From: "Jonathan H. Wage" Date: Mon, 4 Oct 2010 22:23:45 -0500 Subject: [PATCH 06/10] Integrating new data fixtures code. --- autoload.php.dist | 17 ++- install_vendors.sh | 3 + .../LoadDataFixturesDoctrineCommand.php | 142 ++---------------- .../DoctrineBundle/Resources/config/dbal.xml | 9 +- .../DoctrineBundle/Resources/config/orm.xml | 9 +- .../DoctrineBundle/Tests/ContainerTest.php | 62 ++++++++ .../CreateSchemaDoctrineODMCommand.php | 8 +- .../Command/DropSchemaDoctrineODMCommand.php | 8 +- .../LoadDataFixturesDoctrineODMCommand.php | 91 +++++++++++ .../Resources/config/mongodb.xml | 3 +- .../Tests/ContainerTest.php | 58 +++++++ update_vendors.sh | 3 + 12 files changed, 257 insertions(+), 156 deletions(-) create mode 100644 src/Symfony/Bundle/DoctrineBundle/Tests/ContainerTest.php create mode 100644 src/Symfony/Bundle/DoctrineMongoDBBundle/Command/LoadDataFixturesDoctrineODMCommand.php create mode 100644 src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/ContainerTest.php diff --git a/autoload.php.dist b/autoload.php.dist index 81ee7573a143a..902a1735ba33b 100644 --- a/autoload.php.dist +++ b/autoload.php.dist @@ -6,13 +6,14 @@ use Symfony\Component\HttpFoundation\UniversalClassLoader; $loader = new UniversalClassLoader(); $loader->registerNamespaces(array( - 'Symfony' => __DIR__.'/src', - 'Doctrine\\ODM\\MongoDB' => __DIR__.'/vendor/doctrine-mongodb/lib', - 'Doctrine\\Common' => __DIR__.'/vendor/doctrine-common/lib', - 'Doctrine\\DBAL\\Migrations' => __DIR__.'/vendor/doctrine-migrations/lib', - 'Doctrine\\DBAL' => __DIR__.'/vendor/doctrine-dbal/lib', - 'Doctrine' => __DIR__.'/vendor/doctrine/lib', - 'Zend' => __DIR__.'/vendor/zend/library', + 'Symfony' => __DIR__.'/src', + 'Doctrine\\ODM\\MongoDB' => __DIR__.'/vendor/doctrine-mongodb/lib', + 'Doctrine\\Common' => __DIR__.'/vendor/doctrine-common/lib', + 'Doctrine\\DBAL\\Migrations' => __DIR__.'/vendor/doctrine-migrations/lib', + 'Doctrine\\DBAL' => __DIR__.'/vendor/doctrine-dbal/lib', + 'Doctrine\\ORM\\DataFixtures' => __DIR__.'/vendor/doctrine-orm-data-fixtures', + 'Doctrine' => __DIR__.'/vendor/doctrine/lib', + 'Zend' => __DIR__.'/vendor/zend/library', )); $loader->registerPrefixes(array( 'Swift_' => __DIR__.'/vendor/swiftmailer/lib/classes', @@ -26,4 +27,4 @@ set_include_path( __DIR__.'/vendor/phing/classes'.PATH_SEPARATOR. __DIR__.'/vendor/propel/runtime/lib'.PATH_SEPARATOR. get_include_path() -); +); \ No newline at end of file diff --git a/install_vendors.sh b/install_vendors.sh index f61a8d0170e1f..d0a6f1ceb1fd7 100755 --- a/install_vendors.sh +++ b/install_vendors.sh @@ -12,6 +12,9 @@ cd vendor # Doctrine ORM git clone git://github.com/doctrine/doctrine2.git doctrine +# Doctrine ORM Data Fixtures Extension +git clone git://github.com/doctrine/orm-data-fixtures doctrine-orm-data-fixtures + # Doctrine DBAL git clone git://github.com/doctrine/dbal.git doctrine-dbal diff --git a/src/Symfony/Bundle/DoctrineBundle/Command/LoadDataFixturesDoctrineCommand.php b/src/Symfony/Bundle/DoctrineBundle/Command/LoadDataFixturesDoctrineCommand.php index 532ab90b21652..c07dac0045165 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Command/LoadDataFixturesDoctrineCommand.php +++ b/src/Symfony/Bundle/DoctrineBundle/Command/LoadDataFixturesDoctrineCommand.php @@ -39,6 +39,7 @@ protected function configure() ->setDescription('Load data fixtures to your database.') ->addOption('fixtures', null, InputOption::PARAMETER_OPTIONAL | InputOption::PARAMETER_IS_ARRAY, 'The directory or file to load data fixtures from.') ->addOption('append', null, InputOption::PARAMETER_OPTIONAL, 'Whether or not to append the data fixtures.', false) + ->addOption('em', null, InputOption::PARAMETER_REQUIRED, 'The entity manager to use for this command.') ->setHelp(<<doctrine:data:load command loads data fixtures from your bundles: @@ -57,7 +58,10 @@ protected function configure() protected function execute(InputInterface $input, OutputInterface $output) { - $defaultEm = $this->container->getDoctrine_ORM_EntityManagerService(); + $emName = $input->getOption('em'); + $emName = $emName ? $emName : 'default'; + $emServiceName = sprintf('doctrine.orm.%s_entity_manager', $emName); + $em = $this->container->get($emServiceName); $dirOrFile = $input->getOption('fixtures'); if ($dirOrFile) { $paths = is_array($dirOrFile) ? $dirOrFile : array($dirOrFile); @@ -69,139 +73,19 @@ protected function execute(InputInterface $input, OutputInterface $output) $namespace = str_replace('/', '\\', dirname($tmp)); $class = basename($tmp); - if (isset($bundleDirs[$namespace]) && is_dir($dir = $bundleDirs[$namespace].'/'.$class.'/Resources/data/fixtures/doctrine/orm')) { + if (isset($bundleDirs[$namespace]) && is_dir($dir = $bundleDirs[$namespace].'/'.$class.'/DataFixtures/ORM')) { $paths[] = $dir; } } } - $files = array(); + $loader = new \Doctrine\Common\DataFixtures\Loader(); foreach ($paths as $path) { - if (is_dir($path)) { - $finder = new Finder(); - $found = iterator_to_array($finder - ->files() - ->name('*.php') - ->in($path)); - } else { - $found = array($path); - } - $files = array_merge($files, $found); - } - - $ems = array(); - $emEntities = array(); - $files = array_unique($files); - foreach ($files as $file) { - $em = $defaultEm; - $output->writeln(sprintf('Loading data fixtures from "%s"', $file)); - - $before = array_keys(get_defined_vars()); - include($file); - $after = array_keys(get_defined_vars()); - $new = array_diff($after, $before); - $params = $em->getConnection()->getParams(); - $emName = isset($params['path']) ? $params['path']:$params['dbname']; - - $ems[$emName] = $em; - $emEntities[$emName] = array(); - $variables = array_values($new); - - foreach ($variables as $variable) { - $value = $$variable; - if (!is_object($value) || $value instanceof \Doctrine\ORM\EntityManager) { - continue; - } - $emEntities[$emName][] = $value; - } - foreach ($ems as $emName => $em) { - if (!$input->getOption('append')) { - $output->writeln(sprintf('Purging data from entity manager named "%s"', $emName)); - $this->purgeEntityManager($em); - } - - $entities = $emEntities[$emName]; - $numEntities = count($entities); - $output->writeln(sprintf('Persisting "%s" '.($numEntities > 1 ? 'entities' : 'entity').'', count($entities))); - - foreach ($entities as $entity) { - $em->persist($entity); - } - $output->writeln('Flushing entity manager'); - $em->flush(); - } - } - } - - protected function purgeEntityManager(EntityManager $em) - { - $classes = array(); - $metadatas = $em->getMetadataFactory()->getAllMetadata(); - - foreach ($metadatas as $metadata) { - if (!$metadata->isMappedSuperclass) { - $classes[] = $metadata; - } + $loader->loadFromDirectory($path); } - - $commitOrder = $this->getCommitOrder($em, $classes); - - // Drop association tables first - $orderedTables = $this->getAssociationTables($commitOrder); - - // Drop tables in reverse commit order - for ($i = count($commitOrder) - 1; $i >= 0; --$i) { - $class = $commitOrder[$i]; - - if (($class->isInheritanceTypeSingleTable() && $class->name != $class->rootEntityName) - || $class->isMappedSuperclass) { - continue; - } - - $orderedTables[] = $class->getTableName(); - } - - foreach($orderedTables as $tbl) { - $em->getConnection()->executeUpdate("DELETE FROM $tbl"); - } - } - - protected function getCommitOrder(EntityManager $em, array $classes) - { - $calc = new CommitOrderCalculator; - - foreach ($classes as $class) { - $calc->addClass($class); - - foreach ($class->associationMappings as $assoc) { - if ($assoc['isOwningSide']) { - $targetClass = $em->getClassMetadata($assoc['targetEntity']); - - if ( ! $calc->hasClass($targetClass->name)) { - $calc->addClass($targetClass); - } - - // add dependency ($targetClass before $class) - $calc->addDependency($targetClass, $class); - } - } - } - - return $calc->getCommitOrder(); - } - - protected function getAssociationTables(array $classes) - { - $associationTables = array(); - - foreach ($classes as $class) { - foreach ($class->associationMappings as $assoc) { - if ($assoc['isOwningSide'] && $assoc['type'] == ClassMetadata::MANY_TO_MANY) { - $associationTables[] = $assoc['joinTable']['name']; - } - } - } - - return $associationTables; + $fixtures = $loader->getFixtures(); + $purger = new \Doctrine\Common\DataFixtures\Purger\ORMPurger($em); + $executor = new \Doctrine\Common\DataFixtures\Executor\ORMExecutor($em, $purger); + $executor->execute($fixtures, $input->getOption('append')); } -} +} \ No newline at end of file diff --git a/src/Symfony/Bundle/DoctrineBundle/Resources/config/dbal.xml b/src/Symfony/Bundle/DoctrineBundle/Resources/config/dbal.xml index fd7cbe7ba0bfe..33479e3f07e3e 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Resources/config/dbal.xml +++ b/src/Symfony/Bundle/DoctrineBundle/Resources/config/dbal.xml @@ -7,15 +7,16 @@ default Doctrine\DBAL\Connection - + Doctrine\DBAL\Logging\DebugStack + Symfony\Bundle\DoctrineBundle\Logger\DbalLogger Symfony\Bundle\DoctrineBundle\DataCollector\DoctrineDataCollector default - + - + @@ -24,4 +25,4 @@ - + \ No newline at end of file diff --git a/src/Symfony/Bundle/DoctrineBundle/Resources/config/orm.xml b/src/Symfony/Bundle/DoctrineBundle/Resources/config/orm.xml index e4e43730dbc4a..2a01ae14d0f60 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Resources/config/orm.xml +++ b/src/Symfony/Bundle/DoctrineBundle/Resources/config/orm.xml @@ -42,13 +42,12 @@ - + %doctrine.orm.metadata_driver.entity_dirs% - - %doctrine.orm.metadata.annotation_default_namespace% + Doctrine\ORM\Mapping\ orm @@ -56,12 +55,12 @@ - + %doctrine.orm.metadata_driver.mapping_dirs% - + %doctrine.orm.metadata_driver.mapping_dirs% diff --git a/src/Symfony/Bundle/DoctrineBundle/Tests/ContainerTest.php b/src/Symfony/Bundle/DoctrineBundle/Tests/ContainerTest.php new file mode 100644 index 0000000000000..5276ee797781a --- /dev/null +++ b/src/Symfony/Bundle/DoctrineBundle/Tests/ContainerTest.php @@ -0,0 +1,62 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\DoctrineBundle\Tests; + +use Symfony\Component\DependencyInjection\Dumper\PhpDumper; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; +use Symfony\Bundle\DoctrineBundle\DependencyInjection\DoctrineExtension; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; + +class ContainerTest extends TestCase +{ + public function getContainer() + { + $container = new ContainerBuilder(new ParameterBag(array( + 'kernel.bundle_dirs' => array(), + 'kernel.bundles' => array(), + 'kernel.cache_dir' => sys_get_temp_dir(), + ))); + $loader = new DoctrineExtension(); + $container->registerExtension($loader); + $loader->dbalLoad(array(), $container); + $loader->ormLoad(array(), $container); + + $dumper = new PhpDumper($container); + $code = $dumper->dump(); + eval(str_replace('getContainer(); + $this->assertInstanceOf('Doctrine\DBAL\Logging\DebugStack', $container->get('doctrine.dbal.logger.debug')); + $this->assertInstanceOf('Doctrine\DBAL\Logging\DebugStack', $container->get('doctrine.dbal.logger')); + $this->assertInstanceOf('Symfony\Bundle\DoctrineBundle\DataCollector\DoctrineDataCollector', $container->get('doctrine.data_collector')); + $this->assertInstanceOf('Doctrine\DBAL\Configuration', $container->get('doctrine.dbal.default_connection.configuration')); + $this->assertInstanceOf('Doctrine\Common\EventManager', $container->get('doctrine.dbal.default_connection.event_manager')); + $this->assertInstanceOf('Doctrine\DBAL\Connection', $container->get('doctrine.dbal.default_connection')); + $this->assertInstanceOf('Doctrine\ORM\Mapping\Driver\AnnotationDriver', $container->get('doctrine.orm.metadata_driver.annotation')); + $this->assertInstanceOf('Doctrine\Common\Annotations\AnnotationReader', $container->get('doctrine.orm.metadata_driver.annotation.reader')); + $this->assertInstanceOf('Doctrine\ORM\Mapping\Driver\XmlDriver', $container->get('doctrine.orm.metadata_driver.xml')); + $this->assertInstanceOf('Doctrine\ORM\Mapping\Driver\YamlDriver', $container->get('doctrine.orm.metadata_driver.yml')); + $this->assertInstanceOf('Doctrine\ORM\Configuration', $container->get('doctrine.orm.default_configuration')); + $this->assertInstanceOf('Doctrine\ORM\Mapping\Driver\DriverChain', $container->get('doctrine.orm.metadata_driver')); + $this->assertInstanceOf('Doctrine\Common\Cache\ArrayCache', $container->get('doctrine.orm.default_metadata_cache')); + $this->assertInstanceOf('Doctrine\Common\Cache\ArrayCache', $container->get('doctrine.orm.default_query_cache')); + $this->assertInstanceOf('Doctrine\Common\Cache\ArrayCache', $container->get('doctrine.orm.default_result_cache')); + $this->assertInstanceOf('Doctrine\ORM\EntityManager', $container->get('doctrine.orm.default_entity_manager')); + $this->assertInstanceOf('Doctrine\DBAL\Connection', $container->get('database_connection')); + $this->assertInstanceOf('Doctrine\ORM\EntityManager', $container->get('doctrine.orm.entity_manager')); + } +} \ No newline at end of file diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/CreateSchemaDoctrineODMCommand.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/CreateSchemaDoctrineODMCommand.php index 52cd8d91b0278..25e87e2428879 100644 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/CreateSchemaDoctrineODMCommand.php +++ b/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/CreateSchemaDoctrineODMCommand.php @@ -21,16 +21,16 @@ protected function configure() parent::configure(); $this - ->setName('doctrine:odm:schema:create') + ->setName('doctrine:mongodb:schema:create') ->addOption('dm', null, InputOption::PARAMETER_REQUIRED, 'The document manager to use for this command.') ->setHelp(<<doctrine:odm:schema:create command creates the default document manager's schema: +The doctrine:mongodb:schema:create command creates the default document manager's schema: - ./symfony doctrine:odm:schema:create + ./symfony doctrine:mongodb:schema:create You can also optionally specify the name of a document manager to create the schema for: - ./symfony doctrine:odm:schema:create --dm=default + ./symfony doctrine:mongodb:schema:create --dm=default EOT ); } diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/DropSchemaDoctrineODMCommand.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/DropSchemaDoctrineODMCommand.php index 37f7005b67fc1..3c49e0f8af9ac 100644 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/DropSchemaDoctrineODMCommand.php +++ b/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/DropSchemaDoctrineODMCommand.php @@ -21,16 +21,16 @@ protected function configure() parent::configure(); $this - ->setName('doctrine:odm:schema:drop') + ->setName('doctrine:mongodb:schema:drop') ->addOption('dm', null, InputOption::PARAMETER_REQUIRED, 'The document manager to use for this command.') ->setHelp(<<doctrine:odm:schema:drop command drops the default document manager's schema: +The doctrine:mongodb:schema:drop command drops the default document manager's schema: - ./symfony doctrine:odm:schema:drop + ./symfony doctrine:mongodb:schema:drop You can also optionally specify the name of a document manager to drop the schema for: - ./symfony doctrine:odm:schema:drop --dm=default + ./symfony doctrine:mongodb:schema:drop --dm=default EOT ); } diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/LoadDataFixturesDoctrineODMCommand.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/LoadDataFixturesDoctrineODMCommand.php new file mode 100644 index 0000000000000..abafc25f8e2e1 --- /dev/null +++ b/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/LoadDataFixturesDoctrineODMCommand.php @@ -0,0 +1,91 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +/** + * Load data fixtures from bundles. + * + * @author Fabien Potencier + * @author Jonathan H. Wage + */ +class LoadDataFixturesDoctrineODMCommand extends DoctrineODMCommand +{ + protected function configure() + { + $this + ->setName('doctrine:mongodb:data:load') + ->setDescription('Load data fixtures to your database.') + ->addOption('fixtures', null, InputOption::PARAMETER_OPTIONAL | InputOption::PARAMETER_IS_ARRAY, 'The directory or file to load data fixtures from.') + ->addOption('append', null, InputOption::PARAMETER_OPTIONAL, 'Whether or not to append the data fixtures.', false) + ->addOption('dm', null, InputOption::PARAMETER_REQUIRED, 'The document manager to use for this command.') + ->setHelp(<<doctrine:mongodb:data:load command loads data fixtures from your bundles: + + ./symfony doctrine:mongodb:data:load + +You can also optionally specify the path to fixtures with the --fixtures option: + + ./symfony doctrine:mongodb:data:load --fixtures=/path/to/fixtures1 --fixtures=/path/to/fixtures2 + +If you want to append the fixtures instead of flushing the database first you can use the --append option: + + ./symfony doctrine:mongodb:data:load --append +EOT + ); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $dmName = $input->getOption('dm'); + $dmName = $dmName ? $dmName : 'default'; + $dmServiceName = sprintf('doctrine.odm.mongodb.%s_document_manager', $dmName); + $dm = $this->container->get($dmServiceName); + $dirOrFile = $input->getOption('fixtures'); + if ($dirOrFile) { + $paths = is_array($dirOrFile) ? $dirOrFile : array($dirOrFile); + } else { + $paths = array(); + $bundleDirs = $this->container->getKernelService()->getBundleDirs(); + foreach ($this->container->getKernelService()->getBundles() as $bundle) { + $tmp = dirname(str_replace('\\', '/', get_class($bundle))); + $namespace = str_replace('/', '\\', dirname($tmp)); + $class = basename($tmp); + + if (isset($bundleDirs[$namespace]) && is_dir($dir = $bundleDirs[$namespace].'/'.$class.'/DataFixtures/MongoDB')) { + $paths[] = $dir; + } + } + } + + $loader = new \Doctrine\Common\DataFixtures\Loader(); + foreach ($paths as $path) { + $loader->loadFromDirectory($path); + } + $fixtures = $loader->getFixtures(); + $purger = new \Doctrine\Common\DataFixtures\Purger\MongoDBPurger($dm); + $executor = new \Doctrine\Common\DataFixtures\Executor\MongoDBExecutor($dm, $purger); + $executor->execute($fixtures, $input->getOption('append')); + } +} \ No newline at end of file diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Resources/config/mongodb.xml b/src/Symfony/Bundle/DoctrineMongoDBBundle/Resources/config/mongodb.xml index c2f718b54e5ba..71835fd7e78f8 100755 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Resources/config/mongodb.xml +++ b/src/Symfony/Bundle/DoctrineMongoDBBundle/Resources/config/mongodb.xml @@ -56,7 +56,6 @@ - %doctrine.odm.mongodb.metadata.annotation_default_namespace% Doctrine\ODM\MongoDB\Mapping\ mongodb @@ -77,4 +76,4 @@ - + \ No newline at end of file diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/ContainerTest.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/ContainerTest.php new file mode 100644 index 0000000000000..6d03d6db7fae6 --- /dev/null +++ b/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/ContainerTest.php @@ -0,0 +1,58 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\DoctrineBundle\Tests; + +use Symfony\Component\DependencyInjection\Dumper\PhpDumper; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; +use Symfony\Bundle\DoctrineMongoDBBundle\DependencyInjection\DoctrineMongoDBExtension; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; + +class ContainerTest extends TestCase +{ + public function getContainer() + { + $container = new ContainerBuilder(new ParameterBag(array( + 'kernel.bundle_dirs' => array(), + 'kernel.bundles' => array(), + 'kernel.cache_dir' => sys_get_temp_dir(), + ))); + $loader = new DoctrineMongoDBExtension(); + $container->registerExtension($loader); + $loader->mongodbLoad(array(), $container); + + $dumper = new PhpDumper($container); + $code = $dumper->dump(); + eval(str_replace('getContainer(); + $this->assertInstanceOf('Doctrine\ODM\MongoDB\Mapping\Driver\DriverChain', $container->get('doctrine.odm.mongodb.metadata.chain')); + $this->assertInstanceOf('Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver', $container->get('doctrine.odm.mongodb.metadata.annotation')); + $this->assertInstanceOf('Doctrine\Common\Annotations\AnnotationReader', $container->get('doctrine.odm.mongodb.metadata.annotation_reader')); + $this->assertInstanceOf('Doctrine\ODM\MongoDB\Mapping\Driver\XmlDriver', $container->get('doctrine.odm.mongodb.metadata.xml')); + $this->assertInstanceOf('Doctrine\ODM\MongoDB\Mapping\Driver\YamlDriver', $container->get('doctrine.odm.mongodb.metadata.yml')); + $this->assertInstanceOf('Doctrine\Common\Cache\ArrayCache', $container->get('doctrine.odm.mongodb.cache.array')); + $this->assertInstanceOf('Symfony\Bundle\DoctrineMongoDBBundle\Logger\DoctrineMongoDBLogger', $container->get('doctrine.odm.mongodb.logger')); + $this->assertInstanceOf('Symfony\Bundle\DoctrineMongoDBBundle\DataCollector\DoctrineMongoDBDataCollector', $container->get('doctrine.odm.mongodb.data_collector')); + $this->assertInstanceOf('Doctrine\ODM\MongoDB\Mongo', $container->get('doctrine.odm.mongodb.default_connection')); + $this->assertInstanceOf('Doctrine\ODM\MongoDB\Configuration', $container->get('doctrine.odm.mongodb.default_configuration')); + $this->assertInstanceOf('Doctrine\ODM\MongoDB\Mapping\Driver\DriverChain', $container->get('doctrine.odm.mongodb.metadata')); + $this->assertInstanceOf('Doctrine\Common\Cache\ArrayCache', $container->get('doctrine.odm.mongodb.default_metadata_cache')); + $this->assertInstanceOf('Doctrine\ODM\MongoDB\DocumentManager', $container->get('doctrine.odm.mongodb.default_document_manager')); + $this->assertInstanceOf('Doctrine\Common\Cache\ArrayCache', $container->get('doctrine.odm.mongodb.cache')); + $this->assertInstanceOf('Doctrine\ODM\MongoDB\DocumentManager', $container->get('doctrine.odm.mongodb.document_manager')); + } +} \ No newline at end of file diff --git a/update_vendors.sh b/update_vendors.sh index 1de72e87f3dc8..446b486071597 100755 --- a/update_vendors.sh +++ b/update_vendors.sh @@ -5,6 +5,9 @@ CURRENT=`pwd`/vendor # Doctrine ORM cd $CURRENT/doctrine && git pull +# Doctrine ORM Data Fixtures Extension +cd $CURRENT/doctrine-orm-data-fixtures && git pull + # Doctrine DBAL cd $CURRENT/doctrine-dbal && git pull From 3bc3115d8c784c5be201d0156a51d6626135a246 Mon Sep 17 00:00:00 2001 From: "Jonathan H. Wage" Date: Tue, 5 Oct 2010 01:51:23 -0500 Subject: [PATCH 07/10] Adding setLogger for data fixtures. --- .../DoctrineBundle/Command/LoadDataFixturesDoctrineCommand.php | 3 +++ .../Command/LoadDataFixturesDoctrineODMCommand.php | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/Symfony/Bundle/DoctrineBundle/Command/LoadDataFixturesDoctrineCommand.php b/src/Symfony/Bundle/DoctrineBundle/Command/LoadDataFixturesDoctrineCommand.php index c07dac0045165..9b02dd4b6c7be 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Command/LoadDataFixturesDoctrineCommand.php +++ b/src/Symfony/Bundle/DoctrineBundle/Command/LoadDataFixturesDoctrineCommand.php @@ -86,6 +86,9 @@ protected function execute(InputInterface $input, OutputInterface $output) $fixtures = $loader->getFixtures(); $purger = new \Doctrine\Common\DataFixtures\Purger\ORMPurger($em); $executor = new \Doctrine\Common\DataFixtures\Executor\ORMExecutor($em, $purger); + $executor->setLogger(function($message) use ($output) { + $output->writeln(sprintf(' > %s', $message)); + }); $executor->execute($fixtures, $input->getOption('append')); } } \ No newline at end of file diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/LoadDataFixturesDoctrineODMCommand.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/LoadDataFixturesDoctrineODMCommand.php index abafc25f8e2e1..c5e8997603966 100644 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/LoadDataFixturesDoctrineODMCommand.php +++ b/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/LoadDataFixturesDoctrineODMCommand.php @@ -86,6 +86,9 @@ protected function execute(InputInterface $input, OutputInterface $output) $fixtures = $loader->getFixtures(); $purger = new \Doctrine\Common\DataFixtures\Purger\MongoDBPurger($dm); $executor = new \Doctrine\Common\DataFixtures\Executor\MongoDBExecutor($dm, $purger); + $executor->setLogger(function($message) use ($output) { + $output->writeln(sprintf(' > %s', $message)); + }); $executor->execute($fixtures, $input->getOption('append')); } } \ No newline at end of file From c6ed5930229780a7bcf11a45c64918a7c13897ae Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 5 Oct 2010 09:05:29 +0200 Subject: [PATCH 08/10] fixed unit tests --- src/Symfony/Bundle/DoctrineBundle/Tests/ContainerTest.php | 2 +- .../Bundle/DoctrineMongoDBBundle/Tests/ContainerTest.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Bundle/DoctrineBundle/Tests/ContainerTest.php b/src/Symfony/Bundle/DoctrineBundle/Tests/ContainerTest.php index 5276ee797781a..ba7d46bbae003 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Tests/ContainerTest.php +++ b/src/Symfony/Bundle/DoctrineBundle/Tests/ContainerTest.php @@ -32,7 +32,7 @@ public function getContainer() $loader->ormLoad(array(), $container); $dumper = new PhpDumper($container); - $code = $dumper->dump(); + $code = $dumper->dump(array('class' => 'DoctrineBundleTestsProjectServiceContainer')); eval(str_replace('mongodbLoad(array(), $container); $dumper = new PhpDumper($container); - $code = $dumper->dump(); + $code = $dumper->dump(array('class' => 'DoctrineMongoDBBundleTestsProjectServiceContainer')); eval(str_replace('assertInstanceOf('Doctrine\Common\Cache\ArrayCache', $container->get('doctrine.odm.mongodb.cache')); $this->assertInstanceOf('Doctrine\ODM\MongoDB\DocumentManager', $container->get('doctrine.odm.mongodb.document_manager')); } -} \ No newline at end of file +} From 36a31eceb86755db9773758a2f29499e0eceea8d Mon Sep 17 00:00:00 2001 From: "Jonathan H. Wage" Date: Tue, 5 Oct 2010 02:14:07 -0500 Subject: [PATCH 09/10] Fixing container test. --- src/Symfony/Bundle/DoctrineBundle/Tests/ContainerTest.php | 2 +- .../Bundle/DoctrineMongoDBBundle/Tests/ContainerTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bundle/DoctrineBundle/Tests/ContainerTest.php b/src/Symfony/Bundle/DoctrineBundle/Tests/ContainerTest.php index ba7d46bbae003..45480c7347c56 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Tests/ContainerTest.php +++ b/src/Symfony/Bundle/DoctrineBundle/Tests/ContainerTest.php @@ -34,7 +34,7 @@ public function getContainer() $dumper = new PhpDumper($container); $code = $dumper->dump(array('class' => 'DoctrineBundleTestsProjectServiceContainer')); eval(str_replace('dump(array('class' => 'DoctrineMongoDBBundleTestsProjectServiceContainer')); eval(str_replace(' Date: Tue, 5 Oct 2010 02:29:00 -0500 Subject: [PATCH 10/10] Fixing old path to new one. --- autoload.php.dist | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/autoload.php.dist b/autoload.php.dist index 902a1735ba33b..ecaec83f53c96 100644 --- a/autoload.php.dist +++ b/autoload.php.dist @@ -6,14 +6,14 @@ use Symfony\Component\HttpFoundation\UniversalClassLoader; $loader = new UniversalClassLoader(); $loader->registerNamespaces(array( - 'Symfony' => __DIR__.'/src', - 'Doctrine\\ODM\\MongoDB' => __DIR__.'/vendor/doctrine-mongodb/lib', - 'Doctrine\\Common' => __DIR__.'/vendor/doctrine-common/lib', - 'Doctrine\\DBAL\\Migrations' => __DIR__.'/vendor/doctrine-migrations/lib', - 'Doctrine\\DBAL' => __DIR__.'/vendor/doctrine-dbal/lib', - 'Doctrine\\ORM\\DataFixtures' => __DIR__.'/vendor/doctrine-orm-data-fixtures', - 'Doctrine' => __DIR__.'/vendor/doctrine/lib', - 'Zend' => __DIR__.'/vendor/zend/library', + 'Symfony' => __DIR__.'/src', + 'Doctrine\\ODM\\MongoDB' => __DIR__.'/vendor/doctrine-mongodb/lib', + 'Doctrine\\Common' => __DIR__.'/vendor/doctrine-common/lib', + 'Doctrine\\DBAL\\Migrations' => __DIR__.'/vendor/doctrine-migrations/lib', + 'Doctrine\\DBAL' => __DIR__.'/vendor/doctrine-dbal/lib', + 'Doctrine\\Common\\DataFixtures' => __DIR__.'/vendor/doctrine-data-fixtures/lib', + 'Doctrine' => __DIR__.'/vendor/doctrine/lib', + 'Zend' => __DIR__.'/vendor/zend/library', )); $loader->registerPrefixes(array( 'Swift_' => __DIR__.'/vendor/swiftmailer/lib/classes', pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy