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

This commit is contained in:
Bernhard Schussek 2011-02-16 18:01:42 +01:00
parent f39d8b62f2
commit 5eb5cc5743
11 changed files with 248 additions and 88 deletions

View File

@ -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')) {

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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,59 +167,18 @@ class DateField extends HybridField
$this->setFieldMode(self::FORM);
$this->addChoiceFields();
$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')),
)));
}
}
/**
* 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);
}
return $choices;
}
public function getPattern()
{
// set order as specified in the pattern
@ -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
*

View File

@ -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());

View File

@ -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')),
)));
}
}