Skip to content

Instantly share code, notes, and snippets.

@gabrieljmj
Created November 19, 2019 17:39
Show Gist options
  • Save gabrieljmj/783474740b4175f872727ec1513b28dc to your computer and use it in GitHub Desktop.
Save gabrieljmj/783474740b4175f872727ec1513b28dc to your computer and use it in GitHub Desktop.
LaravelRuleSets
<?php
namespace App\Rules\RuleSets;
use InvalidArgumentException;
abstract class AbstractRuleSet implements RuleSet
{
/**
* Rules set to combines with.
* The order of the combination will be:
* add the combination rules than this object rules.
*
* @var array
*/
protected $combineWith = [];
/**
* Override rules of combinations with rules of this set.
*
* @var bool
*/
protected $overrideRules = false;
/**
* Returns all the rules combined with the rule sets indicated
*
* @return array
*/
public function getRules(): array
{
$rules = [];
$thisRules = $this->rules();
foreach ($this->combineWith as $ruleSet) {
array_merge($rules, app($ruleSet)->getRules());
}
foreach ($thisRules as $field => $rule) {
if (!isset($rules[$field]) || $this->overrideRules) {
$rules[$field] = $rule;
}
}
return $rules;
}
/**
* Combine this rules with anothe ones.
*
* @param \App\Rules\RuleSets\RuleSet|array $rules
*
* @return array
*/
public function combineWithRules(...$rules): array
{
return array_merge($this->getRules(), ...$this->normalizeRules(...$rules));
}
/**
* Returns rules of rule sets arrays or objects as array.
*
* @param ...$rules
*
* @return array
*/
private function normalizeRules(...$rules): array
{
return array_map(function ($ruleSet) {
if ($this->validateRuleSet($ruleSet)) {
return $ruleSet instanceof RuleSet ? $ruleSet->getRules() : $ruleSet;
}
}, $rules);
}
/**
* Checks if the set is an instance of RuleSet or an array.
*
* @param \App\Rules\RuleSets\RuleSet|array $rules
*
* @throws \InvalidArgumentException
*
* @return bool
*/
private function validateRuleSet($ruleSet): bool
{
if (!($ruleSet instanceof RuleSet) && !is_array($ruleSet)) {
throw new InvalidArgumentException('Rules must be instance of \App\Rules\RuleSets\RuleSet or array.');
}
return true;
}
/**
* Returns set rules.
*
* @return array
*/
abstract protected function rules(): array;
}
<?php
namespace App\Rules\RuleSets;
interface RuleSet
{
/**
* Returns the rules of the set.
*
* @return array
*/
public function getRules(): array;
/**
* Combines current rule set with another.
*
* @param \App\Rules\RuleSets\RuleSet|array ...$rules
*
* @return array
*/
public function combineWithRules(...$rules): array;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment