Completed
Push — master ( 2823b8...fb1f20 )
by Chad
19s
created

Strings::concat()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
eloc 2
nc 1
nop 3
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
            $format = "Value '%s' with length '%d' is less than '%d' or greater than '%d'";
127
            throw new FilterException(
128
                sprintf($format, $value, $valueLength, $minLength, $maxLength)
129
            );
130
        }
131
    }
132
133
    private static function valueIsNullAndValid(bool $allowNull, $value = null) : bool
134
    {
135
        if ($allowNull === false && $value === null) {
136
            throw new FilterException('Value failed filtering, $allowNull is set to false');
137
        }
138
139
        return $allowNull === true && $value === null;
140
    }
141
142
    private static function validateIfObjectIsAString($value)
143
    {
144
        if (!is_string($value)) {
145
            throw new FilterException("Value '" . var_export($value, true) . "' is not a string");
146
        }
147
    }
148
149
    private static function enforceValueCanBeCastAsString($value)
150
    {
151
        try {
152
            $value = (
153
                function (string $str) : string {
154
                    return $str;
155
                }
156
            )($value);
157
        } catch (TypeError $te) {
158
            throw new FilterException(sprintf("Value '%s' is not a string", var_export($value, true)));
159
        }
160
161
        return $value;
162
    }
163
}
164