Skip to content

Commit c4a2f02

Browse files
dFayetxabbuh
dFayet
authored andcommitted
Add new Form WeekType
1 parent 3936b78 commit c4a2f02

File tree

10 files changed

+947
-0
lines changed

10 files changed

+947
-0
lines changed

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

+11
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,17 @@
255255
{{ block('form_widget_simple') }}
256256
{%- endblock color_widget -%}
257257

258+
{%- block week_widget -%}
259+
{%- if widget == 'single_text' -%}
260+
{{ block('form_widget_simple') }}
261+
{%- else -%}
262+
{%- set vars = widget == 'text' ? { 'attr': { 'size': 1 }} : {} -%}
263+
<div {{ block('widget_container_attributes') }}>
264+
{{ form_widget(form.year, vars) }}-{{ form_widget(form.week, vars) }}
265+
</div>
266+
{%- endif -%}
267+
{%- endblock week_widget -%}
268+
258269
{# Labels #}
259270

260271
{%- block form_label -%}

src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php

+98
Original file line numberDiff line numberDiff line change
@@ -2722,6 +2722,104 @@ public function testColor()
27222722
[@name="name"]
27232723
[@class="my&class form-control"]
27242724
[@value="#0000ff"]
2725+
'
2726+
);
2727+
}
2728+
2729+
public function testWeekSingleText()
2730+
{
2731+
$this->requiresFeatureSet(404);
2732+
2733+
$form = $this->factory->createNamed('holidays', 'Symfony\Component\Form\Extension\Core\Type\WeekType', '1970-W01', [
2734+
'input' => 'string',
2735+
'widget' => 'single_text',
2736+
]);
2737+
2738+
$this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
2739+
'/input
2740+
[@type="week"]
2741+
[@name="holidays"]
2742+
[@class="my&class form-control"]
2743+
[@value="1970-W01"]
2744+
[not(@maxlength)]
2745+
'
2746+
);
2747+
}
2748+
2749+
public function testWeekSingleTextNoHtml5()
2750+
{
2751+
$this->requiresFeatureSet(404);
2752+
2753+
$form = $this->factory->createNamed('holidays', 'Symfony\Component\Form\Extension\Core\Type\WeekType', '1970-W01', [
2754+
'input' => 'string',
2755+
'widget' => 'single_text',
2756+
'html5' => false,
2757+
]);
2758+
2759+
$this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
2760+
'/input
2761+
[@type="text"]
2762+
[@name="holidays"]
2763+
[@class="my&class form-control"]
2764+
[@value="1970-W01"]
2765+
[not(@maxlength)]
2766+
'
2767+
);
2768+
}
2769+
2770+
public function testWeekChoices()
2771+
{
2772+
$this->requiresFeatureSet(404);
2773+
2774+
$data = ['year' => date('Y'), 'week' => 1];
2775+
2776+
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\WeekType', $data, [
2777+
'input' => 'array',
2778+
'required' => false,
2779+
]);
2780+
2781+
$this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
2782+
'/div
2783+
[@class="my&class"]
2784+
[
2785+
./select
2786+
[@id="name_year"]
2787+
[@class="form-control"]
2788+
[./option[@value="'.$data['year'].'"][@selected="selected"]]
2789+
/following-sibling::select
2790+
[@id="name_week"]
2791+
[@class="form-control"]
2792+
[./option[@value="'.$data['week'].'"][@selected="selected"]]
2793+
]
2794+
[count(.//select)=2]'
2795+
);
2796+
}
2797+
2798+
public function testWeekText()
2799+
{
2800+
$this->requiresFeatureSet(404);
2801+
2802+
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\WeekType', '2000-W01', [
2803+
'input' => 'string',
2804+
'widget' => 'text',
2805+
]);
2806+
2807+
$this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
2808+
'/div
2809+
[@class="my&class"]
2810+
[
2811+
./input
2812+
[@id="name_year"]
2813+
[@type="number"]
2814+
[@class="form-control"]
2815+
[@value="2000"]
2816+
/following-sibling::input
2817+
[@id="name_week"]
2818+
[@type="number"]
2819+
[@class="form-control"]
2820+
[@value="1"]
2821+
]
2822+
[count(./input)=2]
27252823
'
27262824
);
27272825
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php if ($widget == 'single_text'): ?>
2+
<?php echo $view['form']->block($form, 'form_widget_simple'); ?>
3+
<?php else: ?>
4+
<?php $vars = $widget == 'text' ? ['attr' => ['size' => 1]] : [] ?>
5+
<div <?php echo $view['form']->block($form, 'widget_container_attributes') ?>>
6+
<?php
7+
// There should be no spaces between the colons and the widgets, that's why
8+
// this block is written in a single PHP tag
9+
echo $view['form']->widget($form['year'], $vars);
10+
echo '-';
11+
echo $view['form']->widget($form['week'], $vars);
12+
?>
13+
</div>
14+
<?php endif ?>

src/Symfony/Component/Form/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ CHANGELOG
44
4.4.0
55
-----
66

7+
* add new `WeekType`
78
* using different values for the "model_timezone" and "view_timezone" options of the `TimeType` without configuring a
89
reference date is deprecated
910
* preferred choices are repeated in the list of all choices

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

+1
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ protected function loadTypes()
8383
new Type\CurrencyType(),
8484
new Type\TelType(),
8585
new Type\ColorType(),
86+
new Type\WeekType(),
8687
];
8788
}
8889

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
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+
namespace Symfony\Component\Form\Extension\Core\DataTransformer;
13+
14+
use Symfony\Component\Form\DataTransformerInterface;
15+
use Symfony\Component\Form\Exception\TransformationFailedException;
16+
17+
/**
18+
* Transforms between an ISO 8601 week date string and an array.
19+
*
20+
* @author Damien Fayet <damienf1521@gmail.com>
21+
*/
22+
class WeekToArrayTransformer implements DataTransformerInterface
23+
{
24+
/**
25+
* Transforms a string containing an ISO 8601 week date into an array.
26+
*
27+
* @param string|null $value A week date string
28+
*
29+
* @return array A value containing year and week
30+
*
31+
* @throws TransformationFailedException If the given value is not a string,
32+
* or if the given value does not follow the right format
33+
*/
34+
public function transform($value)
35+
{
36+
if (null === $value) {
37+
return ['year' => null, 'week' => null];
38+
}
39+
40+
if (!\is_string($value)) {
41+
throw new TransformationFailedException(sprintf('Value is expected to be a string but was "%s".', \is_object($value) ? \get_class($value) : \gettype($value)));
42+
}
43+
44+
if (0 === preg_match('/^(?P<year>\d{4})-W(?P<week>\d{2})$/', $value, $matches)) {
45+
throw new TransformationFailedException('Given data does not follow the date format "Y-\WW".');
46+
}
47+
48+
return [
49+
'year' => (int) $matches['year'],
50+
'week' => (int) $matches['week'],
51+
];
52+
}
53+
54+
/**
55+
* Transforms an array into a week date string.
56+
*
57+
* @param array $value An array containing a year and a week number
58+
*
59+
* @return string|null A week date string following the format Y-\WW
60+
*
61+
* @throws TransformationFailedException If the given value can not be merged in a valid week date string,
62+
* or if the obtained week date does not exists
63+
*/
64+
public function reverseTransform($value)
65+
{
66+
if (null === $value || [] === $value) {
67+
return null;
68+
}
69+
70+
if (!\is_array($value)) {
71+
throw new TransformationFailedException(sprintf('Value is expected to be an array, but was "%s".', \is_object($value) ? \get_class($value) : \gettype($value)));
72+
}
73+
74+
if (!\array_key_exists('year', $value)) {
75+
throw new TransformationFailedException('Key "year" is missing.');
76+
}
77+
78+
if (!\array_key_exists('week', $value)) {
79+
throw new TransformationFailedException('Key "week" is missing.');
80+
}
81+
82+
if ($additionalKeys = array_diff(array_keys($value), ['year', 'week'])) {
83+
throw new TransformationFailedException(sprintf('Expected only keys "year" and "week" to be present, but also got ["%s"].', implode('", "', $additionalKeys)));
84+
}
85+
86+
if (null === $value['year'] && null === $value['week']) {
87+
return null;
88+
}
89+
90+
if (!\is_int($value['year'])) {
91+
throw new TransformationFailedException(sprintf('Year is expected to be an integer, but was "%s".', \is_object($value['year']) ? \get_class($value['year']) : \gettype($value['year'])));
92+
}
93+
94+
if (!\is_int($value['week'])) {
95+
throw new TransformationFailedException(sprintf('Week is expected to be an integer, but was "%s".', \is_object($value['week']) ? \get_class($value['week']) : \gettype($value['week'])));
96+
}
97+
98+
// The 28th December is always in the last week of the year
99+
if (date('W', strtotime('28th December '.$value['year'])) < $value['week']) {
100+
throw new TransformationFailedException(sprintf('Week "%d" does not exist for year "%d".', $value['week'], $value['year']));
101+
}
102+
103+
return sprintf('%d-W%02d', $value['year'], $value['week']);
104+
}
105+
}

0 commit comments

Comments
 (0)