Completed
Push — v2 ( e81eda...b3c0e1 )
by Joschi
04:43
created

ProfiledNamesFactory   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 156
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 80.43%

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 156
ccs 37
cts 46
cp 0.8043
rs 10
wmc 18
lcom 1
cbo 2

5 Methods

Rating   Name   Duplication   Size   Complexity  
A createProfiledNameFromArray() 0 19 4
A createFromArguments() 0 12 2
B consumeProfiledName() 0 23 5
A createProfiledNameFromObject() 0 16 4
A createProfiledNameFromString() 0 15 3
1
<?php
2
3
/**
4
 * micrometa
5
 *
6
 * @category Jkphl
7
 * @package Jkphl\Micrometa
8
 * @subpackage Jkphl\Micrometa\Infrastructure
9
 * @author Joschi Kuphal <[email protected]> / @jkphl
10
 * @copyright Copyright © 2017 Joschi Kuphal <[email protected]> / @jkphl
11
 * @license http://opensource.org/licenses/MIT The MIT License (MIT)
12
 */
13
14
/***********************************************************************************
15
 *  The MIT License (MIT)
16
 *
17
 *  Copyright © 2017 Joschi Kuphal <[email protected]> / @jkphl
18
 *
19
 *  Permission is hereby granted, free of charge, to any person obtaining a copy of
20
 *  this software and associated documentation files (the "Software"), to deal in
21
 *  the Software without restriction, including without limitation the rights to
22
 *  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
23
 *  the Software, and to permit persons to whom the Software is furnished to do so,
24
 *  subject to the following conditions:
25
 *
26
 *  The above copyright notice and this permission notice shall be included in all
27
 *  copies or substantial portions of the Software.
28
 *
29
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
31
 *  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
32
 *  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
33
 *  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
34
 *  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35
 ***********************************************************************************/
36
37
namespace Jkphl\Micrometa\Infrastructure\Factory;
38
39
use Jkphl\Micrometa\Infrastructure\Parser\ProfiledNamesList;
40
use Jkphl\Micrometa\Ports\Exceptions\InvalidArgumentException;
41
use Jkphl\Micrometa\Ports\Item\Item;
42
43
/**
44
 * Profiled name factory
45
 *
46
 * @package Jkphl\Micrometa
47
 * @subpackage Jkphl\Micrometa\Infrastructure
48
 */
49
class ProfiledNamesFactory
50
{
51
    /**
52
     * Create a list of profiled names from function arguments
53
     *
54
     * The method takes an arbitrary number of arguments and tries to parse them as profiled names. Arguments
55
     * may be strings, arrays or objects.
56
     *
57
     * String values are interpreted as names — with one exception: If the first two arguments are both strings,
58
     * the second one is taken as profile IRI. Optionally following string arguments are taken as names again,
59
     * assuming to share the same profile:
60
     *
61
     *      createFromArguments($name1 [, $profile])
62
     *      createFromArguments($name1, $profile1, $name2, $profile2 ...)
63
     *
64
     * Arrays arguments are expected to have at least one argument which is taken as name. If present, the
65
     * second argument is used as profile (otherwise an empty profile is assumed):
66
     *
67
     *      createFromArguments(array($name [, $profile]))
68
     *
69
     * Object values are expected to have a "name" and an optional "profile" property:
70
     *
71
     *      createFromArguments((object)array('name' => $name [, 'profile' => $profile]))
72
     *
73
     * When an array or object argument is consumed, the profile value will be used for any following string
74
     * argument. You can "reset" the profile to another value by specifying another array or object value in
75
     * this case.
76
     *
77
     *      createFromArguments(array($name1, $profile1), $name2, $name3 ...)
78
     *
79
     * @param array $args Arguments
80
     * @return ProfiledNamesList Profiled names
81
     * @see Item::isOfType()
82
     * @see Item::firstOf()
83
     */
84 15
    public static function createFromArguments($args)
85
    {
86 15
        $profiledNames = [];
87 15
        $profile = false;
88
89
        // Consume and register all given names and profiles
90 15
        while (count($args)) {
91 15
            $profiledNames[] = self::consumeProfiledName($args, $profile);
92 15
        }
93
94 15
        return new ProfiledNamesList($profiledNames);
95
    }
96
97
    /**
98
     * Create a single profiled name by argument consumption
99
     *
100
     * @param array $args Arguments
101
     * @param string|boolean|null $profile Profile
102
     * @return \stdClass Profiled name
103
     */
104 15
    protected static function consumeProfiledName(&$args, &$profile)
105
    {
106 15
        $profiledName = new \stdClass();
107 15
        $profiledName->profile = $profile;
108
109
        // Get the first argument
110 15
        $arg = array_shift($args);
111
112
        // If it's an object argument
113 15
        if (is_object($arg)) {
114 6
            return self::createProfiledNameFromObject($arg, $profile);
115
        }
116
117
        // If it's an array argument
118 13
        if (is_array($arg)) {
119 2
            return self::createProfiledNameFromArray($arg, $profile);
0 ignored issues
show
Bug introduced by
It seems like $profile defined by parameter $profile on line 104 can also be of type boolean or null; however, Jkphl\Micrometa\Infrastr...ProfiledNameFromArray() does only seem to accept string, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
120
        }
121
122 11
        if (($profile === false) && is_string(current($args))) {
123 5
            $profile = array_shift($args);
124 5
        }
125 11
        return self::createProfiledNameFromString(strval($arg), $profile);
126
    }
127
128
    /**
129
     * Create a profiled name from an object argument
130
     *
131
     * @param \stdClass $arg Object argument
132
     * @param string $profile Profile
133
     * @return \stdClass Profiled name
134
     * @throws InvalidArgumentException If the name is missing
135
     */
136 7
    protected static function createProfiledNameFromObject($arg, &$profile)
137
    {
138
        // If the name is invalid
139 7
        if (!isset($arg->name)) {
140
            throw new InvalidArgumentException(
141
                InvalidArgumentException::INVALID_TYPE_PROPERTY_NAME_STR,
142
                InvalidArgumentException::INVALID_TYPE_PROPERTY_NAME
143
            );
144
        }
145
146 7
        if (isset($arg->profile)) {
147 7
            $profile = trim($arg->profile) ?: null;
148 7
        }
149
150 7
        return self::createProfiledNameFromString($arg->name, $profile);
151
    }
152
153
    /**
154
     * Create a profiled name from an array argument
155
     *
156
     * @param array $arg Array argument
157
     * @param string $profile Profile
158
     * @return \stdClass Profiled name
159
     * @throws InvalidArgumentException If the array definition is invalid
160
     */
161 2
    protected static function createProfiledNameFromArray(array $arg, &$profile)
162
    {
163
        // If it's an associative array containing a "name" key
164 2
        if (array_key_exists('name', $arg)) {
165 1
            return self::createProfiledNameFromObject((object)$arg, $profile);
166
        }
167
168
        // If the argument has two items at least
169 1
        if (count($arg) > 1) {
170 1
            $name = array_shift($arg);
171 1
            $profile = trim(array_shift($arg)) ?: null;
172 1
            return self::createProfiledNameFromString($name, $profile);
173
        }
174
175
        throw new InvalidArgumentException(
176
            InvalidArgumentException::INVALID_TYPE_PROPERTY_ARRAY_STR,
177
            InvalidArgumentException::INVALID_TYPE_PROPERTY_ARRAY
178
        );
179
    }
180
181
    /**
182
     * Create a profiled name from string arguments
183
     *
184
     * @param string $name Name
185
     * @param string|null $profile Profile
186
     * @return \stdClass Profiled name
187
     * @throws InvalidArgumentException If the name is invalid
188
     */
189 15
    protected static function createProfiledNameFromString($name, $profile)
190
    {
191
        // If the name is invalid
192 15
        if (!strlen(trim($name))) {
193
            throw new InvalidArgumentException(
194
                InvalidArgumentException::INVALID_TYPE_PROPERTY_NAME_STR,
195
                InvalidArgumentException::INVALID_TYPE_PROPERTY_NAME
196
            );
197
        }
198
199
        return (object)[
200 15
            'name' => trim($name),
201 15
            'profile' => trim($profile) ?: null,
202 15
        ];
203
    }
204
}
205