Passed
Pull Request — master (#5)
by Chad
03:17
created

Strings::validateIfObjectIsAString()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
nc 2
nop 1
dl 0
loc 4
c 0
b 0
f 0
cc 2
rs 10
1
<?php
2
3
namespace TraderInteractive\Filter;
4
5
use TraderInteractive\Exceptions\FilterException;
6
use TypeError;
7
8
/**
9
 * A collection of filters for strings.
10
 */
11
final class Strings
12
{
13
    /**
14
     * Filter a string.
15
     *
16
     * Verify that the passed in value  is a string.  By default, nulls are not allowed, and the length is restricted
17
     * between 1 and PHP_INT_MAX.  These parameters can be overwritten for custom behavior.
18
     *
19
     * The return value is the string, as expected by the \TraderInteractive\Filterer class.
20
     *
21
     * @param mixed $value The value to filter.
22
     * @param bool $allowNull True to allow nulls through, and false (default) if nulls should not be allowed.
23
     * @param int $minLength Minimum length to allow for $value.
24
     * @param int $maxLength Maximum length to allow for $value.
25
     * @return string|null The passed in $value.
26
     *
27
     * @throws FilterException if the value did not pass validation.
28
     * @throws \InvalidArgumentException if one of the parameters was not correctly typed.
29
     */
30
    public static function filter(
31
        $value = null,
32
        bool $allowNull = false,
33
        int $minLength = 1,
34
        int $maxLength = PHP_INT_MAX
35
    ) {
36
        self::validateMinimumLength($minLength);
37
        self::validateMaximumLength($maxLength);
38
39
        if (self::valueIsNullAndValid($allowNull, $value)) {
40
            return null;
41
        }
42
43
        $value = self::enforceValueCanBeCastAsString($value);
44
45
        self::validateStringLength($value, $minLength, $maxLength);
46
47
        return $value;
48
    }
49
50
    /**
51
     * Explodes a string into an array using the given delimiter.
52
     *
53
     * For example, given the string 'foo,bar,baz', this would return the array ['foo', 'bar', 'baz'].
54
     *
55
     * @param string $value The string to explode.
56
     * @param string $delimiter The non-empty delimiter to explode on.
57
     * @return array The exploded values.
58
     *
59
     * @throws \InvalidArgumentException if the delimiter does not pass validation.
60
     */
61
    public static function explode($value, string $delimiter = ',')
62
    {
63
        self::validateIfObjectIsAString($value);
64
65
        if (empty($delimiter)) {
66
            throw new \InvalidArgumentException(
67
                "Delimiter '" . var_export($delimiter, true) . "' is not a non-empty string"
68
            );
69
        }
70
71
        return explode($delimiter, $value);
72
    }
73
74
    /**
75
     * This filter prepends $prefix and appends $suffix to the string value.
76
     *
77
     * @param mixed  $value  The string value to which $prefix and $suffix will be added.
78
     * @param string $prefix The value to prepend to the string.
79
     * @param string $suffix The value to append to the string.
80
     *
81
     * @return string
82
     *
83
     * @throws FilterException Thrown if $value cannot be casted to a string.
84
     */
85
    public static function concat($value, string $prefix = '', string $suffix = '') : string
86
    {
87
        self::enforceValueCanBeCastAsString($value);
88
        return "{$prefix}{$value}{$suffix}";
89
    }
90
91
    /**
92
     * Strip HTML and PHP tags from a string. Unlike the strip_tags function this method will return null if a null
93
     * value is given. The native php function will return an empty string.
94
     *
95
     * @param string|null $value The input string
96
     *
97
     * @return string|null
98
     */
99
    public static function stripTags(string $value = null)
100
    {
101
        if ($value === null) {
102
            return null;
103
        }
104
105
        return strip_tags($value);
106
    }
107
108
    private static function validateMinimumLength(int $minLength)
109
    {
110
        if ($minLength < 0) {
111
            throw new \InvalidArgumentException('$minLength was not a positive integer value');
112
        }
113
    }
114
115
    private static function validateMaximumLength(int $maxLength)
116
    {
117
        if ($maxLength < 0) {
118
            throw new \InvalidArgumentException('$maxLength was not a positive integer value');
119
        }
120
    }
121
122
    private static function validateStringLength(string $value = null, int $minLength, int $maxLength)
123
    {
124
        $valueLength = strlen($value);
125
        if ($valueLength < $minLength || $valueLength > $maxLength) {
126
            throw new FilterException(
127
                sprintf(
128
                    "Value '%s' with length '%d' is less than '%d' or greater than '%d'",
129
                    $value,
130
                    $valueLength,
131
                    $minLength,
132
                    $maxLength
133
                )
134
            );
135
        }
136
    }
137
138
    private static function valueIsNullAndValid(bool $allowNull, $value = null) : bool
139
    {
140
        if ($allowNull === false && $value === null) {
141
            throw new FilterException('Value failed filtering, $allowNull is set to false');
142
        }
143
144
        return $allowNull === true && $value === null;
145
    }
146
147
    private static function checkIfScalarAndConvert(&$value)
0 ignored issues
show
Unused Code introduced by
The method checkIfScalarAndConvert() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
148
    {
149
        if (is_scalar($value)) {
150
            $value = (string)$value;
151
        }
152
    }
153
154
    private static function checkIfObjectAndConvert(&$value)
0 ignored issues
show
Unused Code introduced by
The method checkIfObjectAndConvert() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
155
    {
156
        if (is_object($value) && method_exists($value, '__toString')) {
157
            $value = (string)$value;
158
        }
159
    }
160
161
    private static function validateIfObjectIsAString($value)
162
    {
163
        if (!is_string($value)) {
164
            throw new FilterException("Value '" . var_export($value, true) . "' is not a string");
165
        }
166
    }
167
168
    private static function enforceValueCanBeCastAsString($value)
169
    {
170
        try {
171
            $value = (
172
                function (string $str) : string {
173
                    return $str;
174
                }
175
            )($value);
176
        } catch (TypeError $te) {
177
            throw new FilterException(sprintf("Value '%s' is not a string", var_export($value, true)));
178
        }
179
180
        return $value;
181
    }
182
}
183