Passed
Push — master ( adb24b...f5ed45 )
by Tim
12:31
created

Assert::all()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 5
c 1
b 0
f 0
nc 2
nop 2
dl 0
loc 7
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\SAML11\Assert;
6
7
use BadMethodCallException; // Requires ext-spl
8
use DateTime; // requires ext-date
9
use DateTimeImmutable; // requires ext-date
10
use InvalidArgumentException; // Requires ext-spl
11
use SimpleSAML\Assert\Assert as BaseAssert;
12
use SimpleSAML\Assert\AssertionFailedException;
13
use Throwable;
14
15
use function array_pop;
16
use function array_unshift;
17
use function call_user_func_array;
18
use function end;
19
use function is_object;
20
use function is_resource;
21
use function is_string;
22
use function is_subclass_of;
23
use function lcfirst;
24
use function method_exists;
25
use function preg_match; // Requires ext-pcre
26
use function strval;
27
28
/**
29
 * SimpleSAML\SAML11\Assert\Assert wrapper class
30
 *
31
 * @package simplesamlphp/saml11
32
 *
33
 * @method static void validDateTime(mixed $value, string $message = '', string $exception = '')
34
 * @method static void validURI(mixed $value, string $message = '', string $exception = '')
35
 * @method static void validEntityID(mixed $value, string $message = '', string $exception = '')
36
 * @method static void nullOrValidDateTime(mixed $value, string $message = '', string $exception = '')
37
 * @method static void nullOrValidURI(mixed $value, string $message = '', string $exception = '')
38
 * @method static void nullOrValidEntityID(mixed $value, string $message = '', string $exception = '')
39
 * @method static void allValidDateTime(mixed $value, string $message = '', string $exception = '')
40
 * @method static void allValidURI(mixed $value, string $message = '', string $exception = '')
41
 * @method static void allValidEntityID(mixed $value, string $message = '', string $exception = '')
42
 */
43
final class Assert
44
{
45
    use CustomAssertionTrait;
46
47
48
    /**
49
     * @param string $name
50
     * @param array<mixed> $arguments
51
     */
52
    public static function __callStatic(string $name, array $arguments): void
53
    {
54
        // Handle Exception-parameter
55
        $exception = AssertionFailedException::class;
56
57
        $last = end($arguments);
58
        if (is_string($last) && class_exists($last) && is_subclass_of($last, Throwable::class)) {
59
            $exception = $last;
60
            array_pop($arguments);
61
        }
62
63
        try {
64
            if (method_exists(static::class, $name)) {
65
                call_user_func_array([static::class, $name], $arguments);
66
                return;
67
            } elseif (preg_match('/^nullOr(.*)$/i', $name, $matches)) {
68
                $method = lcfirst($matches[1]);
69
                if (method_exists(static::class, $method)) {
70
                    call_user_func_array([static::class, 'nullOr'], [[static::class, $method], $arguments]);
71
                } elseif (method_exists(BaseAssert::class, $method)) {
72
                    call_user_func_array([static::class, 'nullOr'], [[BaseAssert::class, $method], $arguments]);
73
                } else {
74
                    throw new BadMethodCallException(sprintf("Assertion named `%s` does not exists.", $method));
75
                }
76
            } elseif (preg_match('/^all(.*)$/i', $name, $matches)) {
77
                $method = lcfirst($matches[1]);
78
                if (method_exists(static::class, $method)) {
79
                    call_user_func_array([static::class, 'all'], [[static::class, $method], $arguments]);
80
                } elseif (method_exists(BaseAssert::class, $method)) {
81
                    call_user_func_array([static::class, 'all'], [[BaseAssert::class, $method], $arguments]);
82
                } else {
83
                    throw new BadMethodCallException(sprintf("Assertion named `%s` does not exists.", $method));
84
                }
85
            } else {
86
                throw new BadMethodCallException(sprintf("Assertion named `%s` does not exists.", $name));
87
            }
88
        } catch (InvalidArgumentException $e) {
89
            throw new $exception($e->getMessage());
90
        }
91
    }
92
93
94
    /**
95
     * Handle nullOr* for either Webmozart or for our custom assertions
96
     *
97
     * @param callable $method
98
     * @param array<mixed> $arguments
99
     * @return void
100
     */
101
    private static function nullOr(callable $method, array $arguments): void
102
    {
103
        $value = reset($arguments);
104
        ($value === null) || call_user_func_array($method, $arguments);
105
    }
106
107
108
    /**
109
     * all* for our custom assertions
110
     *
111
     * @param callable $method
112
     * @param array<mixed> $arguments
113
     * @return void
114
     */
115
    private static function all(callable $method, array $arguments): void
116
    {
117
        $values = array_pop($arguments);
118
        foreach ($values as $value) {
119
            $tmp = $arguments;
120
            array_unshift($tmp, $value);
121
            call_user_func_array($method, $tmp);
122
        }
123
    }
124
125
126
    /**
127
     * @param mixed $value
128
     *
129
     * @return string
130
     */
131
    protected static function valueToString(mixed $value): string
132
    {
133
        if (is_resource($value)) {
134
            return 'resource';
135
        }
136
137
        if (null === $value) {
138
            return 'null';
139
        }
140
141
        if (true === $value) {
142
            return 'true';
143
        }
144
145
        if (false === $value) {
146
            return 'false';
147
        }
148
149
        if (is_array($value)) {
150
            return 'array';
151
        }
152
153
        if (is_object($value)) {
154
            if (method_exists($value, '__toString')) {
155
                return $value::class . ': ' . self::valueToString($value->__toString());
156
            }
157
158
            if ($value instanceof DateTime || $value instanceof DateTimeImmutable) {
159
                return $value::class . ': ' . self::valueToString($value->format('c'));
160
            }
161
162
            return $value::class;
163
        }
164
165
        if (is_string($value)) {
166
            return '"' . $value . '"';
167
        }
168
169
        return strval($value);
170
    }
171
}
172