Extract the rule name and parameters from a rule.

@param  array|string $rules
@return array
500197
protected function parseRule( $rules )
	{
		if ( is_array( $rules ) )
		{
			$rules = $this->parseArrayRule( $rules );
		}
		else
		{
			$rules = $this->parseStringRule( $rules );
		}

		$rules[0] = $this->normalizeRule( $rules[0] );

		return $rules;
	}
918082
private function sortRules(&$rules)
    {
        sort($rules);
        usort($rules, function ($a, $b) {
            return strlen($a) - strlen($b);
        });
    }
81499
public function parse( $rules ) {
		if ( is_array( $rules ) ) {
			return $this->parse_array_rules( $rules );
		}

		return $this->parse_string_rules( $rules );
	}
936438
protected function parseConstraint($rule)
    {
        $parsed = [];

        // If someone added a native (associative) array.
        if (is_array($rule) && !isset($rule[0])) {
            return $this->normalizeNativeRule($rule);
        }

        $constraints = $this->explodeConstraints($rule);

        foreach ($constraints as $constraint) {
            list($name, $parameters) = $this->nameAndParameters($constraint);
            $parsed[$name] = $parameters;
        }

        return $parsed;
    }
1178795
protected function parse_string_rules( $rules ) {
		$split_rules = explode( '|', $rules );
		$parse_rules = [];

		foreach ( $split_rules as $rule ) {
			$parameters = [];

			// Format rule and parameters follows {rule}:{parameters}.
			if ( strpos( $rule, ':' ) !== false ) {
				list( $rule, $parameter ) = explode( ':', $rule, 2 );

				$parameter = false !== strpos( $parameter, ',' )
					? str_getcsv( $parameter )
					: [ $parameter ];

				$parameters = $this->wrap_parameters( $rule, $parameter );
			}

			$parse_rules[] = [ $this->normalize( $rule ), $parameters ];
		}

		return $parse_rules;
	}
764031
public function filterRules(array $rules = array())
    {
        if (empty($rules)) {
            return $this->filterRules;
        }

        $this->filterRules = $rules;

        return $this;
    }
358585
private function extractNeededProperties($rule)
    {
        if (\in_array($rule['operation'], ['AND', 'OR'])) {
            $properties = [];
            foreach ($rule['children'] as $childRule) {
                $properties[] = $this->extractNeededProperties($childRule);
            }
            return $properties;
        }

        // Local is child property name.
        if (isset($rule['local'])) {
            return $rule['local'];
        }

        // Remote is parent property name.
        if (isset($rule['property'])) {
            return $rule['property'];
        }

        throw new \RuntimeException('Unexpected filter rule ' . \var_export($rule, true));
    }
966055
private function serializeRules(array $rules): array
    {
        $serializer = new BlockSerializer();

        $indexMap = [];
        foreach ($rules as $name => $rule) {
            $indexMap[$name] = $serializer->addBlock($rule->setName($name)->enableCapture()->toBlock());
        }

        return [$indexMap, $serializer->get()];
    }
890574
public function explode( $rules ) {
		if ( empty( $rules ) ) {
			return [];
		}

		foreach ( $rules as $key => $_rules ) {
			$rules[ $key ] = $this->parse( $_rules );
		}

		return $rules;
	}
417506
protected function rulesArrayContainsAnyNestedRules(array $rules)
    {
        foreach ($rules as $rule) {

            if ( ! empty($rule->key())) {
                return true;
            }
        }

        return false;
    }
652283
protected function splitTypeAndProperties($rule)
    {
        // A nested rule
        if (!mb_strpos($rule, ':[')) {
            $parts = explode('|', $rule);
            $typeName = array_shift($parts);
            return [$typeName, $parts];
        }

        $chars = Helper::stringSplit($rule);

        $level = 0;
        $isFirst = true;
        $typeName = '';
        $parts = [];
        $currentPart = -1;

        foreach ($chars as $char) {
            if ($char == '[') {
                $level++;
            }

            if ($char == ']') {
                $level--;
            }

            if ($char == '|' && $level == 0) {
                $isFirst = false;
                $currentPart++;
                continue;
            }

            if ($isFirst) {
                $typeName .= $char;
                continue;
            }


            if (!isset($parts[$currentPart])) {
                $parts[$currentPart] = '';
            }

            $parts[$currentPart] .= $char;
        }

        return [$typeName, $parts];
    }
1260517
protected static function initMatrix(array $rules)
	{
		$matrix   = [];
		$tagNames = array_keys($rules);

		foreach ($rules as $tagName => $tagRules)
		{
			$matrix[$tagName]['allowedChildren']    = array_fill_keys($tagNames, 0);
			$matrix[$tagName]['allowedDescendants'] = array_fill_keys($tagNames, 0);
		}

		return $matrix;
	}
583737
protected function resolveRule($rule)
    {

        $validation = [];
        if (is_array($rule)) {
            return $validation;
        }
        switch ($rule) {
            case 'required':
                $validation['required'] = 'required';
                break;
            default:
                if (str_contains($rule, ':') && !str_contains($rule, 'unique')) {
                    list($name, $value) = explode(':', $rule);
                    $validation["data-{$name}length"] = $value;
                }
                break;
        }
        return $validation;
    }
132566
protected function parseRulesArray(array $rules)
    {
        $parsedRules = [];

        $rawRules = (new ValidationRuleParser($this->data))->explode($rules);

        foreach ($rawRules->rules as $attribute => $attributeRules) {
            foreach ($attributeRules as $attributeRule) {
                $parsedRule = $this->parseRuleString($attributeRule);
                if ($parsedRule) {
                    $parsedRules[$attribute][] = $parsedRule;
                }
            }
        }

        return $parsedRules;
    }
393298
protected function getValidationRulesForAttributes(array $modelParams, array $rules = []): array
    {
        $modelRules = empty($rules) ? $this->getValidationRules() : $rules;
        return array_intersect_key($modelRules, $modelParams);
    }
96729
public function explode($rules)
    {
        $this->implicitAttributes = [];

        $rules = $this->explodeRules($rules);

        return (object) [
            'rules' => $rules,
            'implicitAttributes' => $this->implicitAttributes,
        ];
    }
16531
private function parseRule($rule)
    {
        $parameters = [];

        if (strpos($rule, ':') !== false) {
            list($rule, $parameter) = explode(':', $rule, 2);
            $parameters = $this->parseParameters($rule, $parameter);
        }

        if (!Variable::ruleExists($rule)) {
            throw new \InvalidArgumentException("validation: rule '$rule' not supported.");
        }

        return [$rule, $parameters];
    }