Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit77eff03

Browse files
committed
[Form] Add a DateInterval form type
Also add dateinterval widget to twig templates.
1 parent6f05632 commit77eff03

File tree

11 files changed

+1382
-0
lines changed

11 files changed

+1382
-0
lines changed

‎src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_layout.html.twig‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,25 @@
8787
{%endif %}
8888
{%-endblocktime_widget %}
8989

90+
{%blockdateinterval_widget %}
91+
{%ifwidget=='single_text' %}
92+
{{-block('form_widget_simple') -}}
93+
{%else %}
94+
{%setattr=attr|merge({class: (attr.class|default('') ~' form-inline')|trim}) %}
95+
<div {{block('widget_container_attributes') }}>
96+
{{ form_errors(form) }}
97+
{%ifwith_years %}{{ form_widget(form.years) }}{%endif %}
98+
{%ifwith_months %}{{ form_widget(form.months) }}{%endif %}
99+
{%ifwith_weeks %}{{ form_widget(form.weeks) }}{%endif %}
100+
{%ifwith_days %}{{ form_widget(form.days) }}{%endif %}
101+
{%ifwith_hours %}{{ form_widget(form.hours) }}{%endif %}
102+
{%ifwith_minutes %}{{ form_widget(form.minutes) }}{%endif %}
103+
{%ifwith_seconds %}{{ form_widget(form.seconds) }}{%endif %}
104+
{%ifwith_invert %}{{ form_widget(form.invert) }}{%endif %}
105+
</div>
106+
{%endif %}
107+
{%endblockdateinterval_widget %}
108+
90109
{%blockchoice_widget_collapsed -%}
91110
{%setattr=attr|merge({class: (attr.class|default('') ~' form-control')|trim}) %}
92111
{{-parent() -}}

‎src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,24 @@
131131
{%-endif -%}
132132
{%-endblocktime_widget -%}
133133

134+
{%blockdateinterval_widget %}
135+
{%ifwidget=='single_text' %}
136+
{{-block('form_widget_simple') -}}
137+
{%else %}
138+
<div {{block('widget_container_attributes') }}>
139+
{{ form_errors(form) }}
140+
{%ifwith_years %}{{ form_widget(form.years) }}{%endif %}
141+
{%ifwith_months %}{{ form_widget(form.months) }}{%endif %}
142+
{%ifwith_weeks %}{{ form_widget(form.weeks) }}{%endif %}
143+
{%ifwith_days %}{{ form_widget(form.days) }}{%endif %}
144+
{%ifwith_hours %}{{ form_widget(form.hours) }}{%endif %}
145+
{%ifwith_minutes %}{{ form_widget(form.minutes) }}{%endif %}
146+
{%ifwith_seconds %}{{ form_widget(form.seconds) }}{%endif %}
147+
{%ifwith_invert %}{{ form_widget(form.invert) }}{%endif %}
148+
</div>
149+
{%endif %}
150+
{%endblockdateinterval_widget %}
151+
134152
{%-blocknumber_widget -%}
135153
{# type="number" doesn't work with floats#}
136154
{%-settype=type|default('text') -%}

‎src/Symfony/Component/Form/Extension/Core/CoreExtension.php‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ protected function loadTypes()
5151
newType\ChoiceType($this->choiceListFactory),
5252
newType\CollectionType(),
5353
newType\CountryType(),
54+
newType\DateIntervalType(),
5455
newType\DateType(),
5556
newType\DateTimeType(),
5657
newType\EmailType(),
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespaceSymfony\Component\Form\Extension\Core\DataTransformer;
13+
14+
useSymfony\Component\Form\DataTransformerInterface;
15+
useSymfony\Component\Form\Exception\TransformationFailedException;
16+
useSymfony\Component\Form\Exception\UnexpectedTypeException;
17+
18+
/**
19+
* Transforms between a normalized date interval and an interval string/array.
20+
*
21+
* @author Steffen Roßkamp <steffen.rosskamp@gimmickmedia.de>
22+
*/
23+
class DateIntervalToArrayTransformerimplements DataTransformerInterface
24+
{
25+
constYEARS ='years';
26+
constMONTHS ='months';
27+
constDAYS ='days';
28+
constHOURS ='hours';
29+
constMINUTES ='minutes';
30+
constSECONDS ='seconds';
31+
constINVERT ='invert';
32+
33+
privatestatic$availableFields =array(
34+
self::YEARS =>'y',
35+
self::MONTHS =>'m',
36+
self::DAYS =>'d',
37+
self::HOURS =>'h',
38+
self::MINUTES =>'i',
39+
self::SECONDS =>'s',
40+
self::INVERT =>'r',
41+
);
42+
private$fields;
43+
44+
/**
45+
* Constructor.
46+
*
47+
* @param array $fields The date fields
48+
* @param bool $pad Whether to use padding
49+
*/
50+
publicfunction__construct(array$fields =null,$pad =false)
51+
{
52+
if (null ===$fields) {
53+
$fields =array('years','months','days','hours','minutes','seconds','invert');
54+
}
55+
$this->fields =$fields;
56+
$this->pad = (bool)$pad;
57+
}
58+
59+
/**
60+
* Transforms a normalized date interval into an interval array.
61+
*
62+
* @param \DateInterval $dateInterval Normalized date interval.
63+
*
64+
* @return array Interval array.
65+
*
66+
* @throws UnexpectedTypeException If the given value is not a \DateInterval instance.
67+
*/
68+
publicfunctiontransform($dateInterval)
69+
{
70+
if (null ===$dateInterval) {
71+
returnarray_intersect_key(
72+
array(
73+
'years' =>'',
74+
'months' =>'',
75+
'weeks' =>'',
76+
'days' =>'',
77+
'hours' =>'',
78+
'minutes' =>'',
79+
'seconds' =>'',
80+
'invert' =>false,
81+
),
82+
array_flip($this->fields)
83+
);
84+
}
85+
if (!$dateIntervalinstanceof \DateInterval) {
86+
thrownewUnexpectedTypeException($dateInterval,'\DateInterval');
87+
}
88+
$result =array();
89+
foreach (self::$availableFieldsas$field =>$char) {
90+
$result[$field] =$dateInterval->format('%'.($this->pad ?strtoupper($char) :$char));
91+
}
92+
if (in_array('weeks',$this->fields,true)) {
93+
$result['weeks'] =0;
94+
if (isset($result['days']) && (int)$result['days'] >=7) {
95+
$result['weeks'] = (string)floor($result['days'] /7);
96+
$result['days'] = (string) ($result['days'] %7);
97+
}
98+
}
99+
$result['invert'] ='-' ===$result['invert'];
100+
$result =array_intersect_key($result,array_flip($this->fields));
101+
102+
return$result;
103+
}
104+
105+
/**
106+
* Transforms an interval array into a normalized date interval.
107+
*
108+
* @param array $value Interval array
109+
*
110+
* @return \DateInterval Normalized date interval
111+
*
112+
* @throws UnexpectedTypeException If the given value is not an array.
113+
* @throws TransformationFailedException If the value could not be transformed.
114+
*/
115+
publicfunctionreverseTransform($value)
116+
{
117+
if (null ===$value) {
118+
return;
119+
}
120+
if (!is_array($value)) {
121+
thrownewUnexpectedTypeException($value,'array');
122+
}
123+
if ('' ===implode('',$value)) {
124+
return;
125+
}
126+
$emptyFields =array();
127+
foreach ($this->fieldsas$field) {
128+
if (!isset($value[$field])) {
129+
$emptyFields[] =$field;
130+
}
131+
}
132+
if (count($emptyFields) >0) {
133+
thrownewTransformationFailedException(
134+
sprintf('The fields "%s" should not be empty',implode('", "',$emptyFields))
135+
);
136+
}
137+
if (isset($value['invert']) && !is_bool($value['invert'])) {
138+
thrownewUnexpectedTypeException($value['invert'],'boolean');
139+
}
140+
foreach (self::$availableFieldsas$field =>$char) {
141+
if ($field !=='invert' &&isset($value[$field]) && !ctype_digit((string)$value[$field])) {
142+
thrownewTransformationFailedException(sprintf('This amount of "%s" is invalid',$field));
143+
}
144+
}
145+
try {
146+
if (!empty($value['weeks'])) {
147+
$interval =sprintf(
148+
'P%sY%sM%sWT%sH%sM%sS',
149+
empty($value['years']) ?'0' :$value['years'],
150+
empty($value['months']) ?'0' :$value['months'],
151+
empty($value['weeks']) ?'0' :$value['weeks'],
152+
empty($value['hours']) ?'0' :$value['hours'],
153+
empty($value['minutes']) ?'0' :$value['minutes'],
154+
empty($value['seconds']) ?'0' :$value['seconds']
155+
);
156+
}else {
157+
$interval =sprintf(
158+
'P%sY%sM%sDT%sH%sM%sS',
159+
empty($value['years']) ?'0' :$value['years'],
160+
empty($value['months']) ?'0' :$value['months'],
161+
empty($value['days']) ?'0' :$value['days'],
162+
empty($value['hours']) ?'0' :$value['hours'],
163+
empty($value['minutes']) ?'0' :$value['minutes'],
164+
empty($value['seconds']) ?'0' :$value['seconds']
165+
);
166+
}
167+
$dateInterval =new \DateInterval($interval);
168+
if (!empty($value['invert'])) {
169+
$dateInterval->invert =$value['invert'] ?1 :0;
170+
}
171+
}catch (\Exception$e) {
172+
thrownewTransformationFailedException($e->getMessage(),$e->getCode(),$e);
173+
}
174+
175+
return$dateInterval;
176+
}
177+
}
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespaceSymfony\Component\Form\Extension\Core\DataTransformer;
13+
14+
useSymfony\Component\Form\DataTransformerInterface;
15+
useSymfony\Component\Form\Exception\TransformationFailedException;
16+
useSymfony\Component\Form\Exception\UnexpectedTypeException;
17+
18+
/**
19+
* Transforms between a date string and a DateInterval object.
20+
*
21+
* @author Steffen Roßkamp <steffen.rosskamp@gimmickmedia.de>
22+
*/
23+
class DateIntervalToStringTransformerimplements DataTransformerInterface
24+
{
25+
private$format;
26+
private$parseSigned;
27+
28+
/**
29+
* Transforms a \DateInterval instance to a string.
30+
*
31+
* @see \DateInterval::format() for supported formats
32+
*
33+
* @param string $format The date format
34+
* @param bool $parseSigned Whether to parse as a signed interval
35+
*/
36+
publicfunction__construct($format ='P%yY%mM%dDT%hH%iM%sS',$parseSigned =false)
37+
{
38+
$this->format =$format;
39+
$this->parseSigned =$parseSigned;
40+
}
41+
42+
/**
43+
* Transforms a DateInterval object into a date string with the configured format.
44+
*
45+
* @param \DateInterval $value A DateInterval object
46+
*
47+
* @return string An ISO 8601 or relative date string like date interval presentation
48+
*
49+
* @throws UnexpectedTypeException If the given value is not a \DateInterval instance.
50+
*/
51+
publicfunctiontransform($value)
52+
{
53+
if (null ===$value) {
54+
return'';
55+
}
56+
if (!$valueinstanceof \DateInterval) {
57+
thrownewUnexpectedTypeException($value,'\DateInterval');
58+
}
59+
60+
return$value->format($this->format);
61+
}
62+
63+
/**
64+
* Transforms a date string in the configured format into a DateInterval object.
65+
*
66+
* @param string $value An ISO 8601 or date string like date interval presentation
67+
*
68+
* @return \DateInterval An instance of \DateInterval
69+
*
70+
* @throws UnexpectedTypeException If the given value is not a string.
71+
* @throws TransformationFailedException If the date interval could not be parsed.
72+
*/
73+
publicfunctionreverseTransform($value)
74+
{
75+
if (null ===$value) {
76+
return;
77+
}
78+
if (!is_string($value)) {
79+
thrownewUnexpectedTypeException($value,'string');
80+
}
81+
if ('' ===$value) {
82+
return;
83+
}
84+
if (!$this->isISO8601($value)) {
85+
thrownewTransformationFailedException('Non ISO 8601 date strings are not supported yet');
86+
}
87+
$valuePattern ='/^'.preg_replace('/%([yYmMdDhHiIsSwW])(\w)/','(?P<$1>\d+)$2',$this->format).'$/';
88+
if (!preg_match($valuePattern,$value)) {
89+
thrownewTransformationFailedException(
90+
sprintf('Value "%s" contains intervals not accepted by format "%s".',$value,$this->format)
91+
);
92+
}
93+
try {
94+
$dateInterval =new \DateInterval($value);
95+
}catch (\Exception$e) {
96+
thrownewTransformationFailedException($e->getMessage(),$e->getCode(),$e);
97+
}
98+
99+
return$dateInterval;
100+
}
101+
102+
/**
103+
* Checks if a string is a valid ISO 8601 duration string.
104+
*
105+
* @param string $string A string
106+
*
107+
* @return int
108+
*/
109+
privatefunctionisISO8601($string)
110+
{
111+
returnpreg_match(
112+
'/^P(?=\w*(?:\d|%\w))(?:\d+Y|%[yY]Y)?(?:\d+M|%[mM]M)?(?:(?:\d+D|%[dD]D)|(?:\d+W|%[wW]W))?(?:T(?:\d+H|[hH]H)?(?:\d+M|[iI]M)?(?:\d+S|[sS]S)?)?$/',
113+
$string
114+
);
115+
}
116+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp