Skip to content

Commit b9ee07c

Browse files
authored
refs #447: adding same: rule automatically (#710)
1 parent 7775b3e commit b9ee07c

File tree

4 files changed

+123
-4
lines changed

4 files changed

+123
-4
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ composer.phar
33
composer.lock
44
.DS_Store
55
.idea
6+
.vscode
67
coverage
78
*.taskpaper
8-
NOTES.md
9+
NOTES.md
10+
.phpunit.result.cache

src/Kris/LaravelFormBuilder/Fields/FormField.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ protected function prepareRules(array &$sourceOptions = [])
361361

362362
// Append rules
363363
if ($rulesToBeAppended = Arr::pull($sourceOptions, 'rules_append')) {
364-
$mergedRules = array_values(array_unique(array_merge($options['rules'], $rulesToBeAppended), SORT_REGULAR));
364+
$mergedRules = $this->mergeRules($options['rules'], $rulesToBeAppended);
365365
$options['rules'] = $mergedRules;
366366
}
367367

@@ -390,6 +390,18 @@ protected function normalizeRules($rules)
390390
return $rules;
391391
}
392392

393+
/**
394+
* Merges two sets of rules into one
395+
*
396+
* @param array $first first set of rules
397+
* @param array $second second set of rules
398+
* @return array merged set of rules without duplicates
399+
*/
400+
protected function mergeRules($first, $second)
401+
{
402+
return array_values(array_unique(array_merge($first, $second), SORT_REGULAR));
403+
}
404+
393405

394406
/**
395407
* Get name of the field.

src/Kris/LaravelFormBuilder/Fields/RepeatedType.php

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace Kris\LaravelFormBuilder\Fields;
44

5+
use Illuminate\Support\Arr;
6+
57
class RepeatedType extends ParentType
68
{
79

@@ -42,21 +44,36 @@ public function getAllAttributes()
4244
*/
4345
protected function createChildren()
4446
{
47+
$this->prepareOptions();
48+
4549
$firstName = $this->getRealName();
4650
$secondName = $this->getOption('second_name');
4751

4852
if (is_null($secondName)) {
4953
$secondName = $firstName.'_confirmation';
5054
}
5155

56+
// merge field rules and first field rules
57+
$firstOptions = $this->getOption('first_options');
58+
$firstOptions['rules'] = $this->normalizeRules(Arr::pull($firstOptions, 'rules', []));
59+
if ($mainRules = $this->getOption('rules')) {
60+
$firstOptions['rules'] = $this->mergeRules($mainRules, $firstOptions['rules']);
61+
}
62+
63+
$sameRule = 'same:' . $secondName;
64+
if (!in_array($sameRule, $firstOptions['rules'])) {
65+
$firstOptions['rules'][] = $sameRule;
66+
}
67+
5268
$form = $this->parent->getFormBuilder()->plain([
5369
'name' => $this->parent->getName(),
5470
'model' => $this->parent->getModel()
5571
])
56-
->add($firstName, $this->getOption('type'), $this->getOption('first_options'))
72+
->add($firstName, $this->getOption('type'), $firstOptions)
5773
->add($secondName, $this->getOption('type'), $this->getOption('second_options'));
5874

5975
$this->children['first'] = $form->getField($firstName);
6076
$this->children['second'] = $form->getField($secondName);
6177
}
78+
6279
}

tests/Fields/RepeatedTypeTest.php

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
<?php
22

3+
34
use Kris\LaravelFormBuilder\Fields\RepeatedType;
4-
use Kris\LaravelFormBuilder\Form;
5+
56

67
class RepeatedTypeTest extends FormBuilderTestCase
78
{
@@ -36,4 +37,91 @@ public function it_checks_if_field_rendered_by_children()
3637

3738
$this->assertTrue($this->plainForm->getFormOption('files'));
3839
}
40+
41+
/** @test */
42+
public function handles_validation_rules_properly()
43+
{
44+
// has no other rules
45+
$plainForm = $this->formBuilder->plain();
46+
$plainForm->add('password', 'repeated');
47+
$repeated = $plainForm->getField('password');
48+
49+
$this->assertContains('same:password_confirmation', $repeated->first->getOption('rules'));
50+
51+
$this->request['password'] = '123';
52+
$this->request['password_confirmation'] = '124';
53+
54+
$valid = $plainForm->isValid();
55+
$this->assertFalse($valid);
56+
57+
$errors = [
58+
'password' => ['The Password and password confirmation must match.'],
59+
];
60+
$this->assertEquals($errors, $plainForm->getErrors());
61+
62+
// has own rules
63+
$plainForm = $this->formBuilder->plain();
64+
$plainForm->add('password', 'repeated', [
65+
'rules' => 'required|min:5',
66+
]);
67+
$plainForm->renderForm();
68+
69+
$rules = ['password' => ['required', 'min:5', 'same:password_confirmation']];
70+
$this->assertEquals($rules, $plainForm->getRules());
71+
72+
$valid = $plainForm->isValid();
73+
$this->assertFalse($valid);
74+
75+
$errors = [
76+
'password' => [
77+
'The Password must be at least 5 characters.',
78+
'The Password and password confirmation must match.',
79+
]
80+
];
81+
$this->assertEquals($errors, $plainForm->getErrors());
82+
83+
// has own rules on field and in first field options
84+
$plainForm = $this->formBuilder->plain();
85+
$plainForm->add('password', 'repeated', [
86+
'rules' => 'required',
87+
'first_options' => [
88+
'rules' => 'min:5',
89+
]
90+
]);
91+
$rules = ['password' => ['required', 'min:5', 'same:password_confirmation']];
92+
$this->assertEquals($rules, $plainForm->getRules());
93+
$valid = $plainForm->isValid();
94+
$this->assertFalse($valid);
95+
96+
$errors = [
97+
'password' => [
98+
'The Password must be at least 5 characters.',
99+
'The Password and password confirmation must match.',
100+
]
101+
];
102+
$this->assertEquals($errors, $plainForm->getErrors());
103+
104+
// has rules only in field options
105+
$plainForm = $this->formBuilder->plain();
106+
$plainForm->add('password', 'repeated', [
107+
'rules' => 'required',
108+
'first_options' => [
109+
'rules' => 'required|min:5',
110+
]
111+
]);
112+
$rules = ['password' => ['required', 'min:5', 'same:password_confirmation']];
113+
$this->assertEquals($rules, $plainForm->getRules());
114+
115+
$valid = $plainForm->isValid();
116+
$this->assertFalse($valid);
117+
118+
$errors = [
119+
'password' => [
120+
'The Password must be at least 5 characters.',
121+
'The Password and password confirmation must match.',
122+
]
123+
];
124+
$this->assertEquals($errors, $plainForm->getErrors());
125+
}
126+
39127
}

0 commit comments

Comments
 (0)