202 lines
5.2 KiB
PHP
202 lines
5.2 KiB
PHP
<?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;
|
|
});
|
|
}
|
|
}
|