Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/Javascript/JavascriptValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
namespace Proengsoft\JsValidation\Javascript;

use Exception;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Support\Facades\View;
use Illuminate\Contracts\Support\Arrayable;
use Proengsoft\JsValidation\Exceptions\PropertyNotFoundException;

class JavascriptValidator implements Arrayable
Expand Down Expand Up @@ -137,6 +137,10 @@ protected function getViewData()
$data = $this->validator->validationData();
$data['selector'] = $this->selector;

if (! is_null($this->validator->getDelegatedValidator())) {
$data['wildcards'] = $this->validator->getDelegatedValidator()->getWildcardRules();
}

if (! is_null($this->ignore)) {
$data['ignore'] = $this->ignore;
}
Expand Down
23 changes: 18 additions & 5 deletions src/Javascript/RuleParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

namespace Proengsoft\JsValidation\Javascript;

use Proengsoft\JsValidation\Support\DelegatedValidator;
use Proengsoft\JsValidation\Support\RuleListTrait;
use Proengsoft\JsValidation\Support\DelegatedValidator;
use Proengsoft\JsValidation\Support\UseDelegatedValidatorTrait;

class RuleParser
Expand Down Expand Up @@ -161,11 +161,24 @@ protected function remoteRule($attribute, $forceRemote)
*/
protected function getAttributeName($attribute)
{
$attributeArray = explode('.', $attribute);
if (count($attributeArray) > 1) {
return $attributeArray[0].'['.implode('][', array_slice($attributeArray, 1)).']';
if (stripos($attribute, '.') === false) {
return $attribute;
}

return $attribute;
$attributes = explode('.', $attribute);

return $attributes[0].
'['.
implode(
'][',
array_map(function ($attribute) {
if ($attribute === '*') {
return '';
}

return $attribute;
}, array_slice($attributes, 1))
).
']';
}
}
44 changes: 33 additions & 11 deletions src/JsValidatorFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

namespace Proengsoft\JsValidation;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Validator;
use Proengsoft\JsValidation\Javascript\JavascriptValidator;
use Proengsoft\JsValidation\Javascript\MessageParser;
use Illuminate\Foundation\Http\FormRequest;
use Proengsoft\JsValidation\Javascript\RuleParser;
use Proengsoft\JsValidation\Javascript\ValidatorHandler;
use Proengsoft\JsValidation\Javascript\MessageParser;
use Proengsoft\JsValidation\Support\DelegatedValidator;
use Proengsoft\JsValidation\Javascript\ValidatorHandler;
use Proengsoft\JsValidation\Javascript\JavascriptValidator;

class JsValidatorFactory
{
Expand Down Expand Up @@ -61,7 +61,7 @@ public function make(array $rules, array $messages = array(), array $customAttri
{
$validator = $this->getValidatorInstance($rules, $messages, $customAttributes);

return $this->validator($validator, $selector);
return $this->validator($validator, $selector, $this->wildcardRules($rules));
}

/**
Expand Down Expand Up @@ -89,7 +89,6 @@ protected function getValidatorInstance(array $rules, array $messages = array(),
* @param null $selector
*
* @return JavascriptValidator
* @throws FormRequestArgumentException
*/
public function formRequest($formRequest, $selector = null)
{
Expand All @@ -101,7 +100,28 @@ public function formRequest($formRequest, $selector = null)

$validator = $this->getValidatorInstance($rules, $formRequest->messages(), $formRequest->attributes());

return $this->validator($validator, $selector);
return $this->validator($validator, $selector, $this->wildcardRules($rules));
}

/**
* Find Laravel >= 5.2 wildcard validation rules removed by
* Illuminate\Validation\Validator@explodeRules() but required for
* JavaScript validation.
*
* @param array $rules
*
* @return array
*/
protected function wildcardRules(array $rules)
{
return array_map(
function ($attribute) use ($rules) {
return is_array($rules[$attribute]) ? $rules[$attribute] : explode('|', (string) $rules[$attribute]);
},
array_filter(array_keys($rules), function ($attribute) {
return $attribute !== '' && mb_strpos($attribute, '*') !== false;
})
);
}

protected function parseFormRequestName($class)
Expand Down Expand Up @@ -148,29 +168,31 @@ protected function createFormRequest($class)
*
* @param \Illuminate\Validation\Validator $validator
* @param string|null $selector
* @param array $wildcardRules
*
* @return JavascriptValidator
*/
public function validator(Validator $validator, $selector = null)
public function validator(Validator $validator, $selector = null, array $wildcardRules = [])
{
return $this->jsValidator($validator, $selector);
return $this->jsValidator($validator, $selector, $wildcardRules);
}

/**
* Creates JsValidator instance based on Validator.
*
* @param \Illuminate\Validation\Validator $validator
* @param string|null $selector
* @param array $wildcardRules
*
* @return JavascriptValidator
*/
protected function jsValidator(Validator $validator, $selector = null)
protected function jsValidator(Validator $validator, $selector = null, array $wildcardRules = [])
{
$remote = ! $this->options['disable_remote_validation'];
$view = $this->options['view'];
$selector = is_null($selector) ? $this->options['form_selector'] : $selector;

$delegated = new DelegatedValidator($validator);
$delegated = new DelegatedValidator($validator, $wildcardRules);
$rules = new RuleParser($delegated, $this->getSessionToken());
$messages = new MessageParser($delegated);

Expand Down
25 changes: 23 additions & 2 deletions src/Support/DelegatedValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
class DelegatedValidator
{
use AccessProtectedTrait;

/**
* The Validator resolved instance.
*
Expand All @@ -22,22 +23,32 @@ class DelegatedValidator
*/
protected $validatorMethod;

/**
* Array validation rules with * wildcard matching.
*
* @var array
*/
protected $wildcardRules;

/**
* DelegatedValidator constructor.
*
* @param \Illuminate\Validation\Validator $validator
* @param array $wildcardRules
*/
public function __construct(BaseValidator $validator)
public function __construct(BaseValidator $validator, array $wildcardRules = [])
{
$this->validator = $validator;
$this->validatorMethod = $this->createProtectedCaller($validator);
$this->wildcardRules = $wildcardRules;
}

/**
* Call validator method.
*
* @param string $method
* @param array $args
*
* @return mixed
*/
private function callValidator($method, $args = [])
Expand Down Expand Up @@ -82,7 +93,17 @@ public function setData($data)
*/
public function getRules()
{
return $this->validator->getRules();
return $this->validator->getRules() + $this->wildcardRules;
}

/**
* Get the validation rules with '*' wildcard.
*
* @return array
*/
public function getWildcardRules()
{
return $this->wildcardRules;
}

/**
Expand Down
42 changes: 42 additions & 0 deletions tests/Javascript/JavascriptValidatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,48 @@ public function testToArray()
}



public function testToArrayWildcards()
{
$mockHandler = $this->getMockBuilder('\Proengsoft\JsValidation\Javascript\ValidatorHandler')
->disableOriginalConstructor()
->setMethods(['validationData','setRemote','getDelegatedValidator'])
->getMock();

$mockHandler->expects($this->once())
->method('setRemote')
->with(true)
->willReturn([]);

$mockHandler->expects($this->once())
->method('validationData')
->with()
->willReturn([]);

$mockDelegated = $this->getMockBuilder('Proengsoft\JsValidation\Support\DelegatedValidator')
->disableOriginalConstructor()
->setMethods(['getWildcardRules'])
->getMock();

$mockDelegated->expects($this->once())
->method('getWildcardRules')
->with()
->willReturn(['person.*.email' => ['Required', 'Email']]);

$mockHandler->expects($this->exactly(2))
->method('getDelegatedValidator')
->with()
->willReturn($mockDelegated);

$validator = new JavascriptValidator($mockHandler);

$expected=['selector'=>'form','wildcards' => ['person.*.email' => ['Required', 'Email']]];
$viewData=$validator->toArray();
$this->assertEquals($expected,$viewData);

}


public function testGet()
{
$mockHandler = $this->getMockBuilder('\Proengsoft\JsValidation\Javascript\ValidatorHandler')
Expand Down