vendor and env first commit

This commit is contained in:
2025-03-28 08:52:46 +01:00
parent f8388bc81b
commit 8f26283832
10976 changed files with 1349952 additions and 2 deletions
@@ -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);
}
}
@@ -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);
}
}