Ver código fonte

[Form] Refactored date and time field choices into ChoiceList classes

Bernhard Schussek 14 anos atrás
pai
commit
5eb5cc5743

+ 12 - 7
src/Symfony/Component/Form/ChoiceField.php

@@ -63,20 +63,25 @@ class ChoiceField extends HybridField
 
     protected function configure()
     {
-        $this->addRequiredOption('choices');
+        $this->addOption('choices', array());
         $this->addOption('preferred_choices', array());
         $this->addOption('multiple', false);
         $this->addOption('expanded', false);
         $this->addOption('empty_value', '');
+        $this->addOption('choice_list');
 
         parent::configure();
 
-        $this->choiceList = new DefaultChoiceList(
-            $this->getOption('choices'),
-            $this->getOption('preferred_choices'),
-            $this->getOption('empty_value'),
-            $this->isRequired()
-        );
+        if ($this->getOption('choice_list')) {
+            $this->choiceList = $this->getOption('choice_list');
+        } else {
+            $this->choiceList = new DefaultChoiceList(
+                $this->getOption('choices'),
+                $this->getOption('preferred_choices'),
+                $this->getOption('empty_value'),
+                $this->isRequired()
+            );
+        }
 
         if ($this->getOption('expanded')) {
             if ($this->getOption('multiple')) {

+ 24 - 0
src/Symfony/Component/Form/ChoiceList/DayChoiceList.php

@@ -0,0 +1,24 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Form\ChoiceList;
+
+class DayChoiceList extends PaddedChoiceList
+{
+    public function __construct(array $days = array(), array $preferredChoices = array(), $emptyValue = '', $required = false)
+    {
+        if (count($days) === 0) {
+            $days = range(1, 31);
+        }
+
+        parent::__construct($days, 2, '0', STR_PAD_LEFT, $preferredChoices, $emptyValue, $required);
+    }
+}

+ 24 - 0
src/Symfony/Component/Form/ChoiceList/HourChoiceList.php

@@ -0,0 +1,24 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Form\ChoiceList;
+
+class HourChoiceList extends PaddedChoiceList
+{
+    public function __construct(array $hours = array(), array $preferredChoices = array(), $emptyValue = '', $required = false)
+    {
+        if (count($hours) === 0) {
+            $hours = range(0, 23);
+        }
+
+        parent::__construct($hours, 2, '0', STR_PAD_LEFT, $preferredChoices, $emptyValue, $required);
+    }
+}

+ 24 - 0
src/Symfony/Component/Form/ChoiceList/MinuteChoiceList.php

@@ -0,0 +1,24 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Form\ChoiceList;
+
+class MinuteChoiceList extends PaddedChoiceList
+{
+    public function __construct(array $minutes = array(), array $preferredChoices = array(), $emptyValue = '', $required = false)
+    {
+        if (count($minutes) === 0) {
+            $minutes = range(0, 59);
+        }
+
+        parent::__construct($minutes, 2, '0', STR_PAD_LEFT, $preferredChoices, $emptyValue, $required);
+    }
+}

+ 49 - 0
src/Symfony/Component/Form/ChoiceList/MonthChoiceList.php

@@ -0,0 +1,49 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Form\ChoiceList;
+
+class MonthChoiceList extends PaddedChoiceList
+{
+    /**
+     * Generates an array of localized month choices
+     *
+     * @param  array $months  The month numbers to generate
+     * @return array          The localized months respecting the configured
+     *                        locale and date format
+     */
+    public function __construct(\IntlDateFormatter $formatter, array $months = array(), array $preferredChoices = array(), $emptyValue = '', $required = false)
+    {
+        if (count($months) === 0) {
+            $months = range(1, 12);
+        }
+
+        $pattern = $formatter->getPattern();
+
+        if (preg_match('/M+/', $pattern, $matches)) {
+            $formatter->setPattern($matches[0]);
+            $choices = array();
+
+            foreach ($months as $month) {
+                $choices[$month] = $formatter->format(gmmktime(0, 0, 0, $month));
+            }
+
+            // I'd like to clone the formatter above, but then we get a
+            // segmentation fault, so let's restore the old state instead
+            $formatter->setPattern($pattern);
+
+            DefaultChoiceList::__construct($choices, $preferredChoices, $emptyValue, $required);
+        } else {
+            parent::__construct($months, 2, '0', STR_PAD_LEFT, $preferredChoices, $emptyValue, $required);
+        }
+
+    }
+}

+ 37 - 0
src/Symfony/Component/Form/ChoiceList/PaddedChoiceList.php

@@ -0,0 +1,37 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Form\ChoiceList;
+
+class PaddedChoiceList extends DefaultChoiceList
+{
+    /**
+     * Generates an array of choices for the given values
+     *
+     * If the values are shorter than $padLength characters, they are padded with
+     * zeros on the left side.
+     *
+     * @param  array   $values     The available choices
+     * @param  integer $padLength  The length to pad the choices
+     * @return array               An array with the input values as keys and the
+     *                             padded values as values
+     */
+    public function __construct($values, $padLength, $padString, $padType = STR_PAD_LEFT, array $preferredChoices = array(), $emptyValue = '', $required = false)
+    {
+        $choices = array();
+
+        foreach ($values as $value) {
+            $choices[$value] = str_pad($value, $padLength, $padString, $padType);
+        }
+
+        parent::__construct($choices, $preferredChoices, $emptyValue, $required);
+    }
+}

+ 24 - 0
src/Symfony/Component/Form/ChoiceList/SecondChoiceList.php

@@ -0,0 +1,24 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Form\ChoiceList;
+
+class SecondChoiceList extends PaddedChoiceList
+{
+    public function __construct(array $seconds = array(), array $preferredChoices = array(), $emptyValue = '', $required = false)
+    {
+        if (count($seconds) === 0) {
+            $seconds = range(0, 59);
+        }
+
+        parent::__construct($seconds, 2, '0', STR_PAD_LEFT, $preferredChoices, $emptyValue, $required);
+    }
+}

+ 24 - 0
src/Symfony/Component/Form/ChoiceList/YearChoiceList.php

@@ -0,0 +1,24 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Form\ChoiceList;
+
+class YearChoiceList extends PaddedChoiceList
+{
+    public function __construct(array $years = array(), array $preferredChoices = array(), $emptyValue = '', $required = false)
+    {
+        if (count($years) === 0) {
+            $years = range(date('Y') - 5, date('Y') + 5);
+        }
+
+        parent::__construct($years, 4, '0', STR_PAD_LEFT, $preferredChoices, $emptyValue, $required);
+    }
+}

+ 15 - 69
src/Symfony/Component/Form/DateField.php

@@ -17,6 +17,9 @@ use Symfony\Component\Form\ValueTransformer\DateTimeToTimestampTransformer;
 use Symfony\Component\Form\ValueTransformer\ValueTransformerChain;
 use Symfony\Component\Form\ValueTransformer\DateTimeToLocalizedStringTransformer;
 use Symfony\Component\Form\ValueTransformer\DateTimeToArrayTransformer;
+use Symfony\Component\Form\ChoiceList\YearChoiceList;
+use Symfony\Component\Form\ChoiceList\MonthChoiceList;
+use Symfony\Component\Form\ChoiceList\DayChoiceList;
 
 /**
  * Represents a date field.
@@ -108,9 +111,9 @@ class DateField extends HybridField
         $this->addOption('type', self::DATETIME, self::$types);
         $this->addOption('pattern');
 
-        $this->addOption('years', range(date('Y') - 5, date('Y') + 5));
-        $this->addOption('months', range(1, 12));
-        $this->addOption('days', range(1, 31));
+        $this->addOption('years', array());
+        $this->addOption('months', array());
+        $this->addOption('days', array());
 
         $this->addOption('format', self::MEDIUM, self::$formats);
         $this->addOption('data_timezone', date_default_timezone_get());
@@ -164,57 +167,16 @@ class DateField extends HybridField
 
             $this->setFieldMode(self::FORM);
 
-            $this->addChoiceFields();
-        }
-    }
-
-    /**
-     * Generates an array of choices for the given values
-     *
-     * If the values are shorter than $padLength characters, they are padded with
-     * zeros on the left side.
-     *
-     * @param  array   $values     The available choices
-     * @param  integer $padLength  The length to pad the choices
-     * @return array               An array with the input values as keys and the
-     *                             padded values as values
-     */
-    protected function generatePaddedChoices(array $values, $padLength)
-    {
-        $choices = array();
-
-        foreach ($values as $value) {
-            $choices[$value] = str_pad($value, $padLength, '0', STR_PAD_LEFT);
-        }
-
-        return $choices;
-    }
-
-    /**
-     * Generates an array of localized month choices
-     *
-     * @param  array $months  The month numbers to generate
-     * @return array          The localized months respecting the configured
-     *                        locale and date format
-     */
-    protected function generateMonthChoices(array $months)
-    {
-        $pattern = $this->formatter->getPattern();
-
-        if (preg_match('/M+/', $pattern, $matches)) {
-            $this->formatter->setPattern($matches[0]);
-            $choices = array();
-
-            foreach ($months as $month) {
-                $choices[$month] = $this->formatter->format(gmmktime(0, 0, 0, $month));
-            }
-
-            $this->formatter->setPattern($pattern);
-        } else {
-            $choices = $this->generatePaddedChoices($months, 2);
+            $this->add(new ChoiceField('year', array(
+                'choice_list' => new YearChoiceList($this->getOption('years')),
+            )));
+            $this->add(new ChoiceField('month', array(
+                'choice_list' => new MonthChoiceList($this->formatter, $this->getOption('months')),
+            )));
+            $this->add(new ChoiceField('day', array(
+                'choice_list' => new DayChoiceList($this->getOption('days')),
+            )));
         }
-
-        return $choices;
     }
 
     public function getPattern()
@@ -234,22 +196,6 @@ class DateField extends HybridField
         return '{{ year }}-{{ month }}-{{ day }}';
     }
 
-    /**
-     * Adds (or replaces if already added) the fields used when widget=CHOICE
-     */
-    protected function addChoiceFields()
-    {
-        $this->add(new ChoiceField('year', array(
-            'choices' => $this->generatePaddedChoices($this->getOption('years'), 4),
-        )));
-        $this->add(new ChoiceField('month', array(
-            'choices' => $this->generateMonthChoices($this->getOption('months')),
-        )));
-        $this->add(new ChoiceField('day', array(
-            'choices' => $this->generatePaddedChoices($this->getOption('days'), 2),
-        )));
-    }
-
     /**
      * Returns whether the year of the field's data is valid
      *

+ 6 - 6
src/Symfony/Component/Form/DateTimeField.php

@@ -96,12 +96,12 @@ class DateTimeField extends Form
         $this->addOption('date_pattern');
         $this->addOption('with_seconds', false);
 
-        $this->addOption('years', range(date('Y') - 5, date('Y') + 5));
-        $this->addOption('months', range(1, 12));
-        $this->addOption('days', range(1, 31));
-        $this->addOption('hours', range(0, 23));
-        $this->addOption('minutes', range(0, 59));
-        $this->addOption('seconds', range(0, 59));
+        $this->addOption('years', array());
+        $this->addOption('months', array());
+        $this->addOption('days', array());
+        $this->addOption('hours', array());
+        $this->addOption('minutes', array());
+        $this->addOption('seconds', array());
 
         $this->addOption('data_timezone', date_default_timezone_get());
         $this->addOption('user_timezone', date_default_timezone_get());

+ 9 - 6
src/Symfony/Component/Form/TimeField.php

@@ -16,6 +16,9 @@ use Symfony\Component\Form\ValueTransformer\DateTimeToArrayTransformer;
 use Symfony\Component\Form\ValueTransformer\DateTimeToStringTransformer;
 use Symfony\Component\Form\ValueTransformer\DateTimeToTimestampTransformer;
 use Symfony\Component\Form\ValueTransformer\ValueTransformerChain;
+use Symfony\Component\Form\ChoiceList\HourChoiceList;
+use Symfony\Component\Form\ChoiceList\MinuteChoiceList;
+use Symfony\Component\Form\ChoiceList\SecondChoiceList;
 
 /**
  * Represents a time field.
@@ -81,9 +84,9 @@ class TimeField extends Form
         $this->addOption('type', self::DATETIME, self::$types);
         $this->addOption('with_seconds', false);
 
-        $this->addOption('hours', range(0, 23));
-        $this->addOption('minutes', range(0, 59));
-        $this->addOption('seconds', range(0, 59));
+        $this->addOption('hours', array());
+        $this->addOption('minutes', array());
+        $this->addOption('seconds', array());
 
         $this->addOption('data_timezone', date_default_timezone_get());
         $this->addOption('user_timezone', date_default_timezone_get());
@@ -97,15 +100,15 @@ class TimeField extends Form
             }
         } else {
             $this->add(new ChoiceField('hour', array(
-                'choices' => $this->generatePaddedChoices($this->getOption('hours'), 2),
+                'choice_list' => new HourChoiceList($this->getOption('hours')),
             )));
             $this->add(new ChoiceField('minute', array(
-                'choices' => $this->generatePaddedChoices($this->getOption('minutes'), 2),
+                'choice_list' => new MinuteChoiceList($this->getOption('minutes')),
             )));
 
             if ($this->getOption('with_seconds')) {
                 $this->add(new ChoiceField('second', array(
-                    'choices' => $this->generatePaddedChoices($this->getOption('seconds'), 2),
+                    'choice_list' => new SecondChoiceList($this->getOption('seconds')),
                 )));
             }
         }