HydratorFactory::buildMultipart()   C
last analyzed

Complexity

Conditions 9
Paths 6

Size

Total Lines 53
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 27
CRAP Score 9

Importance

Changes 0
Metric Value
cc 9
eloc 29
nc 6
nop 1
dl 0
loc 53
rs 6.8963
c 0
b 0
f 0
ccs 27
cts 27
cp 1
crap 9

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * apparat-resource
5
 *
6
 * @category    Apparat
7
 * @package     Apparat\Resource
8
 * @subpackage Apparat\Resource\Domain
9
 * @author      Joschi Kuphal <[email protected]> / @jkphl
10
 * @copyright   Copyright © 2016 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 © 2016 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 Apparat\Resource\Domain\Factory;
38
39
use Apparat\Kernel\Ports\Kernel;
40
use Apparat\Resource\Domain\Model\Hydrator\AbstractMultipartHydrator;
41
use Apparat\Resource\Domain\Model\Hydrator\AbstractSinglepartHydrator;
42
use Apparat\Resource\Domain\Model\Hydrator\HydratorInterface;
43
use Apparat\Resource\Domain\Model\Hydrator\InvalidArgumentException;
44
use Apparat\Resource\Domain\Model\Part\AbstractPart;
45
46
/**
47
 * Hydrator factory
48
 *
49
 * @package     Apparat\Resource
50
 * @subpackage Apparat\Resource\Domain
51
 */
52
class HydratorFactory
53
{
54
    /**
55
     * Create a hydrator instance from a configuration array
56
     *
57
     * @param array $config Hydrator configuration
58
     * @return HydratorInterface Hydrator
59
     * @throws InvalidArgumentException If the hydrator configuration is invalid
60
     * @throws InvalidArgumentException If the hydrator model is invalid
61
     * @throws InvalidArgumentException If the hydrator model class is invalid
62
     */
63 102
    public static function build(array $config)
64
    {
65
        // If the configuration is empty
66 102
        if (!count($config)) {
67 1
            throw new InvalidArgumentException(
68 1
                'Invalid hydrator configuration',
69 1
                InvalidArgumentException::INVALID_HYDRATOR_CONFIGURATION
70
            );
71
72
            // Else if it's the short instantiation notation
73 101
        } elseif (is_string($config[0]) &&
74 101
            (new \ReflectionClass($config[0]))->isSubclassOf(AbstractSinglepartHydrator::class)
75
        ) {
76 51
            $config[0] = array(HydratorInterface::STANDARD => $config[0]);
77
78
            // Else: Make sure the content model is an array
79 50
        } elseif (!is_array($config[0]) || !count($config[0])) {
80 1
            throw new InvalidArgumentException(
81 1
                'Invalid hydrator content model',
82 1
                InvalidArgumentException::INVALID_HYDRATOR_CONTENT_MODEL
83
            );
84
        }
85
86
        // Run through all subhydrators
87 100
        foreach (array_keys($config[0]) as $subhydratorName) {
88 100
            AbstractPart::validatePartIdentifier($subhydratorName);
89
        }
90
91
        // If the content model has more than one part
92 99
        if (count($config[0]) > 1) {
93 45
            return self::buildMultipart($config);
94
        }
95
96
        // Build a single part hydrator
97 91
        return self::buildSingle($config);
98
    }
99
100
    /**
101
     * Build a multipart hydrator
102
     *
103
     * @param array $config Hydrator configuration
104
     * @return HydratorInterface Hydrator
105
     */
106 45
    protected static function buildMultipart(array $config)
107
    {
108
        // If no multipart hydrator is specified
109 45
        if (count($config) < 2) {
110 1
            throw new InvalidArgumentException(
111 1
                'A multipart hydrator must be specified',
112 1
                InvalidArgumentException::MISSING_MULTIPART_HYDRATOR
113
            );
114
115
            // Else: if the multipart hydrator is invalid
116 44
        } elseif (!strlen(trim($config[1])) ||
117 44
            !(new \ReflectionClass(trim($config[1])))->isSubclassOf(AbstractMultipartHydrator::class)
118
        ) {
119 2
            throw new InvalidArgumentException(
120 2
                sprintf('Invalid multipart hydrator class "%s"', trim($config[1])),
121 2
                InvalidArgumentException::INVALID_MULTIPART_HYDRATOR_CLASS
122
            );
123
124
            // Else: Validate the remaining hydrator arguments
125 42
        } elseif ((count($config) > 2) &&
126 21
            !call_user_func_array(
127 21
                array($config[1], 'validateParameters'),
128 42
                array_slice($config, 2)
129
            )
130
        ) {
131 1
            throw new InvalidArgumentException(
132 1
                'Invalid multipart hydrator parameters',
133 1
                InvalidArgumentException::INVALID_MULTIPART_HYDRATOR_PARAMETERS
134
            );
135
        }
136
137
        // Run through all multipart subhydrators
138 38
        foreach ($config[0] as $multipartHydrator) {
139
            // If it's neither a multipart nor a valid single part hydrator
140 38
            if (!is_array($multipartHydrator) &&
141 38
                !(new \ReflectionClass($multipartHydrator))->implementsInterface(HydratorInterface::class)
142
            ) {
143 1
                throw new InvalidArgumentException(
144
                    sprintf(
145 1
                        'Invalid multipart subhydrator class "%s"',
146
                        $multipartHydrator
147
                    ),
148 38
                    InvalidArgumentException::INVALID_MULTIPART_SUBHYDRATOR_CLASS
149
                );
150
            }
151
        }
152
153
        // Instantiate the multipart hydrator
154 37
        $multipartHydrator = trim($config[1]);
155 37
        $hydratorParameters = array_slice($config, 2);
156 37
        array_unshift($hydratorParameters, $config[0]);
157 37
        return Kernel::create($multipartHydrator, $hydratorParameters);
158
    }
159
160
    /**
161
     * Build a single part hydrator
162
     *
163
     * @param array $config Hydrator configuration
164
     * @return HydratorInterface Hydrator
165
     */
166 91
    protected static function buildSingle(array $config)
167
    {
168 91
        reset($config[0]);
169 91
        $singlepartName = trim(key($config[0]));
170 91
        $singlepartHydrator = trim(current($config[0]));
171
172
        // If it's not a valid simple part hydrator
173 91
        if (!(new \ReflectionClass($singlepartHydrator))->isSubclassOf(AbstractSinglepartHydrator::class)) {
174 1
            throw new InvalidArgumentException(
175
                sprintf(
176 1
                    'Invalid single part hydrator class "%s"',
177
                    $singlepartHydrator
178
                ),
179 1
                InvalidArgumentException::INVALID_SINGLEPART_HYDRATOR_CLASS
180
            );
181
        }
182
183
        // Instantiate the simple hydrator
184 90
        return new $singlepartHydrator($singlepartName);
185
    }
186
}
187