Passed
Push — master ( a4f7f2...d3cc39 )
by Melech
04:09
created

Orm::ormExists()   B

Complexity

Conditions 7
Paths 3

Size

Total Lines 16
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 7
c 0
b 0
f 0
dl 0
loc 16
rs 8.8333
cc 7
nc 3
nop 3
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Valkyrja Framework package.
7
 *
8
 * (c) Melech Mizrachi <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Valkyrja\Validation\Rule;
15
16
use Valkyrja\Container\Contract\Container;
17
use Valkyrja\Exception\InvalidArgumentException;
18
use Valkyrja\Orm\Contract\Manager as OrmManager;
19
use Valkyrja\Orm\Data\Value;
20
use Valkyrja\Orm\Data\Where;
21
use Valkyrja\Orm\Entity\Contract\Entity;
22
use Valkyrja\Validation\Exception\ValidationException;
23
24
use function is_bool;
25
use function is_float;
26
use function is_int;
27
use function is_string;
28
29
/**
30
 * Class Orm.
31
 *
32
 * @author Melech Mizrachi
33
 */
34
class Orm
35
{
36
    /**
37
     * ORM constructor.
38
     *
39
     * @param Container  $container
40
     * @param OrmManager $orm
41
     */
42
    public function __construct(
43
        protected Container $container,
44
        protected OrmManager $orm
45
    ) {
46
    }
47
48
    /**
49
     * Ensure that a subject is unique in the database for a field.
50
     *
51
     * @param mixed                 $subject The subject
52
     * @param class-string<Entity>  $entity  The entity to check for uniqueness
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<Entity> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<Entity>.
Loading history...
53
     * @param non-empty-string|null $field   The field to ensure is unique
54
     *
55
     * @return void
56
     */
57
    public function ormUnique(mixed $subject, string $entity, string|null $field = null): void
58
    {
59
        if ($subject !== null && ! is_string($subject) && ! is_int($subject) && ! is_float($subject) && ! is_bool($subject)) {
60
            throw new InvalidArgumentException('Value to match must be string, int, float, bool, or null');
61
        }
62
63
        $field ??= $entity::getIdField();
64
        // Check for a result
65
        $result = $this->orm->createRepository($entity)->findBy(new Where(new Value(name: $field, value: $subject)));
66
67
        if ($result !== null) {
68
            throw new ValidationException("Must be a unique value in $entity for field $field");
69
        }
70
    }
71
72
    /**
73
     * Ensure that a subject exists in the database for a field.
74
     *
75
     * @param mixed                 $subject The subject
76
     * @param class-string<Entity>  $entity  The entity to check for uniqueness
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<Entity> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<Entity>.
Loading history...
77
     * @param non-empty-string|null $field   The field to ensure is unique
78
     *
79
     * @return void
80
     */
81
    public function ormExists(mixed $subject, string $entity, string|null $field = null): void
82
    {
83
        if ($subject !== null && ! is_string($subject) && ! is_int($subject) && ! is_float($subject) && ! is_bool($subject)) {
84
            throw new InvalidArgumentException('Value to match must be string, int, float, bool, or null');
85
        }
86
87
        $field ??= $entity::getIdField();
88
        // Check for a result
89
        $result = $this->orm->createRepository($entity)->findBy(new Where(new Value(name: $field, value: $subject)));
90
91
        if ($result === null) {
92
            throw new ValidationException("Must exist in $entity for field $field");
93
        }
94
95
        // Set a singleton of the entity in the container for later retrieval
96
        $this->container->setSingleton($entity, $result);
97
    }
98
}
99