Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
73 / 73
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
Validator
100.00% covered (success)
100.00%
73 / 73
100.00% covered (success)
100.00%
4 / 4
20
100.00% covered (success)
100.00%
1 / 1
 notUnique
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
 unique
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
1 / 1
6
 exist
100.00% covered (success)
100.00%
18 / 18
100.00% covered (success)
100.00%
1 / 1
4
 existMany
100.00% covered (success)
100.00%
28 / 28
100.00% covered (success)
100.00%
1 / 1
9
1<?php declare(strict_types=1);
2/*
3 * This file is part of Aplus Framework MVC Library.
4 *
5 * (c) Natan Felles <natanfelles@gmail.com>
6 *
7 * For the full copyright and license information, please view the LICENSE
8 * file that was distributed with this source code.
9 */
10namespace Framework\MVC;
11
12use Framework\Helpers\ArraySimple;
13use LogicException;
14
15/**
16 * Class Validator.
17 *
18 * @package mvc
19 */
20class Validator extends \Framework\Validation\Validator
21{
22    /**
23     * Validates database table not unique value.
24     *
25     * @param string $field
26     * @param array<string,mixed> $data
27     * @param string $tableColumn
28     * @param string $ignoreColumn
29     * @param int|string $ignoreValue
30     * @param string $connection
31     *
32     * @return bool
33     */
34    public static function notUnique(
35        string $field,
36        array $data,
37        string $tableColumn,
38        string $ignoreColumn = '',
39        int | string $ignoreValue = '',
40        string $connection = 'default'
41    ) : bool {
42        return ! static::unique(
43            $field,
44            $data,
45            $tableColumn,
46            $ignoreColumn,
47            $ignoreValue,
48            $connection
49        );
50    }
51
52    /**
53     * Validates database table unique value.
54     *
55     * You can ignore rows where a column has a certain value.
56     * Useful when updating a row in the database.
57     *
58     * @param string $field
59     * @param array<string,mixed> $data
60     * @param string $tableColumn
61     * @param string $ignoreColumn
62     * @param int|string $ignoreValue
63     * @param string $connection
64     *
65     * @return bool
66     */
67    public static function unique(
68        string $field,
69        array $data,
70        string $tableColumn,
71        string $ignoreColumn = '',
72        int | string $ignoreValue = '',
73        string $connection = 'default'
74    ) : bool {
75        $value = static::getData($field, $data);
76        if ($value === null) {
77            return false;
78        }
79        $ignoreValue = (string) $ignoreValue;
80        [$table, $column] = \array_pad(\explode('.', $tableColumn, 2), 2, '');
81        if ($column === '') {
82            $column = $field;
83        }
84        if ($connection === '') {
85            throw new LogicException(
86                'The connection parameter must be set to be able to connect the database'
87            );
88        }
89        $statement = App::database($connection)
90            ->select()
91            ->expressions(['count' => static fn () => 'COUNT(*)'])
92            ->from($table)
93            ->whereEqual($column, $value);
94        if ($ignoreColumn !== '' && ! \preg_match('#^{(\w+)}$#', $ignoreValue)) {
95            $statement->whereNotEqual($ignoreColumn, $ignoreValue);
96        }
97        return $statement->limit(1)->run()->fetch()->count < 1; // @phpstan-ignore-line
98    }
99
100    /**
101     * Validates value exists in database table.
102     *
103     * @since 3.3
104     *
105     * @param string $field
106     * @param array<string,mixed> $data
107     * @param string $tableColumn
108     * @param string $connection
109     *
110     * @return bool
111     */
112    public static function exist(
113        string $field,
114        array $data,
115        string $tableColumn,
116        string $connection = 'default'
117    ) : bool {
118        $value = static::getData($field, $data);
119        if ($value === null) {
120            return false;
121        }
122        [$table, $column] = \array_pad(\explode('.', $tableColumn, 2), 2, '');
123        if ($column === '') {
124            $column = $field;
125        }
126        if ($connection === '') {
127            throw new LogicException(
128                'The connection parameter must be set to be able to connect the database'
129            );
130        }
131        return App::database($connection) // @phpstan-ignore-line
132            ->select()
133            ->expressions(['count' => static fn () => 'COUNT(*)'])
134            ->from($table)
135            ->whereEqual($column, $value)
136            ->limit(1)
137            ->run()
138            ->fetch()->count > 0;
139    }
140
141    /**
142     * Validates many values exists in database table.
143     *
144     * @since 3.10
145     *
146     * @param string $field
147     * @param array<string,mixed> $data
148     * @param string $tableColumn
149     * @param string $connection
150     *
151     * @return bool
152     */
153    public static function existMany(
154        string $field,
155        array $data,
156        string $tableColumn,
157        string $connection = 'default'
158    ) : bool {
159        $values = ArraySimple::value($field, $data);
160        if ($values === null) {
161            return true;
162        }
163        if ( ! \is_array($values)) {
164            return false;
165        }
166        foreach ($values as $value) {
167            if ( ! \is_scalar($value)) {
168                return false;
169            }
170        }
171        [$table, $column] = \array_pad(\explode('.', $tableColumn, 2), 2, '');
172        if ($column === '') {
173            $column = $field;
174        }
175        if ($connection === '') {
176            throw new LogicException(
177                'The connection parameter must be set to be able to connect the database'
178            );
179        }
180        $database = App::database($connection);
181        foreach ($values as $value) {
182            $count = $database // @phpstan-ignore-line
183                ->select()
184                ->expressions(['count' => static fn () => 'COUNT(*)'])
185                ->from($table)
186                ->whereEqual($column, $value)
187                ->limit(1)
188                ->run()
189                ->fetch()->count;
190            if ($count < 1) {
191                return false;
192            }
193        }
194        return true;
195    }
196}