Skip to content

Commit 5aa4ce3

Browse files
dFayetdFayet
authored andcommitted
Add new Form WeekType
1 parent a29aff0 commit 5aa4ce3

File tree

10 files changed

+1033
-0
lines changed

10 files changed

+1033
-0
lines changed

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

Lines changed: 11 additions & 0 deletions
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

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2722,6 +2722,97 @@ 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+
$form = $this->factory->createNamed('holidays', 'Symfony\Component\Form\Extension\Core\Type\WeekType', '1970-W01', [
2732+
'input' => 'string',
2733+
'widget' => 'single_text',
2734+
]);
2735+
2736+
$this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
2737+
'/input
2738+
[@type="week"]
2739+
[@name="holidays"]
2740+
[@class="my&class form-control"]
2741+
[@value="1970-W01"]
2742+
[not(@maxlength)]
2743+
'
2744+
);
2745+
}
2746+
2747+
public function testWeekSingleTextNoHtml5()
2748+
{
2749+
$form = $this->factory->createNamed('holidays', 'Symfony\Component\Form\Extension\Core\Type\WeekType', '1970-W01', [
2750+
'input' => 'string',
2751+
'widget' => 'single_text',
2752+
'html5' => false,
2753+
]);
2754+
2755+
$this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
2756+
'/input
2757+
[@type="text"]
2758+
[@name="holidays"]
2759+
[@class="my&class form-control"]
2760+
[@value="1970-W01"]
2761+
[not(@maxlength)]
2762+
'
2763+
);
2764+
}
2765+
2766+
public function testWeekChoices()
2767+
{
2768+
$data = ['year' => date('Y'), 'week' => 'W01'];
2769+
2770+
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\WeekType', $data, [
2771+
'input' => 'array',
2772+
'required' => false,
2773+
]);
2774+
2775+
$this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
2776+
'/div
2777+
[@class="my&class"]
2778+
[
2779+
./select
2780+
[@id="name_year"]
2781+
[@class="form-control"]
2782+
[./option[@value="' . $data['year'] . '"][@selected="selected"]]
2783+
/following-sibling::select
2784+
[@id="name_week"]
2785+
[@class="form-control"]
2786+
[./option[@value="' . $data['week'] . '"][@selected="selected"]]
2787+
]
2788+
[count(.//select)=2]'
2789+
);
2790+
}
2791+
2792+
2793+
public function testWeekText()
2794+
{
2795+
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\WeekType', '2000-W01', [
2796+
'input' => 'string',
2797+
'widget' => 'text',
2798+
]);
2799+
2800+
$this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
2801+
'/div
2802+
[@class="my&class"]
2803+
[
2804+
./input
2805+
[@id="name_year"]
2806+
[@type="text"]
2807+
[@class="form-control"]
2808+
[@value="2000"]
2809+
/following-sibling::input
2810+
[@id="name_week"]
2811+
[@type="text"]
2812+
[@class="form-control"]
2813+
[@value="W01"]
2814+
]
2815+
[count(./input)=2]
27252816
'
27262817
);
27272818
}
Lines changed: 14 additions & 0 deletions
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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
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 am ISO 8601 week date string and an array.
19+
*
20+
* @author Damien Fayet <damienf1521@gmail.com>
21+
*/
22+
class WeekDateToArrayTransformer implements DataTransformerInterface
23+
{
24+
/**
25+
* Transforms a string containing an ISO 8601 week date into an array.
26+
*
27+
* @param string|null $weekdate 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($weekdate)
35+
{
36+
if (null === $weekdate) {
37+
return ['year' => '', 'week' => ''];
38+
}
39+
40+
if (!\is_string($weekdate)) {
41+
throw new TransformationFailedException('Expected a string.');
42+
}
43+
44+
if (0 === preg_match('/^\d{4}-W\d{2}$/', $weekdate)) {
45+
throw new TransformationFailedException('Given data does not follow the date format "Y-\WW"');
46+
}
47+
48+
return array_combine(['year', 'week'], explode('-', $weekdate));
49+
}
50+
51+
/**
52+
* Transforms an array into a week date string.
53+
*
54+
* @param array $value An array containing a year and a week number
55+
*
56+
* @return string|null A week date string following the format Y-\WW
57+
*
58+
* @throws TransformationFailedException If the given value can not be merged in a valid week date string,
59+
* or if the obtained week date does not exists
60+
*/
61+
public function reverseTransform($value)
62+
{
63+
if (empty($value)) {
64+
return;
65+
}
66+
67+
if (!\is_array($value)) {
68+
throw new TransformationFailedException('Expected an array.');
69+
}
70+
71+
$gluedValue = implode('-', $value);
72+
73+
if ('-' === $gluedValue) {
74+
return;
75+
}
76+
77+
if (0 === preg_match('/^\d{4}-W\d{2}$/', $gluedValue)) {
78+
throw new TransformationFailedException('Given data does not contains valid year, and week combination following format "Y-\WW"');
79+
}
80+
81+
$weekNumber = ltrim($value['week'], 'W');
82+
83+
// The 28th December is always in the last week of the year
84+
if (date('W', strtotime('28th December '.$value['year'])) < $weekNumber) {
85+
throw new TransformationFailedException(sprintf('Week No. %s does not exists for year %d', $weekNumber, $value['year']));
86+
}
87+
88+
return $gluedValue;
89+
}
90+
}

0 commit comments

Comments
 (0)
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