Skip to content

Commit b31cf49

Browse files
authored
Fix Model/Property Validation (#7)
Fix Model/Property Validation
2 parents 4992196 + a4e67bb commit b31cf49

File tree

5 files changed

+69
-27
lines changed

5 files changed

+69
-27
lines changed

composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"prefer-stable": true,
2020
"extra": {
2121
"branch-alias": {
22-
"dev-master": "0.4.x-dev"
22+
"dev-master": "0.5.x-dev"
2323
}
2424
},
2525
"require": {
@@ -32,7 +32,7 @@
3232
"locomotivemtl/charcoal-cache": "~0.1",
3333
"locomotivemtl/charcoal-config": "~0.9",
3434
"locomotivemtl/charcoal-factory": "~0.4",
35-
"locomotivemtl/charcoal-property": "~0.7",
35+
"locomotivemtl/charcoal-property": "~0.9",
3636
"locomotivemtl/charcoal-view": "~0.3"
3737
},
3838
"require-dev": {

src/Charcoal/Model/ModelValidator.php

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44

55
// From 'charcoal-core'
66
use Charcoal\Validator\AbstractValidator;
7+
use Charcoal\Validator\ValidatableInterface;
78

89
/**
9-
*
10+
* Model Validator
1011
*/
1112
class ModelValidator extends AbstractValidator
1213
{
@@ -15,23 +16,27 @@ class ModelValidator extends AbstractValidator
1516
*/
1617
public function validate()
1718
{
18-
$model = $this->model;
19+
$result = true;
1920

21+
$model = $this->model;
2022
$props = $model->properties();
2123

22-
$ret = true;
23-
foreach ($props as $ident => $p) {
24-
if (!$p || !$p->active()) {
24+
foreach ($props as $ident => $prop) {
25+
if (!($prop instanceof ValidatableInterface) || !$prop['active']) {
2526
continue;
2627
}
27-
$valid = $p->validate();
28-
if ($valid === false) {
29-
$validator = $p->validator();
28+
29+
$value = $model->propertyValue($ident);
30+
$isValid = $prop->setVal($value)->validate();
31+
$prop->clearVal();
32+
33+
if ($isValid === false) {
34+
$validator = $prop->validator();
3035
$this->merge($validator, $ident);
31-
$ret = false;
36+
$result = false;
3237
}
3338
}
3439

35-
return $ret;
40+
return $result;
3641
}
3742
}

src/Charcoal/Validator/AbstractValidator.php

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,6 @@
1616
*/
1717
abstract class AbstractValidator implements ValidatorInterface
1818
{
19-
const ERROR = 'error';
20-
const WARNING = 'warning';
21-
const NOTICE = 'notice';
22-
2319
/**
2420
* @var ValidatableInterface
2521
*/
@@ -30,6 +26,13 @@ abstract class AbstractValidator implements ValidatorInterface
3026
*/
3127
private $results = [];
3228

29+
/**
30+
* Holds a list of all camelized strings.
31+
*
32+
* @var string[]
33+
*/
34+
protected static $camelCache = [];
35+
3336
/**
3437
* @param ValidatableInterface $model The object to validate.
3538
*/
@@ -150,24 +153,48 @@ public function noticeResults()
150153
}
151154

152155
/**
153-
* @param ValidatorInterface $v The validator to merge.
154-
* @param string $ident_prefix Optional identigfier prefix.
156+
* @param ValidatorInterface $v The validator to merge.
157+
* @param string|null $prefix Optional key to prefix onto identifiers.
155158
* @return self
156159
*/
157-
public function merge(ValidatorInterface $v, $ident_prefix = null)
160+
public function merge(ValidatorInterface $v, $prefix = null)
158161
{
159-
$results = $v->results();
160-
foreach ($results as $level => $levelResults) {
161-
foreach ($levelResults as $r) {
162-
if ($ident_prefix !== null) {
163-
$r->set_ident($ident_prefix.'.'.$r->ident());
162+
$allResults = $v->results();
163+
164+
foreach ($allResults as $level => $resultset) {
165+
foreach ($resultset as $result) {
166+
if ($prefix !== null) {
167+
$result->setIdent($prefix.'.'.$result->ident());
164168
}
165-
$this->addResult($r);
169+
$this->addResult($result);
166170
}
167171
}
168172
return $this;
169173
}
170174

175+
/**
176+
* Transform a string from "snake_case" to "camelCase".
177+
*
178+
* @param string $value The string to camelize.
179+
* @return string The camelized string.
180+
*/
181+
final protected function camelize($value)
182+
{
183+
$key = $value;
184+
185+
if (isset(static::$camelCache[$key])) {
186+
return static::$camelCache[$key];
187+
}
188+
189+
if (strpos($value, '_') !== false) {
190+
$value = implode('', array_map('ucfirst', explode('_', $value)));
191+
}
192+
193+
static::$camelCache[$key] = lcfirst($value);
194+
195+
return static::$camelCache[$key];
196+
}
197+
171198
/**
172199
* @return boolean
173200
*/

src/Charcoal/Validator/ValidatorInterface.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
*/
88
interface ValidatorInterface
99
{
10+
const ERROR = 'error';
11+
const WARNING = 'warning';
12+
const NOTICE = 'notice';
13+
1014
/**
1115
* @param string $msg The error message.
1216
* @return self

tests/Charcoal/Model/ModelValidatorTest.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,13 @@ public function testValidateModel()
5757
]
5858
]);
5959

60-
$obj = new ModelValidator($model);
61-
$this->assertTrue($obj->validate());
60+
$validator = new ModelValidator($model);
61+
$this->assertFalse($validator->validate());
62+
63+
$model['foo'] = 'qux';
64+
$this->assertFalse($validator->validate());
65+
66+
$model['foo'] = 'xyzzy';
67+
$this->assertTrue($validator->validate());
6268
}
6369
}

0 commit comments

Comments
 (0)