Skip to content

Commit

Permalink
Merge pull request #3 from apility/develop
Browse files Browse the repository at this point in the history
Merge develop into master
  • Loading branch information
thomas-alrek authored Sep 22, 2021
2 parents de79159 + 7eb89b3 commit e6fbb0a
Show file tree
Hide file tree
Showing 13 changed files with 250 additions and 193 deletions.
10 changes: 2 additions & 8 deletions src/DateRules/DateRangeRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,13 @@

class DateRangeRule extends DateRule
{

public ?Carbon $from;
public ?Carbon $to;

public function __construct(array $nodeData, array $rules)
{
parent::__construct($nodeData, $rules);

}

/**
* @inheritDoc
*/
function validate(Carbon $date): bool
public function validate(Carbon $date): bool
{
if (isset($this->from) && $date->lt($this->from)) {
return false;
Expand All @@ -28,6 +21,7 @@ function validate(Carbon $date): bool
if (isset($this->to) && $date->gte($this->to)) {
return false;
}

return true;
}
}
71 changes: 53 additions & 18 deletions src/DateRules/DateRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,60 +2,92 @@

namespace Netflex\RuleBuilder\DateRules;

use ReflectionClass;
use ReflectionException;

use Carbon\Carbon;
use Illuminate\Contracts\Validation\Rule;
use Netflex\RuleBuilder\RuleCollection;
use Netflex\RuleBuilder\ExplainerNode;
use Netflex\RuleBuilder\InvalidConfigurationException;
use Netflex\RuleBuilder\UnknownNodeType;

abstract class DateRule
{
/**
* @var DateRule[]
*/
public static array $rules = [
'group' => GroupDateRule::class,
'dayOfWeek' => DayOfWeekDateRule::class,
'dateRange' => DateRangeRule::class,
'not' => NotDateRule::class
];

/** @var string */
public string $name;
public array $children = [];

/** @var RuleCollection|null */
public ?RuleCollection $children;

/**
* @param array $nodeData
* @param DateRule[] $rules
* @throws UnknownNodeType
*/
public function __construct(array $nodeData, array $rules)
{
$r = new \ReflectionClass($this);
$reflectionClass = new ReflectionClass($this);

foreach ($nodeData as $key => $value) {
try {
$prop = $r->getProperty($key);
if ($prop->hasType() && $prop->getType()->getName() == Carbon::class) {
$value = $value ? Carbon::parse($value) : null;
} else if($prop->hasType() && $prop->getType()->getName() == DateRule::class) {
$value = $value ? DateRule::parse($value, $rules) : null;
$property = $reflectionClass->getProperty($key);

if ($property->hasType()) {
$type = $property->getType()->getName();

if (is_subclass_of($type, Carbon::class) || $type === Carbon::class) {
$value = $value ? Carbon::parse($value) : null;
}

if (is_subclass_of($type, DateRule::class) || $type === DateRule::class) {
$value = $value ? DateRule::parse($value, $rules) : null;
}

if (is_subclass_of($type, RuleCollection::class) || $type === RuleCollection::class) {
$value = ($value ? RuleCollection::make($value) : RuleCollection::make([]))->map(function ($child) use ($rules) {
if (!($child instanceof DateRule)) {
return static::parse($child, $rules);
}

return $child;
});
}
}
} catch (\ReflectionException $e) {
} catch (ReflectionException $e) {
// Unknown property, ignore it
continue;
}
$this->{$key} = $value;
}

foreach ($this->children as $key => $child) {
$this->children[$key] = static::parse($child, $rules);
$this->{$key} = $value;
}
}

/**
* @param array $node
* @param DateRule[]|null $rules
* @throws UnknownNodeType
* @return DateRule
*/
public static function parse(array $node, ?array $rules = null): self
{
$rules = $rules ?? static::$rules;

if ($rule = $rules[$node['type']]) {
if ($rule = $rules[$node['type']] ?: null) {
return new $rule($node, $rules);
} else {
throw new UnknownNodeType("DateRule of type {$node['type']} is not known");
}

throw new UnknownNodeType("DateRule of type {$node['type']} is not known");
}

/**
Expand All @@ -65,7 +97,7 @@ public static function parse(array $node, ?array $rules = null): self
* @return ExplainerNode
* @throws InvalidConfigurationException
*/
function explain(Carbon $date): ExplainerNode
public function explain(Carbon $date): ExplainerNode
{
$children = [];

Expand All @@ -84,9 +116,12 @@ function explain(Carbon $date): ExplainerNode
* @return bool
* @throws InvalidConfigurationException
*/
abstract function validate(Carbon $date): bool;
abstract public function validate(Carbon $date): bool;

function settings(): array
/**
* @return array
*/
public function settings(): array
{
return [
'name' => $this->name
Expand Down
3 changes: 2 additions & 1 deletion src/DateRules/DayOfWeekDateRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@

class DayOfWeekDateRule extends DateRule
{
/** @var int[] */
public array $days;

/**
* @inheritDoc
*/
function validate(Carbon $date): bool
public function validate(Carbon $date): bool
{
return collect($this->days)->some(function (int $day) use ($date) {
return $date->isDayOfWeek($day);
Expand Down
29 changes: 16 additions & 13 deletions src/DateRules/GroupDateRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,56 +3,59 @@
namespace Netflex\RuleBuilder\DateRules;

use Carbon\Carbon;
use Illuminate\Contracts\Validation\DataAwareRule;
use Netflex\RuleBuilder\ExplainerNode;
use Netflex\RuleBuilder\RuleCollection;
use Netflex\RuleBuilder\InvalidConfigurationException;

/**
* Validates a group of rules against the same date and returns a unified answer
*
* $count is required, can be "all", "any" or an integer that determines how many rules must pass the check for the
* $count is required, can be 'all', 'any' or an integer that determines how many rules must pass the check for the
* group value to be true
*/
class GroupDateRule extends DateRule
{

/** @var string|int */
public $count;
public array $children;

/** @var RuleCollection */
public ?RuleCollection $children;

/**
* @inheritDoc
* @throws InvalidConfigurationException
*/
function validate(Carbon $date): bool
public function validate(Carbon $date): bool
{
if($this->count == "all") {
if ($this->count === 'all') {
return collect($this->children)
->every(function(DateRule $rule) use ($date) {
->every(function (DateRule $rule) use ($date) {
return $rule->validate($date);
});
}

if($this->count == "any") {
if ($this->count === 'any') {
return collect($this->children)
->first(function(DateRule $rule) use ($date) {
->first(function (DateRule $rule) use ($date) {
return $rule->validate($date);
}) != null;
}

if(is_int($this->count)) {
if (is_int($this->count)) {
$ch = collect($this->children);
$minLevel = min($ch->count(), $this->count);

return $ch->filter(function(DateRule $rule) use ($date) {
return $ch->filter(function (DateRule $rule) use ($date) {
return $rule->validate($date);
})->count() >= $minLevel;
}

throw new InvalidConfigurationException("[count] is not a valid value on rule with name {$this->name}. Must be 'any', 'all' or int");
}

function settings(): array
/**
* @return array
*/
public function settings(): array
{
return array_merge(parent::settings(), [
'count' => $this->count
Expand Down
6 changes: 3 additions & 3 deletions src/DateRules/NotDateRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@
namespace Netflex\RuleBuilder\DateRules;

use Carbon\Carbon;
use Netflex\RuleBuilder\InvalidConfigurationException;

class NotDateRule extends DateRule
{

/** @var DateRule */
public DateRule $child;

/**
* @inheritDoc
*/
function validate(Carbon $date): bool
public function validate(Carbon $date): bool
{
return !$this->child->validate($date);
}
Expand Down
9 changes: 7 additions & 2 deletions src/ExplainerNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@

class ExplainerNode
{

/** @var bool */
public bool $result;

/** @var array */
public array $children;

/** @var array */
public array $settings;

function __construct(bool $result, array $settings = [], array $children = []) {
public function __construct(bool $result, array $settings = [], array $children = [])
{
$this->result = $result;
$this->settings = $settings;
$this->children = $children;
Expand Down
8 changes: 2 additions & 6 deletions src/InvalidConfigurationException.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,8 @@

namespace Netflex\RuleBuilder;

use Throwable;
use Exception;

class InvalidConfigurationException extends \Exception
class InvalidConfigurationException extends Exception
{
function __construct($message = "", $code = 0, Throwable $previous = null)
{
parent::__construct($message, 0, null);
}
}
9 changes: 9 additions & 0 deletions src/RuleCollection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

namespace Netflex\RuleBuilder;

use Illuminate\Support\Collection;

class RuleCollection extends Collection
{
}
8 changes: 2 additions & 6 deletions src/UnknownNodeType.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,8 @@

namespace Netflex\RuleBuilder;

use Throwable;
use Exception;

class UnknownNodeType extends \Exception
class UnknownNodeType extends Exception
{
function __construct($message = "", $code = 0, Throwable $previous = null)
{
parent::__construct($message, 0, null);
}
}
Loading

0 comments on commit e6fbb0a

Please sign in to comment.