src/core/validator/Validator.php
private function init(): void
    {
        $data = $this->data;

        $this
            // Required value rules
            ->addRule(
                'required',
                function (string $fieldName) use ($data): bool {
                    if (self::isIndexSet($data, $fieldName)) {
                        return true;
                    }
                    return false;
                },
                function ($fieldName): string {
                    return "Field '{$fieldName}' is required.";
                }
            )
            // String rules
            ->addRule(
                'string',
                function (string $fieldName, array $options = []) use ($data): bool {
                    if (self::isIndexSet($data, $fieldName)) {
                        $value = self::getArrayItemByPointSeparatedKey($data, $fieldName);
                        if (!is_string($value)) {
                            return false;
                        }
                        if (isset($options['notEmpty'])) {
                            $trimVal = trim($value);
                            if ($options['notEmpty'] && empty($trimVal)) {
                                return false;
                            }
                            if (!$options['notEmpty'] && !empty($trimVal)) {
                                return false;
                            }
                        }
                        if (isset($options['pattern'])) {
                            if (!preg_match($options['pattern'], $value)) {
                                return false;
                            }
                        }
                        if (isset($options['length'])) {
                            $length = mb_strlen($value);
                            if (isset($options['length']['min'])) {
                                if ($length < $options['length']['min']) {
                                    return false;
                                }
                            }
                            if (isset($options['length']['max'])) {
                                if ($length > $options['length']['max']) {
                                    return false;
                                }
                            }
                            if (isset($options['length']['equal'])) {
                                if ($length != $options['length']['equal']) {
                                    return false;
                                }
                            }
                        }
                    }
                    return true;
                },
                function (string $fieldName, array $options = []): string {
                    if (!empty($options)) {
                        $keys = implode(', ', array_keys($options));
                        return "Invalid string field '{$fieldName}' value. "
                        . "Validation options: {$keys}";
                    }
                    return "Invalid string field '{$fieldName}' value.";
                }
            )
            // Number rules
            ->addRule(
                'number',
                function (string $fieldName, array $options = []) use ($data): bool {
                    if (self::isIndexSet($data, $fieldName)) {
                        $value = self::getArrayItemByPointSeparatedKey($data, $fieldName);
                        if (!is_numeric($value)) {
                            return false;
                        }
                        if (isset($options['float'])) {
                            if ($options['float'] && !is_float($value)) {
                                return false;
                            }
                            if (!$options['float'] && is_float($value)) {
                                return false;
                            }
                        }
                        if (isset($options['integer'])) {
                            if ($options['integer'] && !is_int($value)) {
                                return false;
                            }
                            if (!$options['integer'] && is_int($value)) {
                                return false;
                            }
                        }
                        if (isset($options['positive'])) {
                            if ($options['positive'] && $value <= 0) {
                                return false;
                            }
                            if (!$options['positive'] && $value >= 0) {
                                return false;
                            }
                        }
                        if (isset($options['value'])) {
                            if (isset($options['value']['equal'])) {
                                if ($value != $options['value']['equal']) {
                                    return false;
                                }
                            }
                            if (isset($options['value']['min'])) {
                                if ($value < $options['value']['min']) {
                                    return false;
                                }
                            }
                            if (isset($options['value']['max'])) {
                                if ($value > $options['value']['max']) {
                                    return false;
                                }
                            }
                        }
                    }
                    return true;
                },
                function (string $fieldName, array $options = []) {
                    if (!empty($options)) {
                        $keys = implode(', ', array_keys($options));
                        return "Invalid number field '{$fieldName}' value. "
                        . "Validation options: {$keys}";
                    }
                    return "Invalid number field '{$fieldName}' value.";
                }
            )
            // Array rules
            ->addRule(
                'array',
                function (string $fieldName, array $options = []) use ($data): bool {
                    if (self::isIndexSet($data, $fieldName)) {
                        $value = self::getArrayItemByPointSeparatedKey($data, $fieldName);
                        if (!is_array($value)) {
                            return false;
                        }
                        if (isset($options['assoc'])) {
                            $isAssoc = function (array $array): bool {
                                // return false if array is empty
                                return (bool) count(array_filter(
                                    array_keys($array),
                                    'is_string'
                                ));
                            };
                            if ($options['assoc'] && !$isAssoc($value)) {
                                return false;
                            }
                            if (!$options['assoc'] && $isAssoc($value)) {
                                return false;
                            }
                            unset($isAssoc);
                        }
                        if (isset($options['length'])) {
                            $length = count($value);
                            if (isset($options['length']['min'])) {
                                if ($length < $options['length']['min']) {
                                    return false;
                                }
                            }
                            if (isset($options['length']['max'])) {
                                if ($length > $options['length']['max']) {
                                    return false;
                                }
                            }
                            if (isset($options['length']['equal'])) {
                                if ($length != $options['length']['equal']) {
                                    return false;
                                }
                            }
                        }
                    }
                    return true;
                },
                function (string $fieldName, array $options = []): string {
                    if (!empty($options)) {
                        $keys = implode(', ', array_keys($options));
                        return "Invalid array field '{$fieldName}' value. "
                        . "Validation options: {$keys}";
                    }
                    return "Invalid array field '{$fieldName}' value.";
                }
            )
            // Boolean rules
            ->addRule(
                'boolean',
                function (string $fieldName, array $options = []) use ($data): bool {
                    if (self::isIndexSet($data, $fieldName)) {
                        $value = self::getArrayItemByPointSeparatedKey($data, $fieldName);
                        if (!is_bool($value)) {
                            return false;
                        }
                        if (isset($options['isTrue'])) {
                            if ($options['isTrue'] && !$value) {
                                return false;
                            }
                            if (!$options['isTrue'] && $value) {
                                return false;
                            }
                        }
                    }
                    return true;
                },
                function (string $fieldName, array $options = []): string {
                    if (!empty($options)) {
                        $keys = implode(', ', array_keys($options));
                        return "Invalid boolean field '{$fieldName}' value. "
                        . "Validation options: {$keys}";
                    }
                    return "Invalid boolean field '{$fieldName}' value.";
                }
            );
    }
private function init(): void
    {
        $data = $this->data;

        $this
            // Required value rules
            ->addRule(
                'required',
                function (string $fieldName) use ($data): bool {
                    if (self::isIndexSet($data, $fieldName)) {
                        return true;
                    }
                    return false;
                },
                function ($fieldName): string {
                    return "Field '{$fieldName}' is required.";
                }
            )
            // String rules
            ->addRule(
                'string',
                function (string $fieldName, array $options = []) use ($data): bool {
                    if (self::isIndexSet($data, $fieldName)) {
                        $value = self::getArrayItemByPointSeparatedKey($data, $fieldName);
                        if (!is_string($value)) {
                            return false;
                        }
                        if (isset($options['notEmpty'])) {
                            $trimVal = trim($value);
                            if ($options['notEmpty'] && empty($trimVal)) {
                                return false;
                            }
                            if (!$options['notEmpty'] && !empty($trimVal)) {
                                return false;
                            }
                        }
                        if (isset($options['pattern'])) {
                            if (!preg_match($options['pattern'], $value)) {
                                return false;
                            }
                        }
                        if (isset($options['length'])) {
                            $length = mb_strlen($value);
                            if (isset($options['length']['min'])) {
                                if ($length < $options['length']['min']) {
                                    return false;
                                }
                            }
                            if (isset($options['length']['max'])) {
                                if ($length > $options['length']['max']) {
                                    return false;
                                }
                            }
                            if (isset($options['length']['equal'])) {
                                if ($length != $options['length']['equal']) {
                                    return false;
                                }
                            }
                        }
                    }
                    return true;
                },
                function (string $fieldName, array $options = []): string {
                    if (!empty($options)) {
                        $keys = implode(', ', array_keys($options));
                        return "Invalid string field '{$fieldName}' value. "
                        . "Validation options: {$keys}";
                    }
                    return "Invalid string field '{$fieldName}' value.";
                }
            )
            // Number rules
            ->addRule(
                'number',
                function (string $fieldName, array $options = []) use ($data): bool {
                    if (self::isIndexSet($data, $fieldName)) {
                        $value = self::getArrayItemByPointSeparatedKey($data, $fieldName);
                        if (!is_numeric($value)) {
                            return false;
                        }
                        if (isset($options['float'])) {
                            if ($options['float'] && !is_float($value)) {
                                return false;
                            }
                            if (!$options['float'] && is_float($value)) {
                                return false;
                            }
                        }
                        if (isset($options['integer'])) {
                            if ($options['integer'] && !is_int($value)) {
                                return false;
                            }
                            if (!$options['integer'] && is_int($value)) {
                                return false;
                            }
                        }
                        if (isset($options['positive'])) {
                            if ($options['positive'] && $value <= 0) {
                                return false;
                            }
                            if (!$options['positive'] && $value >= 0) {
                                return false;
                            }
                        }
                        if (isset($options['value'])) {
                            if (isset($options['value']['equal'])) {
                                if ($value != $options['value']['equal']) {
                                    return false;
                                }
                            }
                            if (isset($options['value']['min'])) {
                                if ($value < $options['value']['min']) {
                                    return false;
                                }
                            }
                            if (isset($options['value']['max'])) {
                                if ($value > $options['value']['max']) {
                                    return false;
                                }
                            }
                        }
                    }
                    return true;
                },
                function (string $fieldName, array $options = []) {
                    if (!empty($options)) {
                        $keys = implode(', ', array_keys($options));
                        return "Invalid number field '{$fieldName}' value. "
                        . "Validation options: {$keys}";
                    }
                    return "Invalid number field '{$fieldName}' value.";
                }
            )
            // Array rules
            ->addRule(
                'array',
                function (string $fieldName, array $options = []) use ($data): bool {
                    if (self::isIndexSet($data, $fieldName)) {
                        $value = self::getArrayItemByPointSeparatedKey($data, $fieldName);
                        if (!is_array($value)) {
                            return false;
                        }
                        if (isset($options['assoc'])) {
                            $isAssoc = function (array $array): bool {
                                // return false if array is empty
                                return (bool) count(array_filter(
                                    array_keys($array),
                                    'is_string'
                                ));
                            };
                            if ($options['assoc'] && !$isAssoc($value)) {
                                return false;
                            }
                            if (!$options['assoc'] && $isAssoc($value)) {
                                return false;
                            }
                            unset($isAssoc);
                        }
                        if (isset($options['length'])) {
                            $length = count($value);
                            if (isset($options['length']['min'])) {
                                if ($length < $options['length']['min']) {
                                    return false;
                                }
                            }
                            if (isset($options['length']['max'])) {
                                if ($length > $options['length']['max']) {
                                    return false;
                                }
                            }
                            if (isset($options['length']['equal'])) {
                                if ($length != $options['length']['equal']) {
                                    return false;
                                }
                            }
                        }
                    }
                    return true;
                },
                function (string $fieldName, array $options = []): string {
                    if (!empty($options)) {
                        $keys = implode(', ', array_keys($options));
                        return "Invalid array field '{$fieldName}' value. "
                        . "Validation options: {$keys}";
                    }
                    return "Invalid array field '{$fieldName}' value.";
                }
            )
            // Boolean rules
            ->addRule(
                'boolean',
                function (string $fieldName, array $options = []) use ($data): bool {
                    if (self::isIndexSet($data, $fieldName)) {
                        $value = self::getArrayItemByPointSeparatedKey($data, $fieldName);
                        if (!is_bool($value)) {
                            return false;
                        }
                        if (isset($options['isTrue'])) {
                            if ($options['isTrue'] && !$value) {
                                return false;
                            }
                            if (!$options['isTrue'] && $value) {
                                return false;
                            }
                        }
                    }
                    return true;
                },
                function (string $fieldName, array $options = []): string {
                    if (!empty($options)) {
                        $keys = implode(', ', array_keys($options));
                        return "Invalid boolean field '{$fieldName}' value. "
                        . "Validation options: {$keys}";
                    }
                    return "Invalid boolean field '{$fieldName}' value.";
                }
            );
    }
This method fills the validator with default set of rules (and options of rules)
such as rules for validating required fields, strings, numbers, arrays etc.
@return void