Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
JasonTheAdams committed Mar 16, 2023
2 parents fc1fa26 + 41d6fb9 commit 871c476
Show file tree
Hide file tree
Showing 31 changed files with 1,358 additions and 16 deletions.
4 changes: 2 additions & 2 deletions codeception.slic.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
params:
# read dynamic configuration parameters from the .env file
- .env.testing.slic
# read dynamic configuration parameters from the .env file
- .env.testing.slic
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
],
"require": {
"stellarwp/container-contract": "1.0.4",
"stellarwp/field-conditions": "^1.0",
"ext-json": "*"
},
"require-dev": {
Expand Down
54 changes: 52 additions & 2 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions src/Commands/ExcludeValue.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

namespace StellarWP\Validation\Commands;

/**
* Returning this value from the __invoke method of a ValidationRule will stop all validation rules and exclude the
* value from the validated dataset.
*
* @unreleased
*/
class ExcludeValue
{

}
4 changes: 3 additions & 1 deletion src/Contracts/ValidationRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace StellarWP\Validation\Contracts;

use Closure;
use StellarWP\Validation\Commands\ExcludeValue;
use StellarWP\Validation\Commands\SkipValidationRules;

interface ValidationRule
Expand All @@ -30,9 +31,10 @@ public static function fromString(string $options = null): ValidationRule;
* The invokable method used to validate the value. If the value is invalid, the fail callback should be invoked
* with the error message. Use {field} to reference the field name in the error message.
*
* @unreleased add ExcludeValue return option
* @since 1.0.0
*
* @return void|SkipValidationRules
* @return void|ExcludeValue|SkipValidationRules
*/
public function __invoke($value, Closure $fail, string $key, array $values);
}
73 changes: 73 additions & 0 deletions src/Rules/Abstracts/ConditionalRule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php

declare(strict_types=1);

namespace StellarWP\Validation\Rules\Abstracts;

use StellarWP\FieldConditions\ComplexConditionSet;
use StellarWP\FieldConditions\Contracts\Condition;
use StellarWP\FieldConditions\Contracts\ConditionSet;
use StellarWP\FieldConditions\SimpleConditionSet;
use StellarWP\Validation\Config;
use StellarWP\Validation\Contracts\ValidatesOnFrontEnd;
use StellarWP\Validation\Contracts\ValidationRule;

abstract class ConditionalRule implements ValidationRule, ValidatesOnFrontEnd
{
/**
* @var ConditionSet
*/
protected $conditions;

/**
* @param ConditionSet|Condition[] $conditions
*/
public function __construct($conditions)
{
if ($conditions instanceof ConditionSet) {
$this->conditions = $conditions;
} else {
$this->conditions = new ComplexConditionSet(...$conditions);
}
}

/**
* Supports a simple syntax for defining conditions. Example:
* - ruleId:field1,value1;field2,value2
*
* Each rule is assumed to be a basic condition with an equals operator.
*
* @unreleased
*/
public static function fromString(string $options = null): ValidationRule
{
if (empty($options)) {
Config::throwInvalidArgumentException(static::class . ' rule requires at least one condition');
}

$rules = explode(';', $options);

$conditionSet = new SimpleConditionSet();
foreach ($rules as $rule) {
$rule = explode(',', $rule);

if (count($rule) !== 2) {
Config::throwInvalidArgumentException(static::class . ' rule requires one field name and one value');
}

$conditionSet->and($rule[0], '=', $rule[1]);
}

return new static($conditionSet);
}

/**
* {@inheritdoc}
*
* @unreleased
*/
public function serializeOption()
{
return $this->conditions->jsonSerialize();
}
}
120 changes: 120 additions & 0 deletions src/Rules/DateTime.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<?php

namespace StellarWP\Validation\Rules;

use Closure;
use DateTimeImmutable;
use DateTimeInterface;
use Exception;
use StellarWP\Validation\Contracts\Sanitizer;
use StellarWP\Validation\Contracts\ValidatesOnFrontEnd;
use StellarWP\Validation\Contracts\ValidationRule;

/**
* This rule validates that the given value is a valid date.
*
* @unreleased
*/
class DateTime implements ValidationRule, ValidatesOnFrontEnd, Sanitizer
{
/**
* @var string|null
*/
protected $format;

/**
* @unreleased
*/
public static function id(): string
{
return 'dateTime';
}

/**
* @unreleased
*/
public static function fromString(string $options = null): ValidationRule
{
return new static($options);
}

/**
* @unreleased
*/
public function __construct(string $format = null)
{
$this->format = $format;
}

/**
* @unreleased
*/
public function __invoke($value, Closure $fail, string $key, array $values)
{
if ($value instanceof DateTimeInterface) {
return;
}

$failedValidation = function () use ($fail) {
$fail(sprintf(__('%s must be a valid date', '%TEXTDOMAIN%'), '{field}'));
};

try {
if (!is_string($value) && !is_numeric($value)) {
$failedValidation();

return;
}

if ($this->format !== null) {
$date = \DateTime::createFromFormat($this->format, $value);
if ($date === false || $date->format($this->format) !== $value) {
$failedValidation();

return;
}
}

if (strtotime($value) === false) {
$failedValidation();

return;
}
} catch (Exception $exception) {
$failedValidation();

return;
}

$date = date_parse($value);

if (!checkdate($date['month'], $date['day'], $date['year'])) {
$failedValidation();
}
}

/**
* @unreleased
*/
public function sanitize($value)
{
if ($value instanceof DateTimeInterface) {
return $value;
}

if ($this->format !== null) {
return DateTimeImmutable::createFromFormat($this->format, $value);
}

return new DateTimeImmutable($value);
}

/**
* @unreleased
*/
public function serializeOption()
{
return $this->format;
}

}
47 changes: 47 additions & 0 deletions src/Rules/Exclude.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

declare(strict_types=1);

namespace StellarWP\Validation\Rules;

use Closure;
use StellarWP\Validation\Commands\ExcludeValue;
use StellarWP\Validation\Contracts\ValidationRule;

/**
* Applying this rule will prevent all further validations and exclude the value from the validated dataset.
*
* @unreleased
*/
class Exclude implements ValidationRule
{
/**
* @inheritDoc
*
* @unreleased
*/
public static function id(): string
{
return 'exclude';
}

/**
* @inheritDoc
*
* @unreleased
*/
public static function fromString(string $options = null): ValidationRule
{
return new self();
}

/**
* @inheritDoc
*
* @unreleased
*/
public function __invoke($value, Closure $fail, string $key, array $values): ExcludeValue
{
return new ExcludeValue();
}
}
Loading

0 comments on commit 871c476

Please sign in to comment.