Completed
Push — master ( d6446f...d11253 )
by Nelson
05:36
created

Text::ensureIsNotNull()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2.2559

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 1
dl 0
loc 9
ccs 3
cts 5
cp 0.6
crap 2.2559
rs 9.6666
c 0
b 0
f 0
1
<?php
2
/**
3
 * PHP: Nelson Martell Library file
4
 *
5
 * Content:
6
 * - Class definition:  [NelsonMartell\Extensions]  String
7
 *
8
 * Copyright © 2015-2016 Nelson Martell (http://nelson6e65.github.io)
9
 *
10
 * Licensed under The MIT License (MIT)
11
 * For full copyright and license information, please see the LICENSE
12
 * Redistributions of files must retain the above copyright notice.
13
 *
14
 * @copyright 2015-2017 Nelson Martell
15
 * @link      http://nelson6e65.github.io/php_nml/
16
 * @since     v0.7.0
17
 * @license   http://www.opensource.org/licenses/mit-license.php The MIT License (MIT)
18
 * */
19
namespace NelsonMartell\Extensions;
20
21
use InvalidArgumentException;
22
use Cake\Utility\Text as TextBase;
23
24
use function NelsonMartell\msg;
25
use function NelsonMartell\typeof;
26
27
/**
28
 * Provides extension methods to handle strings.
29
 * This class is based on \Cake\Utility\Text of CakePHP(tm) class.
30
 *
31
 * @see \Cake\Utility\Text::insert
32
 * @link http://book.cakephp.org/3.0/en/core-libraries/text.html
33
 * */
34
class Text extends TextBase
35
{
36
37
    /**
38
     * Replaces format elements in a string with the string representation of an
39
     * object matching the list of arguments specified. You can give as many
40
     * params as you need, or an array with values.
41
     *
42
     * ##Usage
43
     * Using numbers as placeholders (encloses between `{` and `}`), you can get
44
     * the matching string representation of each object given. Use `{0}` for
45
     * the fist object, `{1}` for the second, and so on:
46
     *
47
     * ```php
48
     * $format = '{0} is {1} years old, and have {2} cats.';
49
     * echo Text::format($format, 'Bob', 65, 101); // 'Bob is 65 years old, and have 101 cats.'
50
     * ```
51
     *
52
     * You can also use an array to give objects values:
53
     *
54
     * ```php
55
     * $format = '{0} is {1} years old, and have {2} cats.';
56
     * $data   = ['Bob', 65, 101];
57
     * echo Text::format($format, $data); // 'Bob is 65 years old, and have 101 cats.'
58
     * ```
59
     *
60
     * This is specially useful to be able to use non-numeric placeholders (named placeholders):
61
     *
62
     * ```php
63
     * $format = '{name} is {age} years old, and have {n} cats.';
64
     * $data = ['name' => 'Bob', 'n' => 101, 'age' => 65];
65
     * echo Text::format($format, $data); // 'Bob is 65 years old, and have 101 cats.'
66
     * ```
67
     *
68
     * For numeric placeholders, yo can convert the array into a list of arguments.
69
     *
70
     * ```php
71
     * $format = '{0} is {1} years old, and have {2} cats.';
72
     * $data   = ['Bob', 65, 101];
73
     * echo Text::format($format, ...$data); // 'Bob is 65 years old, and have 101 cats.'
74
     * ```
75
     *
76
     * > Note: If objects are not convertible to string, it will throws and catchable exception
77
     * (`InvalidArgumentException`).
78
     *
79
     * @param string      $format An string containing variable placeholders to be replaced. If you provide name
80
     *   placeholders, you must pass the target array as
81
     * @param array|mixed $args   Object(s) to be replaced into $format placeholders.
82
     *   You can provide one item only of type array for named placeholders replacement. For numeric placeholders, you
83
     *   can still pass the array or convert it into arguments by using the '...' syntax instead.
84
     *
85
     * @return string
86
     * @throws InvalidArgumentException if $format is not an string or placeholder values are not string-convertibles.
87
     * @todo   Implement formatting, like IFormatProvider or something like that.
88
     * @author Nelson Martell <[email protected]>
89
     */
90 234
    public static function format($format, ...$args)
91
    {
92 234
        static $options = [
93
            'before'  => '{',
94
            'after'   => '}',
95
        ];
96
97 234
        $originalData = $args;
98
99
        // Make it compatible with named placeholders along numeric ones if passed only 1 array as argument
100 234
        if (count($args) === 1 && is_array($args[0])) {
101 227
            $originalData = $args[0];
102
        }
103
104 234
        $data = [];
105
        // Sanitize values to be convertibles into strings
106 234
        foreach ($originalData as $placeholder => $value) {
107 234
            $valueType = typeof($value);
108
109 234
            if ($valueType->canBeString() === false) {
110 3
                $msg = 'Value for "{{0}}" placeholder is not convertible to string; "{1}" type given.';
111 3
                throw new InvalidArgumentException(msg($msg, $placeholder, $valueType));
112
            }
113
114
            // This is to work-arround a bug in use of ``asort()`` function in ``Text::insert`` (at v3.2.5)
0 ignored issues
show
Unused Code Comprehensibility introduced by
36% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
115
            // without SORT_STRING flag... by forcing value to be string.
116 234
            settype($value, 'string');
117 234
            $data[$placeholder] = $value;
118
        }
119
120 234
        return static::insert($format, $data, $options);
121
    }
122
123
    /**
124
     * Ensures that object given is not null. If is `null`, throws and exception.
125
     *
126
     * @param mixed $obj Object to validate
127
     *
128
     * @return mixed Same object
129
     * @throws InvalidArgumentException if object is `null`.
130
     */
131 303
    public static function ensureIsNotNull($obj)
132
    {
133 303
        if (is_null($obj)) {
134
            $msg = msg('Provided object must not be NULL.');
135
            throw new InvalidArgumentException($msg);
136
        }
137
138 303
        return $obj;
139
    }
140
141
    /**
142
     * Ensures that object given is an string. Else, thows an exception
143
     *
144
     * @param mixed $obj Object to validate.
145
     *
146
     * @return string Same object given, but ensured that is an string.
147
     * @throws InvalidArgumentException if object is not an `string`.
148
     */
149 303
    public static function ensureIsString($obj)
150
    {
151 303
        if (!is_string(static::ensureIsNotNull($obj))) {
152 1
            $msg = msg('Provided object must to be an string; "{0}" given.', typeof($obj));
153 1
            throw new InvalidArgumentException($msg);
154
        }
155
156 303
        return $obj;
157
    }
158
159
    /**
160
     * Ensures that given string is not empty.
161
     *
162
     * @param string $string String to validate.
163
     *
164
     * @return string Same string given, but ensured that is not empty.
165
     * @throws InvalidArgumentException if string is null or empty.
166
     */
167 View Code Duplication
    public static function ensureIsNotEmpty($string)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
168
    {
169
        if (static::ensureIsString($string) === '') {
170
            $msg = msg('Provided string must not be empty.');
171
            throw new InvalidArgumentException($msg);
172
        }
173
174
        return $string;
175
    }
176
177
    /**
178
     * Ensures that given string is not empty or whitespaces.
179
     *
180
     * @param string $string String to validate.
181
     *
182
     * @return string Same string given, but ensured that is not whitespaces.
183
     * @throws InvalidArgumentException if object is not an `string`.
184
     * @see    \trim()
185
     */
186 View Code Duplication
    public static function ensureIsNotWhiteSpaces($string)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
187
    {
188
        if (trim(static::ensureIsNotEmpty($string)) === '') {
189
            $msg = msg('Provided string must not be white spaces.');
190
            throw new InvalidArgumentException($msg);
191
        }
192
193
        return $string;
194
    }
195
196
    /**
197
     * Ensures that an string follows the PHP variables naming convention.
198
     *
199
     * @param string $string String to be ensured.
200
     *
201
     * @return string
202
     * @throws InvalidArgumentException if object is not an `string` or do not
203
     *   follows the PHP variables naming convention.
204
     */
205 303
    public static function ensureIsValidVarName($string)
206
    {
207 303
        $pattern = '/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/';
208
209 303
        if (!preg_match($pattern, static::ensureIsString($string))) {
210
            $msg = msg('Provided string do not follows PHP variables naming convention: "{0}".', $string);
211
            throw new InvalidArgumentException($msg);
212
        }
213
214 303
        return $string;
215
    }
216
}
217