vendor and env first commit
This commit is contained in:
+21
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Proengsoft\JsValidation\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
class PropertyNotFoundException extends Exception
|
||||
{
|
||||
/**
|
||||
* Property Not Found Exception.
|
||||
*
|
||||
* @param string $property
|
||||
* @param string $caller
|
||||
* @param \Exception $previous
|
||||
*/
|
||||
public function __construct($property = '', $caller = '', Exception $previous = null)
|
||||
{
|
||||
$message = "'$property' not found in '$caller'' object";
|
||||
parent::__construct($message, 0, $previous);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Proengsoft\JsValidation\Facades;
|
||||
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
|
||||
class JsValidatorFacade extends Facade
|
||||
{
|
||||
/**
|
||||
* Get the registered name of the component.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeAccessor()
|
||||
{
|
||||
return 'jsvalidator';
|
||||
}
|
||||
}
|
||||
+207
@@ -0,0 +1,207 @@
|
||||
<?php
|
||||
|
||||
namespace Proengsoft\JsValidation\Javascript;
|
||||
|
||||
trait JavascriptRulesTrait
|
||||
{
|
||||
/**
|
||||
* Handles multidimensional attribute names.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @return string
|
||||
*/
|
||||
abstract protected function getAttributeName($attribute);
|
||||
|
||||
/**
|
||||
* Parse named parameters to $key => $value items.
|
||||
*
|
||||
* @param array $parameters
|
||||
* @return array
|
||||
*/
|
||||
abstract public function parseNamedParameters($parameters);
|
||||
|
||||
/**
|
||||
* Confirmed rule is applied to confirmed attribute.
|
||||
*
|
||||
* @param $attribute
|
||||
* @param array $parameters
|
||||
* @return array
|
||||
*/
|
||||
protected function ruleConfirmed($attribute, array $parameters)
|
||||
{
|
||||
$parameters[0] = $this->getAttributeName($attribute);
|
||||
$attribute = "{$attribute}_confirmation";
|
||||
|
||||
return [$attribute, $parameters];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Javascript parameters for After rule.
|
||||
*
|
||||
* @param $attribute
|
||||
* @param array $parameters
|
||||
* @return array
|
||||
*/
|
||||
protected function ruleAfter($attribute, array $parameters)
|
||||
{
|
||||
if (! ($date = strtotime($parameters[0]))) {
|
||||
$date = $this->getAttributeName($parameters[0]);
|
||||
}
|
||||
|
||||
return [$attribute, [$date]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Javascript parameters for Before rule.
|
||||
*
|
||||
* @param $attribute
|
||||
* @param array $parameters
|
||||
* @return array
|
||||
*/
|
||||
protected function ruleBefore($attribute, array $parameters)
|
||||
{
|
||||
return $this->ruleAfter($attribute, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that two attributes match.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param array $parameters
|
||||
* @return array
|
||||
*/
|
||||
protected function ruleSame($attribute, array $parameters)
|
||||
{
|
||||
$other = $this->getAttributeName($parameters[0]);
|
||||
|
||||
return [$attribute, [$other]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that an attribute is different from another attribute.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param array $parameters
|
||||
* @return array
|
||||
*/
|
||||
protected function ruleDifferent($attribute, array $parameters)
|
||||
{
|
||||
return $this->ruleSame($attribute, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that an attribute exists when any other attribute exists.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $parameters
|
||||
* @return array
|
||||
*/
|
||||
protected function ruleRequiredWith($attribute, array $parameters)
|
||||
{
|
||||
$parameters = array_map([$this, 'getAttributeName'], $parameters);
|
||||
|
||||
return [$attribute, $parameters];
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that an attribute exists when all other attributes exists.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $parameters
|
||||
* @return array
|
||||
*/
|
||||
protected function ruleRequiredWithAll($attribute, array $parameters)
|
||||
{
|
||||
return $this->ruleRequiredWith($attribute, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that an attribute exists when another attribute does not.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $parameters
|
||||
* @return array
|
||||
*/
|
||||
protected function ruleRequiredWithout($attribute, array $parameters)
|
||||
{
|
||||
return $this->ruleRequiredWith($attribute, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that an attribute exists when all other attributes do not.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $parameters
|
||||
* @return array
|
||||
*/
|
||||
protected function ruleRequiredWithoutAll($attribute, array $parameters)
|
||||
{
|
||||
return $this->ruleRequiredWith($attribute, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that an attribute exists when another attribute has a given value.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $parameters
|
||||
* @return array
|
||||
*/
|
||||
protected function ruleRequiredIf($attribute, array $parameters)
|
||||
{
|
||||
$parameters[0] = $this->getAttributeName($parameters[0]);
|
||||
|
||||
return [$attribute, $parameters];
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that an attribute exists when another attribute does not have a given value.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $parameters
|
||||
* @return array
|
||||
*/
|
||||
protected function ruleRequiredUnless($attribute, array $parameters)
|
||||
{
|
||||
return $this->ruleRequiredIf($attribute, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that the values of an attribute is in another attribute.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $parameters
|
||||
* @return array
|
||||
*/
|
||||
protected function ruleInArray($attribute, array $parameters)
|
||||
{
|
||||
return $this->ruleRequiredIf($attribute, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the dimensions of an image matches the given values.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param array $parameters
|
||||
* @return array
|
||||
*/
|
||||
protected function ruleDimensions($attribute, $parameters)
|
||||
{
|
||||
$parameters = $this->parseNamedParameters($parameters);
|
||||
|
||||
return [$attribute, $parameters];
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate an attribute is unique among other values.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param array $parameters
|
||||
* @return array
|
||||
*/
|
||||
protected function ruleDistinct($attribute, array $parameters)
|
||||
{
|
||||
$parameters[0] = $attribute;
|
||||
|
||||
return $this->ruleRequiredIf($attribute, $parameters);
|
||||
}
|
||||
}
|
||||
+230
@@ -0,0 +1,230 @@
|
||||
<?php
|
||||
|
||||
namespace Proengsoft\JsValidation\Javascript;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Illuminate\Support\Facades\View;
|
||||
use Proengsoft\JsValidation\Exceptions\PropertyNotFoundException;
|
||||
|
||||
class JavascriptValidator implements Arrayable
|
||||
{
|
||||
/**
|
||||
* Registered validator instance.
|
||||
*
|
||||
* @var ValidatorHandler
|
||||
*/
|
||||
protected $validator;
|
||||
|
||||
/**
|
||||
* Selector used in javascript generation.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $selector;
|
||||
|
||||
/**
|
||||
* View that renders Javascript.
|
||||
*
|
||||
* @var
|
||||
*/
|
||||
protected $view;
|
||||
|
||||
/**
|
||||
* Enable or disable remote validations.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $remote;
|
||||
|
||||
/**
|
||||
* 'ignore' option for jQuery Validation Plugin.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $ignore;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param ValidatorHandler $validator
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct(ValidatorHandler $validator, $options = [])
|
||||
{
|
||||
$this->validator = $validator;
|
||||
$this->setDefaults($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set default parameters.
|
||||
*
|
||||
* @param $options
|
||||
* @return void
|
||||
*/
|
||||
protected function setDefaults($options)
|
||||
{
|
||||
$this->selector = empty($options['selector']) ? 'form' : $options['selector'];
|
||||
$this->view = empty($options['view']) ? 'jsvalidation::bootstrap' : $options['view'];
|
||||
$this->remote = isset($options['remote']) ? $options['remote'] : true;
|
||||
|
||||
if (isset($options['ignore'])) {
|
||||
$this->ignore = $options['ignore'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the specified view with validator data.
|
||||
*
|
||||
* @param null|\Illuminate\Contracts\View\View|string $view
|
||||
* @param null|string $selector
|
||||
* @return string
|
||||
*/
|
||||
public function render($view = null, $selector = null)
|
||||
{
|
||||
$this->view($view);
|
||||
$this->selector($selector);
|
||||
|
||||
return View::make($this->view, ['validator' => $this->getViewData()])
|
||||
->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view data as an array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return $this->getViewData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the string resulting of render default view.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
try {
|
||||
return $this->render();
|
||||
} catch (Exception $exception) {
|
||||
return trigger_error($exception->__toString(), E_USER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets value from view data.
|
||||
*
|
||||
* @param $name
|
||||
* @return string
|
||||
*
|
||||
* @throws \Proengsoft\JsValidation\Exceptions\PropertyNotFoundException
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
$data = $this->getViewData();
|
||||
if (! array_key_exists($name, $data)) {
|
||||
throw new PropertyNotFoundException($name, get_class());
|
||||
}
|
||||
|
||||
return $data[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets view data.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getViewData()
|
||||
{
|
||||
$this->validator->setRemote($this->remote);
|
||||
$data = $this->validator->validationData();
|
||||
$data['selector'] = $this->selector;
|
||||
|
||||
if (! is_null($this->ignore)) {
|
||||
$data['ignore'] = $this->ignore;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the form selector to validate.
|
||||
*
|
||||
* @param string $selector
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public function setSelector($selector)
|
||||
{
|
||||
$this->selector = $selector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the form selector to validate.
|
||||
*
|
||||
* @param string $selector
|
||||
* @return \Proengsoft\JsValidation\Javascript\JavascriptValidator
|
||||
*/
|
||||
public function selector($selector)
|
||||
{
|
||||
$this->selector = is_null($selector) ? $this->selector : $selector;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the input selector to ignore for validation.
|
||||
*
|
||||
* @param string $ignore
|
||||
* @return \Proengsoft\JsValidation\Javascript\JavascriptValidator
|
||||
*/
|
||||
public function ignore($ignore)
|
||||
{
|
||||
$this->ignore = $ignore;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the view to render Javascript Validations.
|
||||
*
|
||||
* @param null|\Illuminate\Contracts\View\View|string $view
|
||||
* @return \Proengsoft\JsValidation\Javascript\JavascriptValidator
|
||||
*/
|
||||
public function view($view)
|
||||
{
|
||||
$this->view = is_null($view) ? $this->view : $view;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables remote validations.
|
||||
*
|
||||
* @param null|bool $enabled
|
||||
* @return \Proengsoft\JsValidation\Javascript\JavascriptValidator
|
||||
*/
|
||||
public function remote($enabled = true)
|
||||
{
|
||||
$this->remote = $enabled;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate Conditional Validations using Ajax in specified fields.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param string|array $rules
|
||||
* @param null $callback Dummy attribute to make API seamless with Laravel sometimes()
|
||||
* @return \Proengsoft\JsValidation\Javascript\JavascriptValidator
|
||||
*/
|
||||
public function sometimes($attribute, $rules, $callback = null)
|
||||
{
|
||||
$this->validator->sometimes($attribute, $rules);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
namespace Proengsoft\JsValidation\Javascript;
|
||||
|
||||
use Proengsoft\JsValidation\JsValidatorFactory;
|
||||
use Proengsoft\JsValidation\Support\DelegatedValidator;
|
||||
use Proengsoft\JsValidation\Support\UseDelegatedValidatorTrait;
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
|
||||
class MessageParser
|
||||
{
|
||||
use UseDelegatedValidatorTrait;
|
||||
|
||||
/**
|
||||
* Whether to escape messages using htmlentities.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $escape;
|
||||
|
||||
/**
|
||||
* Create a new JsValidation instance.
|
||||
*
|
||||
* @param \Proengsoft\JsValidation\Support\DelegatedValidator $validator
|
||||
* @param bool $escape
|
||||
*/
|
||||
public function __construct(DelegatedValidator $validator, $escape = false)
|
||||
{
|
||||
$this->validator = $validator;
|
||||
$this->escape = $escape;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace javascript error message place-holders with actual values.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param string $rule
|
||||
* @param array $parameters
|
||||
* @return mixed
|
||||
*/
|
||||
public function getMessage($attribute, $rule, $parameters)
|
||||
{
|
||||
$attribute = str_replace(JsValidatorFactory::ASTERISK, '*', $attribute);
|
||||
|
||||
$data = $this->fakeValidationData($attribute, $rule, $parameters);
|
||||
|
||||
$message = $this->validator->getMessage($attribute, $rule);
|
||||
$message = $this->validator->makeReplacements($message, $attribute, $rule, $parameters);
|
||||
|
||||
$this->validator->setData($data);
|
||||
|
||||
return $this->escape ? e($message) : $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates fake data needed to parse messages
|
||||
* Returns original data.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param string $rule
|
||||
* @param $parameters
|
||||
* @return array
|
||||
*/
|
||||
protected function fakeValidationData($attribute, $rule, $parameters)
|
||||
{
|
||||
$data = $this->validator->getData();
|
||||
|
||||
$this->fakeFileData($data, $attribute);
|
||||
$this->fakeRequiredIfData($data, $rule, $parameters);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate fake data to get RequiredIf message.
|
||||
*
|
||||
* @param $data
|
||||
* @param $rule
|
||||
* @param $parameters
|
||||
* @return void
|
||||
*/
|
||||
private function fakeRequiredIfData($data, $rule, $parameters)
|
||||
{
|
||||
if ($rule !== 'RequiredIf') {
|
||||
return;
|
||||
}
|
||||
|
||||
$newData = $data;
|
||||
$newData[$parameters[0]] = $parameters[1];
|
||||
$this->validator->setData($newData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate fake data to get file type messages.
|
||||
*
|
||||
* @param $data
|
||||
* @param $attribute
|
||||
* @return void
|
||||
*/
|
||||
private function fakeFileData($data, $attribute)
|
||||
{
|
||||
if (! $this->validator->hasRule($attribute, ['Mimes', 'Image'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$newFiles = $data;
|
||||
$newFiles[$attribute] = $this->createUploadedFile();
|
||||
$this->validator->setData($newFiles);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create fake UploadedFile to generate file messages.
|
||||
*
|
||||
* @return UploadedFile
|
||||
*/
|
||||
protected function createUploadedFile()
|
||||
{
|
||||
return new UploadedFile('fakefile', 'fakefile', null, UPLOAD_ERR_NO_FILE, true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
<?php
|
||||
|
||||
namespace Proengsoft\JsValidation\Javascript;
|
||||
|
||||
use Proengsoft\JsValidation\JsValidatorFactory;
|
||||
use Proengsoft\JsValidation\Support\DelegatedValidator;
|
||||
use Proengsoft\JsValidation\Support\RuleListTrait;
|
||||
use Proengsoft\JsValidation\Support\UseDelegatedValidatorTrait;
|
||||
|
||||
class RuleParser
|
||||
{
|
||||
use JavascriptRulesTrait;
|
||||
use RuleListTrait;
|
||||
use UseDelegatedValidatorTrait;
|
||||
|
||||
/**
|
||||
* Dummy Laravel validation rule for form requests.
|
||||
*/
|
||||
const FORM_REQUEST_RULE_NAME = 'ProengsoftFormRequest';
|
||||
|
||||
/**
|
||||
* Js validation rule used to validate form requests.
|
||||
*/
|
||||
const FORM_REQUEST_RULE = 'laravelValidationFormRequest';
|
||||
|
||||
/**
|
||||
* Rule used to validate remote requests.
|
||||
*/
|
||||
const REMOTE_RULE = 'laravelValidationRemote';
|
||||
|
||||
/**
|
||||
* Rule used to validate javascript fields.
|
||||
*/
|
||||
const JAVASCRIPT_RULE = 'laravelValidation';
|
||||
|
||||
/**
|
||||
* Token used to secure romte validations.
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $remoteToken;
|
||||
|
||||
/**
|
||||
* Conditional Validations.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $conditional = [];
|
||||
|
||||
/**
|
||||
* Create a new JsValidation instance.
|
||||
*
|
||||
* @param \Proengsoft\JsValidation\Support\DelegatedValidator $validator
|
||||
* @param null|string $remoteToken
|
||||
*/
|
||||
public function __construct(DelegatedValidator $validator, $remoteToken = null)
|
||||
{
|
||||
$this->validator = $validator;
|
||||
$this->remoteToken = $remoteToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return parsed Javascript Rule.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param string $rule
|
||||
* @param $parameters
|
||||
* @param $rawRule
|
||||
* @return array
|
||||
*/
|
||||
public function getRule($attribute, $rule, $parameters, $rawRule)
|
||||
{
|
||||
$isConditional = $this->isConditionalRule($attribute, $rawRule);
|
||||
$isRemote = $this->isRemoteRule($rule);
|
||||
$isFormRequest = $this->isFormRequestRule($rule);
|
||||
|
||||
if ($isFormRequest || $isConditional || $isRemote) {
|
||||
[$attribute, $parameters] = $this->remoteRule($attribute, $isConditional);
|
||||
$jsRule = $isFormRequest ? static::FORM_REQUEST_RULE : static::REMOTE_RULE;
|
||||
} else {
|
||||
[$jsRule, $attribute, $parameters] = $this->clientRule($attribute, $rule, $parameters);
|
||||
}
|
||||
|
||||
$attribute = $this->getAttributeName($attribute);
|
||||
|
||||
return [$attribute, $jsRule, $parameters];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets rules from Validator instance.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getValidatorRules()
|
||||
{
|
||||
return $this->validator->getRules();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add conditional rules.
|
||||
*
|
||||
* @param mixed $attribute
|
||||
* @param array $rules
|
||||
* @return void
|
||||
*/
|
||||
public function addConditionalRules($attribute, $rules = [])
|
||||
{
|
||||
foreach ((array) $attribute as $key) {
|
||||
$current = isset($this->conditional[$key]) ? $this->conditional[$key] : [];
|
||||
$merge = head($this->validator->explodeRules((array) $rules));
|
||||
$this->conditional[$key] = array_merge($current, $merge);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if rule is passed with sometimes.
|
||||
*
|
||||
* @param mixed $attribute
|
||||
* @param string $rule
|
||||
* @return bool
|
||||
*/
|
||||
protected function isConditionalRule($attribute, $rule)
|
||||
{
|
||||
return isset($this->conditional[$attribute])
|
||||
&& in_array($rule, $this->conditional[$attribute]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Javascript parameters for remote validated rules.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param string $rule
|
||||
* @param $parameters
|
||||
* @return array
|
||||
*/
|
||||
protected function clientRule($attribute, $rule, $parameters)
|
||||
{
|
||||
$jsRule = self::JAVASCRIPT_RULE;
|
||||
$method = "rule{$rule}";
|
||||
|
||||
if (method_exists($this, $method)) {
|
||||
[$attribute, $parameters] = $this->$method($attribute, $parameters);
|
||||
}
|
||||
|
||||
return [$jsRule, $attribute, $parameters];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Javascript parameters for remote validated rules.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param bool $forceRemote
|
||||
* @return array
|
||||
*/
|
||||
protected function remoteRule($attribute, $forceRemote)
|
||||
{
|
||||
$attrHtmlName = $this->getAttributeName($attribute);
|
||||
$params = [
|
||||
$attrHtmlName,
|
||||
$this->remoteToken,
|
||||
$forceRemote,
|
||||
];
|
||||
|
||||
return [$attribute, $params];
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles multidimensional attribute names.
|
||||
*
|
||||
* @param mixed $attribute
|
||||
* @return string
|
||||
*/
|
||||
protected function getAttributeName($attribute)
|
||||
{
|
||||
$attribute = str_replace(JsValidatorFactory::ASTERISK, '*', $attribute);
|
||||
|
||||
$attributeArray = explode('.', $attribute);
|
||||
if (count($attributeArray) > 1) {
|
||||
return $attributeArray[0].'['.implode('][', array_slice($attributeArray, 1)).']';
|
||||
}
|
||||
|
||||
return $attribute;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse named parameters to $key => $value items.
|
||||
*
|
||||
* @param array $parameters
|
||||
* @return array
|
||||
*/
|
||||
public function parseNamedParameters($parameters)
|
||||
{
|
||||
return array_reduce($parameters, function ($result, $item) {
|
||||
[$key, $value] = array_pad(explode('=', $item, 2), 2, null);
|
||||
|
||||
$result[$key] = $value;
|
||||
|
||||
return $result;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
|
||||
namespace Proengsoft\JsValidation\Javascript;
|
||||
|
||||
use Proengsoft\JsValidation\Support\DelegatedValidator;
|
||||
use Proengsoft\JsValidation\Support\UseDelegatedValidatorTrait;
|
||||
|
||||
class ValidatorHandler
|
||||
{
|
||||
use UseDelegatedValidatorTrait;
|
||||
|
||||
/**
|
||||
* Rule used to disable validations.
|
||||
*
|
||||
* @const string
|
||||
*/
|
||||
const JSVALIDATION_DISABLE = 'NoJsValidation';
|
||||
|
||||
/**
|
||||
* @var RuleParser
|
||||
*/
|
||||
protected $rules;
|
||||
/**
|
||||
* @var MessageParser
|
||||
*/
|
||||
protected $messages;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $remote = true;
|
||||
|
||||
/**
|
||||
* Create a new JsValidation instance.
|
||||
*
|
||||
* @param RuleParser $rules
|
||||
* @param MessageParser $messages
|
||||
*/
|
||||
public function __construct(RuleParser $rules, MessageParser $messages)
|
||||
{
|
||||
$this->rules = $rules;
|
||||
$this->messages = $messages;
|
||||
$this->validator = $rules->getDelegatedValidator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets delegated Validator instance.
|
||||
*
|
||||
* @param \Proengsoft\JsValidation\Support\DelegatedValidator $validator
|
||||
* @return void
|
||||
*/
|
||||
public function setDelegatedValidator(DelegatedValidator $validator)
|
||||
{
|
||||
$this->validator = $validator;
|
||||
$this->rules->setDelegatedValidator($validator);
|
||||
$this->messages->setDelegatedValidator($validator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable or disables remote validations.
|
||||
*
|
||||
* @param bool $enabled
|
||||
* @return void
|
||||
*/
|
||||
public function setRemote($enabled)
|
||||
{
|
||||
$this->remote = $enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate Javascript Validations.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function generateJavascriptValidations()
|
||||
{
|
||||
$jsValidations = [];
|
||||
|
||||
foreach ($this->validator->getRules() as $attribute => $rules) {
|
||||
if (! $this->jsValidationEnabled($attribute)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$newRules = $this->jsConvertRules($attribute, $rules, $this->remote);
|
||||
$jsValidations = array_merge($jsValidations, $newRules);
|
||||
}
|
||||
|
||||
return $jsValidations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make Laravel Validations compatible with JQuery Validation Plugin.
|
||||
*
|
||||
* @param $attribute
|
||||
* @param $rules
|
||||
* @param bool $includeRemote
|
||||
* @return array
|
||||
*/
|
||||
protected function jsConvertRules($attribute, $rules, $includeRemote)
|
||||
{
|
||||
$jsRules = [];
|
||||
foreach ($rules as $rawRule) {
|
||||
[$rule, $parameters] = $this->validator->parseRule($rawRule);
|
||||
[$jsAttribute, $jsRule, $jsParams] = $this->rules->getRule($attribute, $rule, $parameters, $rawRule);
|
||||
if ($this->isValidatable($jsRule, $includeRemote)) {
|
||||
$jsRules[$jsAttribute][$jsRule][] = [
|
||||
$rule,
|
||||
$jsParams,
|
||||
$this->messages->getMessage($attribute, $rule, $parameters),
|
||||
$this->validator->isImplicit($rule),
|
||||
$jsAttribute,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $jsRules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if rule should be validated with javascript.
|
||||
*
|
||||
* @param $jsRule
|
||||
* @param bool $includeRemote
|
||||
* @return bool
|
||||
*/
|
||||
protected function isValidatable($jsRule, $includeRemote)
|
||||
{
|
||||
return $jsRule && ($includeRemote || $jsRule !== RuleParser::REMOTE_RULE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if JS Validation is disabled for attribute.
|
||||
*
|
||||
* @param $attribute
|
||||
* @return bool
|
||||
*/
|
||||
public function jsValidationEnabled($attribute)
|
||||
{
|
||||
return ! $this->validator->hasRule($attribute, self::JSVALIDATION_DISABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns view data to render javascript.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function validationData()
|
||||
{
|
||||
$jsMessages = [];
|
||||
$jsValidations = $this->generateJavascriptValidations();
|
||||
|
||||
return [
|
||||
'rules' => $jsValidations,
|
||||
'messages' => $jsMessages,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate Conditional Validations using Ajax in specified fields.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param string|array $rules
|
||||
* @return void
|
||||
*/
|
||||
public function sometimes($attribute, $rules = [])
|
||||
{
|
||||
$callback = function () {
|
||||
return true;
|
||||
};
|
||||
$this->validator->sometimes($attribute, $rules, $callback);
|
||||
$this->rules->addConditionalRules($attribute, (array) $rules);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
namespace Proengsoft\JsValidation;
|
||||
|
||||
use Illuminate\Contracts\Http\Kernel;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Proengsoft\JsValidation\Javascript\ValidatorHandler;
|
||||
|
||||
class JsValidationServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Bootstrap the application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$this->bootstrapConfigs();
|
||||
$this->bootstrapViews();
|
||||
$this->bootstrapValidator();
|
||||
$this->publishAssets();
|
||||
|
||||
if ($this->app['config']->get('jsvalidation.disable_remote_validation') === false) {
|
||||
$this->app[Kernel::class]->pushMiddleware(RemoteValidationMiddleware::class);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
$this->app->singleton('jsvalidator', function ($app) {
|
||||
$config = $app['config']->get('jsvalidation');
|
||||
|
||||
return new JsValidatorFactory($app, $config);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure and publish views.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function bootstrapViews()
|
||||
{
|
||||
$viewPath = realpath(__DIR__.'/../resources/views');
|
||||
|
||||
$this->loadViewsFrom($viewPath, 'jsvalidation');
|
||||
$this->publishes([
|
||||
$viewPath => $this->app['path.base'].'/resources/views/vendor/jsvalidation',
|
||||
], 'views');
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure Laravel Validator.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function bootstrapValidator()
|
||||
{
|
||||
$callback = function () {
|
||||
return true;
|
||||
};
|
||||
$this->app['validator']->extend(ValidatorHandler::JSVALIDATION_DISABLE, $callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load and publishes configs.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function bootstrapConfigs()
|
||||
{
|
||||
$configFile = realpath(__DIR__.'/../config/jsvalidation.php');
|
||||
|
||||
$this->mergeConfigFrom($configFile, 'jsvalidation');
|
||||
$this->publishes([$configFile => $this->app['path.config'].'/jsvalidation.php'], 'config');
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish public assets.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function publishAssets()
|
||||
{
|
||||
$this->publishes([
|
||||
realpath(__DIR__.'/../public') => $this->app['path.public'].'/vendor/jsvalidation',
|
||||
], 'public');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,288 @@
|
||||
<?php
|
||||
|
||||
namespace Proengsoft\JsValidation;
|
||||
|
||||
use Illuminate\Contracts\Validation\Factory as ValidationFactory;
|
||||
use Illuminate\Foundation\Http\FormRequest as IlluminateFormRequest;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Validation\Validator;
|
||||
use Proengsoft\JsValidation\Javascript\JavascriptValidator;
|
||||
use Proengsoft\JsValidation\Javascript\MessageParser;
|
||||
use Proengsoft\JsValidation\Javascript\RuleParser;
|
||||
use Proengsoft\JsValidation\Javascript\ValidatorHandler;
|
||||
use Proengsoft\JsValidation\Remote\FormRequest;
|
||||
use Proengsoft\JsValidation\Support\DelegatedValidator;
|
||||
use Proengsoft\JsValidation\Support\ValidationRuleParserProxy;
|
||||
|
||||
class JsValidatorFactory
|
||||
{
|
||||
const ASTERISK = '__asterisk__';
|
||||
|
||||
/**
|
||||
* The application instance.
|
||||
*
|
||||
* @var \Illuminate\Container\Container
|
||||
*/
|
||||
protected $app;
|
||||
|
||||
/**
|
||||
* Configuration options.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $options;
|
||||
|
||||
/**
|
||||
* Create a new Validator factory instance.
|
||||
*
|
||||
* @param \Illuminate\Container\Container $app
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct($app, array $options = [])
|
||||
{
|
||||
$this->app = $app;
|
||||
$this->setOptions($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $options
|
||||
* @return void
|
||||
*/
|
||||
protected function setOptions($options)
|
||||
{
|
||||
$options['disable_remote_validation'] = empty($options['disable_remote_validation']) ? false : $options['disable_remote_validation'];
|
||||
$options['view'] = empty($options['view']) ? 'jsvalidation:bootstrap' : $options['view'];
|
||||
$options['form_selector'] = empty($options['form_selector']) ? 'form' : $options['form_selector'];
|
||||
|
||||
$this->options = $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates JsValidator instance based on rules and message arrays.
|
||||
*
|
||||
* @param array $rules
|
||||
* @param array $messages
|
||||
* @param array $customAttributes
|
||||
* @param null|string $selector
|
||||
* @return \Proengsoft\JsValidation\Javascript\JavascriptValidator
|
||||
*/
|
||||
public function make(array $rules, array $messages = [], array $customAttributes = [], $selector = null)
|
||||
{
|
||||
$validator = $this->getValidatorInstance($rules, $messages, $customAttributes);
|
||||
|
||||
return $this->validator($validator, $selector);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validator instance for the request.
|
||||
*
|
||||
* @param array $rules
|
||||
* @param array $messages
|
||||
* @param array $customAttributes
|
||||
* @return \Illuminate\Validation\Validator
|
||||
*/
|
||||
protected function getValidatorInstance(array $rules, array $messages = [], array $customAttributes = [])
|
||||
{
|
||||
$factory = $this->app->make(ValidationFactory::class);
|
||||
|
||||
$data = $this->getValidationData($rules, $customAttributes);
|
||||
$validator = $factory->make($data, $rules, $messages, $customAttributes);
|
||||
$validator->addCustomAttributes($customAttributes);
|
||||
|
||||
return $validator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets fake data when validator has wildcard rules.
|
||||
*
|
||||
* @param array $rules
|
||||
* @param array $customAttributes
|
||||
* @return array
|
||||
*/
|
||||
protected function getValidationData(array $rules, array $customAttributes = [])
|
||||
{
|
||||
$attributes = array_filter(array_keys($rules), function ($attribute) {
|
||||
return $attribute !== '' && mb_strpos($attribute, '*') !== false;
|
||||
});
|
||||
|
||||
$attributes = array_merge(array_keys($customAttributes), $attributes);
|
||||
$data = array_reduce($attributes, function ($data, $attribute) {
|
||||
// Prevent wildcard rule being removed as an implicit attribute (not present in the data).
|
||||
$attribute = str_replace('*', self::ASTERISK, $attribute);
|
||||
|
||||
Arr::set($data, $attribute, true);
|
||||
|
||||
return $data;
|
||||
}, []);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates JsValidator instance based on FormRequest.
|
||||
*
|
||||
* @param $formRequest
|
||||
* @param null|string $selector
|
||||
* @return \Proengsoft\JsValidation\Javascript\JavascriptValidator
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function formRequest($formRequest, $selector = null)
|
||||
{
|
||||
if (! is_object($formRequest)) {
|
||||
$formRequest = $this->createFormRequest($formRequest);
|
||||
}
|
||||
|
||||
if ($formRequest instanceof FormRequest) {
|
||||
return $this->newFormRequestValidator($formRequest, $selector);
|
||||
}
|
||||
|
||||
return $this->oldFormRequestValidator($formRequest, $selector);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create form request validator.
|
||||
*
|
||||
* @param FormRequest $formRequest
|
||||
* @param string $selector
|
||||
* @return JavascriptValidator
|
||||
*/
|
||||
private function newFormRequestValidator($formRequest, $selector)
|
||||
{
|
||||
// Replace all rules with Noop rules which are checked client-side and always valid to true.
|
||||
// This is important because jquery-validation expects fields under validation to have rules present. For
|
||||
// example, if you mark a field as invalid without a defined rule, then unhighlight won't be called.
|
||||
$rules = method_exists($formRequest, 'rules') ? $formRequest->rules() : [];
|
||||
foreach ($rules as $key => $value) {
|
||||
$rules[$key] = 'proengsoft_noop';
|
||||
}
|
||||
|
||||
// This rule controls AJAX validation of all fields.
|
||||
$rules['proengsoft_jsvalidation'] = RuleParser::FORM_REQUEST_RULE_NAME;
|
||||
|
||||
$baseValidator = $this->getValidatorInstance($rules);
|
||||
|
||||
return $this->validator($baseValidator, $selector);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a form request validator instance.
|
||||
*
|
||||
* @param IlluminateFormRequest $formRequest
|
||||
* @param string $selector
|
||||
* @return JavascriptValidator
|
||||
*/
|
||||
private function oldFormRequestValidator($formRequest, $selector)
|
||||
{
|
||||
$rules = method_exists($formRequest, 'rules') ? $this->app->call([$formRequest, 'rules']) : [];
|
||||
|
||||
$validator = $this->getValidatorInstance($rules, $formRequest->messages(), $formRequest->attributes());
|
||||
|
||||
$jsValidator = $this->validator($validator, $selector);
|
||||
|
||||
if (method_exists($formRequest, 'withJsValidator')) {
|
||||
$formRequest->withJsValidator($jsValidator);
|
||||
}
|
||||
|
||||
return $jsValidator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|array $class
|
||||
* @return array
|
||||
*/
|
||||
protected function parseFormRequestName($class)
|
||||
{
|
||||
$params = [];
|
||||
if (is_array($class)) {
|
||||
$params = empty($class[1]) ? $params : $class[1];
|
||||
$class = $class[0];
|
||||
}
|
||||
|
||||
return [$class, $params];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and initializes an Form Request instance.
|
||||
*
|
||||
* @param string $class
|
||||
* @return IlluminateFormRequest
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
protected function createFormRequest($class)
|
||||
{
|
||||
/*
|
||||
* @var $formRequest \Illuminate\Foundation\Http\FormRequest
|
||||
* @var $request Request
|
||||
*/
|
||||
[$class, $params] = $this->parseFormRequestName($class);
|
||||
|
||||
$request = $this->app->__get('request');
|
||||
$formRequest = $this->app->build($class, $params);
|
||||
|
||||
if ($request->hasSession() && $session = $request->session()) {
|
||||
$formRequest->setLaravelSession($session);
|
||||
}
|
||||
$formRequest->setUserResolver($request->getUserResolver());
|
||||
$formRequest->setRouteResolver($request->getRouteResolver());
|
||||
$formRequest->setContainer($this->app);
|
||||
$formRequest->query = $request->query;
|
||||
|
||||
return $formRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates JsValidator instance based on Validator.
|
||||
*
|
||||
* @param \Illuminate\Validation\Validator $validator
|
||||
* @param null|string $selector
|
||||
* @return \Proengsoft\JsValidation\Javascript\JavascriptValidator
|
||||
*/
|
||||
public function validator(Validator $validator, $selector = null)
|
||||
{
|
||||
return $this->jsValidator($validator, $selector);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates JsValidator instance based on Validator.
|
||||
*
|
||||
* @param \Illuminate\Validation\Validator $validator
|
||||
* @param null|string $selector
|
||||
* @return \Proengsoft\JsValidation\Javascript\JavascriptValidator
|
||||
*/
|
||||
protected function jsValidator(Validator $validator, $selector = null)
|
||||
{
|
||||
$remote = ! $this->options['disable_remote_validation'];
|
||||
$view = $this->options['view'];
|
||||
$selector = is_null($selector) ? $this->options['form_selector'] : $selector;
|
||||
$ignore = $this->options['ignore'];
|
||||
|
||||
$delegated = new DelegatedValidator($validator, new ValidationRuleParserProxy($validator->getData()));
|
||||
$rules = new RuleParser($delegated, $this->getSessionToken());
|
||||
$messages = new MessageParser($delegated, isset($this->options['escape']) ? $this->options['escape'] : false);
|
||||
|
||||
$jsValidator = new ValidatorHandler($rules, $messages);
|
||||
|
||||
return new JavascriptValidator($jsValidator, compact('view', 'selector', 'remote', 'ignore'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get and encrypt token from session store.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
protected function getSessionToken()
|
||||
{
|
||||
$token = null;
|
||||
if ($session = $this->app->__get('session')) {
|
||||
$token = $session->token();
|
||||
}
|
||||
|
||||
if ($encrypter = $this->app->__get('encrypter')) {
|
||||
$token = $encrypter->encrypt($token);
|
||||
}
|
||||
|
||||
return $token;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace Proengsoft\JsValidation\Remote;
|
||||
|
||||
use Illuminate\Contracts\Validation\Validator;
|
||||
use Illuminate\Foundation\Http\FormRequest as Request;
|
||||
use Illuminate\Http\Exceptions\HttpResponseException;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class FormRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Field to identify requests originating from this library.
|
||||
*/
|
||||
const JS_VALIDATION_FIELD = '__proengsoft_form_request';
|
||||
|
||||
/**
|
||||
* Validate the class instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function validateResolved()
|
||||
{
|
||||
parent::validateResolved();
|
||||
|
||||
// BC for Laravel versions prior to 6.x.
|
||||
$this->passedValidation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a passed validation attempt.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function passedValidation()
|
||||
{
|
||||
if ($this->isJsValidation()) {
|
||||
throw new HttpResponseException(
|
||||
new JsonResponse(true, 200)
|
||||
);
|
||||
}
|
||||
|
||||
parent::passedValidation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a failed validation attempt.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Validation\Validator $validator
|
||||
* @return void
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
*/
|
||||
protected function failedValidation(Validator $validator)
|
||||
{
|
||||
if ($this->isJsValidation()) {
|
||||
throw new ValidationException(
|
||||
$validator,
|
||||
new JsonResponse($validator->errors()->messages(), 200)
|
||||
);
|
||||
}
|
||||
|
||||
parent::failedValidation($validator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the request originated from laravel-jsvalidation.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isJsValidation()
|
||||
{
|
||||
return $this->has(static::JS_VALIDATION_FIELD);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
namespace Proengsoft\JsValidation\Remote;
|
||||
|
||||
use Illuminate\Contracts\Validation\Factory as ValidationFactory;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Validation\Validator as BaseValidator;
|
||||
use Proengsoft\JsValidation\Support\AccessProtectedTrait;
|
||||
|
||||
class Resolver
|
||||
{
|
||||
use AccessProtectedTrait;
|
||||
|
||||
/**
|
||||
* @var \Closure
|
||||
*/
|
||||
protected $resolver;
|
||||
|
||||
/**
|
||||
* @var \Illuminate\Contracts\Validation\Factory
|
||||
*/
|
||||
protected $factory;
|
||||
|
||||
/**
|
||||
* Whether to escape validation messages.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $escape;
|
||||
|
||||
/**
|
||||
* RemoteValidator constructor.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Validation\Factory $factory
|
||||
* @param bool $escape
|
||||
*/
|
||||
public function __construct(ValidationFactory $factory, $escape = false)
|
||||
{
|
||||
$this->factory = $factory;
|
||||
$this->resolver = $this->getProtected($factory, 'resolver');
|
||||
$this->escape = $escape;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closure used to resolve Validator instance.
|
||||
*
|
||||
* @param $field
|
||||
* @return \Closure
|
||||
*/
|
||||
public function resolver($field)
|
||||
{
|
||||
return function ($translator, $data, $rules, $messages, $customAttributes) use ($field) {
|
||||
return $this->resolve($translator, $data, $rules, $messages, $customAttributes, $field);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves Validator instance.
|
||||
*
|
||||
* @param $translator
|
||||
* @param $data
|
||||
* @param $rules
|
||||
* @param $messages
|
||||
* @param $customAttributes
|
||||
* @param $field
|
||||
* @return \Illuminate\Validation\Validator
|
||||
*/
|
||||
protected function resolve($translator, $data, $rules, $messages, $customAttributes, $field)
|
||||
{
|
||||
$validateAll = Arr::get($data, $field.'_validate_all', false);
|
||||
$validationRule = 'bail|'.Validator::EXTENSION_NAME.':'.$validateAll;
|
||||
$rules = [$field => $validationRule] + $rules;
|
||||
$validator = $this->createValidator($translator, $data, $rules, $messages, $customAttributes);
|
||||
|
||||
return $validator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new validator instance.
|
||||
*
|
||||
* @param $translator
|
||||
* @param $data
|
||||
* @param $rules
|
||||
* @param $messages
|
||||
* @param $customAttributes
|
||||
* @return \Illuminate\Validation\Validator
|
||||
*/
|
||||
protected function createValidator($translator, $data, $rules, $messages, $customAttributes)
|
||||
{
|
||||
if (is_null($this->resolver)) {
|
||||
return new BaseValidator($translator, $data, $rules, $messages, $customAttributes);
|
||||
}
|
||||
|
||||
return call_user_func($this->resolver, $translator, $data, $rules, $messages, $customAttributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closure used to trigger JsValidations.
|
||||
*
|
||||
* @return \Closure
|
||||
*/
|
||||
public function validatorClosure()
|
||||
{
|
||||
return function ($attribute, $value, $parameters, BaseValidator $validator) {
|
||||
$remoteValidator = new Validator($validator, $this->escape);
|
||||
$remoteValidator->validate($value, $parameters);
|
||||
|
||||
return $attribute;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
<?php
|
||||
|
||||
namespace Proengsoft\JsValidation\Remote;
|
||||
|
||||
use Illuminate\Http\Exceptions\HttpResponseException;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Illuminate\Validation\ValidationRuleParser;
|
||||
use Illuminate\Validation\Validator as BaseValidator;
|
||||
use Proengsoft\JsValidation\Support\AccessProtectedTrait;
|
||||
use Proengsoft\JsValidation\Support\RuleListTrait;
|
||||
|
||||
class Validator
|
||||
{
|
||||
use AccessProtectedTrait;
|
||||
use RuleListTrait;
|
||||
|
||||
/**
|
||||
* Validator extension name.
|
||||
*/
|
||||
const EXTENSION_NAME = 'jsvalidation';
|
||||
|
||||
/**
|
||||
* @var \Illuminate\Validation\Validator
|
||||
*/
|
||||
protected $validator;
|
||||
|
||||
/**
|
||||
* Whether to escape validation messages.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $escape;
|
||||
|
||||
/**
|
||||
* RemoteValidator constructor.
|
||||
*
|
||||
* @param \Illuminate\Validation\Validator $validator
|
||||
* @param bool $escape
|
||||
*/
|
||||
public function __construct(BaseValidator $validator, $escape = false)
|
||||
{
|
||||
$this->validator = $validator;
|
||||
$this->escape = $escape;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate request.
|
||||
*
|
||||
* @param $field
|
||||
* @param $parameters
|
||||
* @return void
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
*/
|
||||
public function validate($field, $parameters = [])
|
||||
{
|
||||
$attribute = $this->parseAttributeName($field);
|
||||
$validationParams = $this->parseParameters($parameters);
|
||||
$validationResult = $this->validateJsRemoteRequest($attribute, $validationParams);
|
||||
|
||||
$this->throwValidationException($validationResult, $this->validator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throw the failed validation exception.
|
||||
*
|
||||
* @param mixed $result
|
||||
* @param \Illuminate\Validation\Validator $validator
|
||||
* @return void
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException|\Illuminate\Http\Exceptions\HttpResponseException
|
||||
*/
|
||||
protected function throwValidationException($result, $validator)
|
||||
{
|
||||
$response = new JsonResponse($result, 200);
|
||||
|
||||
if ($result !== true && class_exists(ValidationException::class)) {
|
||||
throw new ValidationException($validator, $response);
|
||||
}
|
||||
|
||||
throw new HttpResponseException($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse Validation input request data.
|
||||
*
|
||||
* @param $data
|
||||
* @return array
|
||||
*/
|
||||
protected function parseAttributeName($data)
|
||||
{
|
||||
parse_str($data, $attrParts);
|
||||
$attrParts = is_null($attrParts) ? [] : $attrParts;
|
||||
$newAttr = array_keys(Arr::dot($attrParts));
|
||||
|
||||
return array_pop($newAttr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse Validation parameters.
|
||||
*
|
||||
* @param $parameters
|
||||
* @return array
|
||||
*/
|
||||
protected function parseParameters($parameters)
|
||||
{
|
||||
$newParams = ['validate_all' => false];
|
||||
if (isset($parameters[0])) {
|
||||
$newParams['validate_all'] = ($parameters[0] === 'true') ? true : false;
|
||||
}
|
||||
|
||||
return $newParams;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate remote Javascript Validations.
|
||||
*
|
||||
* @param $attribute
|
||||
* @param array $parameters
|
||||
* @return array|bool
|
||||
*/
|
||||
protected function validateJsRemoteRequest($attribute, $parameters)
|
||||
{
|
||||
$this->setRemoteValidation($attribute, $parameters['validate_all']);
|
||||
|
||||
$validator = $this->validator;
|
||||
if ($validator->passes()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$messages = $validator->messages()->get($attribute);
|
||||
|
||||
if ($this->escape) {
|
||||
foreach ($messages as $key => $value) {
|
||||
$messages[$key] = e($value);
|
||||
}
|
||||
}
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets data for validate remote rules.
|
||||
*
|
||||
* @param $attribute
|
||||
* @param bool $validateAll
|
||||
* @return void
|
||||
*/
|
||||
protected function setRemoteValidation($attribute, $validateAll = false)
|
||||
{
|
||||
$validator = $this->validator;
|
||||
$rules = $validator->getRules();
|
||||
$rules = isset($rules[$attribute]) ? $rules[$attribute] : [];
|
||||
if (in_array('no_js_validation', $rules)) {
|
||||
$validator->setRules([$attribute => []]);
|
||||
|
||||
return;
|
||||
}
|
||||
if (! $validateAll) {
|
||||
$rules = $this->purgeNonRemoteRules($rules, $validator);
|
||||
}
|
||||
$validator->setRules([$attribute => $rules]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove rules that should not be validated remotely.
|
||||
*
|
||||
* @param $rules
|
||||
* @param BaseValidator $validator
|
||||
* @return mixed
|
||||
*/
|
||||
protected function purgeNonRemoteRules($rules, $validator)
|
||||
{
|
||||
$protectedValidator = $this->createProtectedCaller($validator);
|
||||
|
||||
foreach ($rules as $i => $rule) {
|
||||
$parsedRule = ValidationRuleParser::parse($rule);
|
||||
if (! $this->isRemoteRule($parsedRule[0])) {
|
||||
unset($rules[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
return $rules;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace Proengsoft\JsValidation;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Config\Repository as Config;
|
||||
use Illuminate\Contracts\Validation\Factory as ValidationFactory;
|
||||
use Illuminate\Http\Request;
|
||||
use Proengsoft\JsValidation\Remote\Resolver;
|
||||
use Proengsoft\JsValidation\Remote\Validator as RemoteValidator;
|
||||
|
||||
class RemoteValidationMiddleware
|
||||
{
|
||||
/**
|
||||
* Validator factory instance to wrap.
|
||||
*
|
||||
* @var \Illuminate\Contracts\Validation\Factory
|
||||
*/
|
||||
protected $factory;
|
||||
|
||||
/**
|
||||
* Field used to detect Javascript validation.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $field;
|
||||
|
||||
/**
|
||||
* Whether to escape messages or not.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $escape;
|
||||
|
||||
/**
|
||||
* RemoteValidationMiddleware constructor.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Validation\Factory $validator
|
||||
* @param \Illuminate\Contracts\Config\Repository $config
|
||||
*/
|
||||
public function __construct(ValidationFactory $validator, Config $config)
|
||||
{
|
||||
$this->factory = $validator;
|
||||
$this->field = $config->get('jsvalidation.remote_validation_field');
|
||||
$this->escape = (bool) $config->get('jsvalidation.escape', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
if ($request->has($this->field)) {
|
||||
$this->wrapValidator();
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps Validator resolver with RemoteValidator resolver.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function wrapValidator()
|
||||
{
|
||||
$resolver = new Resolver($this->factory, $this->escape);
|
||||
$this->factory->resolver($resolver->resolver($this->field));
|
||||
$this->factory->extend(RemoteValidator::EXTENSION_NAME, $resolver->validatorClosure());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace Proengsoft\JsValidation\Support;
|
||||
|
||||
use Closure;
|
||||
|
||||
trait AccessProtectedTrait
|
||||
{
|
||||
/**
|
||||
* Create closure to call inaccessible method.
|
||||
*
|
||||
* @param $instance
|
||||
* @return \Closure
|
||||
*/
|
||||
protected function createProtectedCaller($instance)
|
||||
{
|
||||
$closure = function ($method, $args) {
|
||||
$callable = [$this, $method];
|
||||
|
||||
return call_user_func_array($callable, $args);
|
||||
};
|
||||
|
||||
return $closure->bindTo($instance, $instance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets inaccessible property.
|
||||
*
|
||||
* @param $instance
|
||||
* @param $property
|
||||
* @return \Closure
|
||||
*/
|
||||
protected function getProtected($instance, $property)
|
||||
{
|
||||
$closure = function ($property) {
|
||||
return $this->$property;
|
||||
};
|
||||
$callback = $closure->bindTo($instance, $instance);
|
||||
|
||||
return $callback($property);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls inaccessible method.
|
||||
*
|
||||
* @param object|\Closure $instance
|
||||
* @param $method
|
||||
* @param $args
|
||||
* @return mixed
|
||||
*/
|
||||
protected function callProtected($instance, $method, $args = [])
|
||||
{
|
||||
if (! ($instance instanceof Closure)) {
|
||||
$instance = $this->createProtectedCaller($instance);
|
||||
}
|
||||
|
||||
return call_user_func($instance, $method, $args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
<?php
|
||||
|
||||
namespace Proengsoft\JsValidation\Support;
|
||||
|
||||
use Illuminate\Validation\Validator as BaseValidator;
|
||||
|
||||
class DelegatedValidator
|
||||
{
|
||||
use AccessProtectedTrait;
|
||||
|
||||
/**
|
||||
* The Validator resolved instance.
|
||||
*
|
||||
* @var \Illuminate\Validation\Validator
|
||||
*/
|
||||
protected $validator;
|
||||
|
||||
/**
|
||||
* Validation rule parser instance.
|
||||
*
|
||||
* @var \Proengsoft\JsValidation\Support\ValidationRuleParserProxy
|
||||
*/
|
||||
protected $ruleParser;
|
||||
|
||||
/**
|
||||
* Closure to invoke non accessible Validator methods.
|
||||
*
|
||||
* @var \Closure
|
||||
*/
|
||||
protected $validatorMethod;
|
||||
|
||||
/**
|
||||
* DelegatedValidator constructor.
|
||||
*
|
||||
* @param \Illuminate\Validation\Validator $validator
|
||||
* @param \Proengsoft\JsValidation\Support\ValidationRuleParserProxy $ruleParser
|
||||
*/
|
||||
public function __construct(BaseValidator $validator, ValidationRuleParserProxy $ruleParser)
|
||||
{
|
||||
$this->validator = $validator;
|
||||
$this->ruleParser = $ruleParser;
|
||||
$this->validatorMethod = $this->createProtectedCaller($validator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call validator method.
|
||||
*
|
||||
* @param string $method
|
||||
* @param array $args
|
||||
* @return mixed
|
||||
*/
|
||||
private function callValidator($method, $args = [])
|
||||
{
|
||||
return $this->callProtected($this->validatorMethod, $method, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current \Illuminate\Validation\Validator instance.
|
||||
*
|
||||
* @return \Illuminate\Validation\Validator
|
||||
*/
|
||||
public function getValidator()
|
||||
{
|
||||
return $this->validator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data under validation.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getData()
|
||||
{
|
||||
return $this->validator->getData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the data under validation.
|
||||
*
|
||||
* @param array
|
||||
*/
|
||||
public function setData($data)
|
||||
{
|
||||
$rules = $this->validator->getRules();
|
||||
$this->validator->setData($data);
|
||||
if (is_array($rules)) {
|
||||
$this->validator->setRules($rules);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getRules()
|
||||
{
|
||||
return $this->validator->getRules();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a given rule implies the attribute is required.
|
||||
*
|
||||
* @param string $rule
|
||||
* @return bool
|
||||
*/
|
||||
public function isImplicit($rule)
|
||||
{
|
||||
return $this->callValidator('isImplicit', [$rule]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace all error message place-holders with actual values.
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $attribute
|
||||
* @param string $rule
|
||||
* @param array $parameters
|
||||
* @return string
|
||||
*/
|
||||
public function makeReplacements($message, $attribute, $rule, $parameters)
|
||||
{
|
||||
if (is_object($rule)) {
|
||||
$rule = get_class($rule);
|
||||
}
|
||||
|
||||
return $this->callValidator('makeReplacements', [$message, $attribute, $rule, $parameters]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given attribute has a rule in the given set.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param string|array $rules
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRule($attribute, $rules)
|
||||
{
|
||||
return $this->callValidator('hasRule', [$attribute, $rules]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation message for an attribute and rule.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param string $rule
|
||||
* @return string
|
||||
*/
|
||||
public function getMessage($attribute, $rule)
|
||||
{
|
||||
if (is_object($rule)) {
|
||||
$rule = get_class($rule);
|
||||
}
|
||||
|
||||
return $this->callValidator('getMessage', [$attribute, $rule]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the rule name and parameters from a rule.
|
||||
*
|
||||
* @param array|string $rules
|
||||
* @return array
|
||||
*/
|
||||
public function parseRule($rules)
|
||||
{
|
||||
return $this->ruleParser->parse($rules);
|
||||
}
|
||||
|
||||
/**
|
||||
* Explode the rules into an array of rules.
|
||||
*
|
||||
* @param string|array $rules
|
||||
* @return array
|
||||
*/
|
||||
public function explodeRules($rules)
|
||||
{
|
||||
return $this->ruleParser->explodeRules($rules);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add conditions to a given field based on a Closure.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param string|array $rules
|
||||
* @param callable $callback
|
||||
* @return void
|
||||
*/
|
||||
public function sometimes($attribute, $rules, callable $callback)
|
||||
{
|
||||
$this->validator->sometimes($attribute, $rules, $callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegate method calls to validator instance.
|
||||
*
|
||||
* @param $method
|
||||
* @param $params
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call($method, $params)
|
||||
{
|
||||
$arrCaller = [$this->validator, $method];
|
||||
|
||||
return call_user_func_array($arrCaller, $params);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
namespace Proengsoft\JsValidation\Support;
|
||||
|
||||
use Proengsoft\JsValidation\Javascript\RuleParser;
|
||||
|
||||
trait RuleListTrait
|
||||
{
|
||||
/**
|
||||
* Rules validated with Javascript.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $clientRules = [
|
||||
'Accepted', 'After', 'AfterOrEqual', 'Alpha', 'AlphaDash',
|
||||
'AlphaNum', 'Array', 'Bail', 'Before', 'BeforeOrEqual', 'Between', 'Boolean', 'Confirmed', 'Date', 'Dimensions',
|
||||
'DateFormat', 'Different', 'Digits', 'DigitsBetween', 'Distinct', 'Email', 'File', 'Filled', 'Image',
|
||||
'In', 'InArray', 'Integer', 'Ip', 'Json', 'Max', 'Mimes', 'Mimetypes', 'Min', 'NotIn', 'Nullable',
|
||||
'Numeric', 'Regex', 'Required', 'RequiredIf', 'RequiredUnless', 'RequiredWith', 'RequiredWithAll',
|
||||
'RequiredWithout', 'RequiredWithoutAll', 'Same', 'Size', 'Sometimes',
|
||||
'String', 'Timezone', 'ProengsoftNoop',
|
||||
];
|
||||
|
||||
/**
|
||||
* Rules validated in Server-Side.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $serverRules = ['ActiveUrl', 'Exists', 'Unique', 'Url'];
|
||||
|
||||
/**
|
||||
* Rules applyed to files.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fileRules = ['File', 'Image', 'Mimes', 'Mimetypes'];
|
||||
|
||||
/**
|
||||
* Rule used to disable validations.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $disableJsValidationRule = 'NoJsValidation';
|
||||
|
||||
/**
|
||||
* Returns if rule is validated using Javascript.
|
||||
*
|
||||
* @param $rule
|
||||
* @return bool
|
||||
*/
|
||||
protected function isImplemented($rule)
|
||||
{
|
||||
return in_array($rule, $this->clientRules) || in_array($rule, $this->serverRules);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if rule must be validated in server-side.
|
||||
*
|
||||
* @param $rule
|
||||
* @return bool
|
||||
*/
|
||||
protected function isRemoteRule($rule)
|
||||
{
|
||||
return in_array($rule, $this->serverRules) ||
|
||||
! in_array($rule, $this->clientRules);
|
||||
}
|
||||
|
||||
/**
|
||||
* Form request rule.
|
||||
*
|
||||
* @param string $rule
|
||||
* @return bool
|
||||
*/
|
||||
protected function isFormRequestRule($rule)
|
||||
{
|
||||
return $rule === RuleParser::FORM_REQUEST_RULE_NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if rule disables rule processing.
|
||||
*
|
||||
* @param $rule
|
||||
* @return bool
|
||||
*/
|
||||
protected function isDisableRule($rule)
|
||||
{
|
||||
return $rule === $this->disableJsValidationRule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if rules should be validated.
|
||||
*
|
||||
* @param $rules
|
||||
* @return bool
|
||||
*/
|
||||
protected function validationDisabled($rules)
|
||||
{
|
||||
$rules = (array) $rules;
|
||||
|
||||
return in_array($this->disableJsValidationRule, $rules);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if rules is for input file type.
|
||||
*
|
||||
* @param $rule
|
||||
* @return bool
|
||||
*/
|
||||
protected function isFileRule($rule)
|
||||
{
|
||||
return in_array($rule, $this->fileRules);
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Proengsoft\JsValidation\Support;
|
||||
|
||||
trait UseDelegatedValidatorTrait
|
||||
{
|
||||
/**
|
||||
* Delegated validator.
|
||||
*
|
||||
* @var \Proengsoft\JsValidation\Support\DelegatedValidator
|
||||
*/
|
||||
protected $validator;
|
||||
|
||||
/**
|
||||
* Sets delegated Validator instance.
|
||||
*
|
||||
* @param \Proengsoft\JsValidation\Support\DelegatedValidator $validator
|
||||
* @return void
|
||||
*/
|
||||
public function setDelegatedValidator(DelegatedValidator $validator)
|
||||
{
|
||||
$this->validator = $validator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets current DelegatedValidator instance.
|
||||
*
|
||||
* @return \Proengsoft\JsValidation\Support\DelegatedValidator
|
||||
*/
|
||||
public function getDelegatedValidator()
|
||||
{
|
||||
return $this->validator;
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace Proengsoft\JsValidation\Support;
|
||||
|
||||
use Illuminate\Validation\ValidationRuleParser;
|
||||
|
||||
class ValidationRuleParserProxy
|
||||
{
|
||||
use AccessProtectedTrait;
|
||||
|
||||
/**
|
||||
* ValidationRuleParser instance.
|
||||
*
|
||||
* @var ValidationRuleParser
|
||||
*/
|
||||
protected $parser;
|
||||
|
||||
/**
|
||||
* Closure to invoke non accessible Validator methods.
|
||||
*
|
||||
* @var \Closure
|
||||
*/
|
||||
protected $parserMethod;
|
||||
|
||||
/**
|
||||
* ValidationRuleParserProxy constructor.
|
||||
*
|
||||
* @param array $data
|
||||
*/
|
||||
public function __construct($data = [])
|
||||
{
|
||||
$this->parser = new ValidationRuleParser((array) $data);
|
||||
$this->parserMethod = $this->createProtectedCaller($this->parser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the rule name and parameters from a rule.
|
||||
*
|
||||
* @param array|string $rules
|
||||
* @return array
|
||||
*/
|
||||
public function parse($rules)
|
||||
{
|
||||
return $this->parser->parse($rules);
|
||||
}
|
||||
|
||||
/**
|
||||
* Explode the rules into an array of explicit rules.
|
||||
*
|
||||
* @param array $rules
|
||||
* @return mixed
|
||||
*/
|
||||
public function explodeRules($rules)
|
||||
{
|
||||
return $this->callProtected($this->parserMethod, 'explodeRules', [$rules]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegate method calls to parser instance.
|
||||
*
|
||||
* @param string $method
|
||||
* @param mixed $params
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call($method, $params)
|
||||
{
|
||||
$arrCaller = [$this->parser, $method];
|
||||
|
||||
return call_user_func_array($arrCaller, $params);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user