Failed Conditions
Push — master ( ebb1ea...d49c03 )
by Bernhard
06:05
created

PackageFileConverter::compareBindingDescriptors()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 5
ccs 2
cts 2
cp 1
rs 9.4285
cc 1
eloc 2
nc 1
nop 2
crap 1
1
<?php
2
3
/*
4
 * This file is part of the puli/manager package.
5
 *
6
 * (c) Bernhard Schussek <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Puli\Manager\Package;
13
14
use Puli\Discovery\Api\Type\BindingParameter;
15
use Puli\Discovery\Api\Type\BindingType;
16
use Puli\Discovery\Binding\ClassBinding;
17
use Puli\Discovery\Binding\ResourceBinding;
18
use Puli\Manager\Api\Discovery\BindingDescriptor;
19
use Puli\Manager\Api\Discovery\BindingTypeDescriptor;
20
use Puli\Manager\Api\Package\PackageFile;
21
use Puli\Manager\Api\Repository\PathMapping;
22
use Puli\Manager\Assert\Assert;
23
use Rhumsaa\Uuid\Uuid;
24
use stdClass;
25
use Webmozart\Json\Conversion\JsonConverter;
26
27
/**
28
 * Converts package files to JSON and back.
29
 *
30
 * @since  1.0
31
 *
32
 * @author Bernhard Schussek <[email protected]>
33
 */
34
class PackageFileConverter implements JsonConverter
35
{
36
    /**
37
     * The JSON version this converter supports.
38
     */
39
    const VERSION = '1.0';
40
41
    /**
42
     * The default order of the keys in the written package file.
43
     *
44
     * @var string[]
45
     */
46
    private static $keyOrder = array(
47
        'version',
48
        'name',
49
        'path-mappings',
50
        'bindings',
51
        'binding-types',
52
        'override',
53
        'extra',
54
    );
55
56 3
    public static function compareBindingDescriptors(BindingDescriptor $a, BindingDescriptor $b)
57
    {
58
        // Make sure that bindings are always printed in the same order
59 3
        return strcmp($a->getUuid()->toString(), $b->getUuid()->toString());
60
    }
61
62
    /**
63
     * {@inheritdoc}
64
     */
65 14 View Code Duplication
    public function toJson($packageFile, array $options = array())
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...
66
    {
67 14
        Assert::isInstanceOf($packageFile, 'Puli\Manager\Api\Package\PackageFile');
68
69 14
        $jsonData = new stdClass();
70
71 14
        $this->addPackageFileToJson($packageFile, $jsonData);
72
73
        // Sort according to key order
74 14
        $jsonArray = (array) $jsonData;
75 14
        $orderedKeys = array_intersect_key(array_flip(self::$keyOrder), $jsonArray);
76 14
        $jsonData = (object) array_replace($orderedKeys, $jsonArray);
77
78 14
        return $jsonData;
79
    }
80
81
    /**
82
     * {@inheritdoc}
83
     */
84 22
    public function fromJson($jsonData, array $options = array())
85
    {
86 22
        Assert::isInstanceOf($jsonData, 'stdClass');
87
88 22
        $packageFile = new PackageFile(null, isset($options['path']) ? $options['path'] : null);
89
90 22
        $this->addJsonToPackageFile($jsonData, $packageFile);
91
92 22
        return $packageFile;
93
    }
94
95 20
    protected function addPackageFileToJson(PackageFile $packageFile, stdClass $jsonData)
96
    {
97 20
        $mappings = $packageFile->getPathMappings();
98 20
        $bindingDescriptors = $packageFile->getBindingDescriptors();
99 20
        $typeDescriptors = $packageFile->getTypeDescriptors();
100 20
        $overrides = $packageFile->getOverriddenPackages();
101 20
        $extra = $packageFile->getExtraKeys();
102
103 20
        if (null !== $packageFile->getPackageName()) {
104 2
            $jsonData->name = $packageFile->getPackageName();
105
        }
106
107 20
        if (count($mappings) > 0) {
108 4
            $jsonData->{'path-mappings'} = new stdClass();
109
110 4
            foreach ($mappings as $mapping) {
111 4
                $puliPath = $mapping->getRepositoryPath();
112 4
                $localPaths = $mapping->getPathReferences();
113
114 4
                $jsonData->{'path-mappings'}->$puliPath = count($localPaths) > 1 ? $localPaths : reset($localPaths);
115
            }
116
        }
117
118 20
        if (count($bindingDescriptors) > 0) {
119 6
            uasort($bindingDescriptors, array(__CLASS__, 'compareBindingDescriptors'));
120
121 6
            $jsonData->bindings = new stdClass();
122
123 6
            foreach ($bindingDescriptors as $bindingDescriptor) {
124 6
                $binding = $bindingDescriptor->getBinding();
125 6
                $bindingData = new stdClass();
126 6
                $bindingData->_class = get_class($binding);
127
128
                // This needs to be moved to external classes to allow adding
129
                // custom binding classes at some point
130 6
                if ($binding instanceof ResourceBinding) {
131 6
                    $bindingData->query = $binding->getQuery();
132
133 6
                    if ('glob' !== $binding->getLanguage()) {
134 6
                        $bindingData->language = $binding->getLanguage();
135
                    }
136
                } elseif ($binding instanceof ClassBinding) {
137 3
                    $bindingData->class = $binding->getClassName();
138
                }
139
140 6
                $bindingData->type = $bindingDescriptor->getTypeName();
141
142
                // Don't include the default values of the binding type
143 6
                if ($binding->hasParameterValues(false)) {
144 1
                    $parameterData = $binding->getParameterValues(false);
145 1
                    ksort($parameterData);
146 1
                    $bindingData->parameters = (object) $parameterData;
147
                }
148
149 6
                $jsonData->bindings->{$bindingDescriptor->getUuid()->toString()} = $bindingData;
150
            }
151
        }
152
153 20
        if (count($typeDescriptors) > 0) {
154 8
            $bindingTypesData = array();
155
156 8
            foreach ($typeDescriptors as $typeDescriptor) {
157 8
                $type = $typeDescriptor->getType();
158 8
                $typeData = new stdClass();
159
160 8
                if ($typeDescriptor->getDescription()) {
161 2
                    $typeData->description = $typeDescriptor->getDescription();
162
                }
163
164 8
                if ($type->hasParameters()) {
165 6
                    $parametersData = array();
166
167 6
                    foreach ($type->getParameters() as $parameter) {
168 6
                        $parameterData = new stdClass();
169
170 6
                        if ($typeDescriptor->hasParameterDescription($parameter->getName())) {
171 3
                            $parameterData->description = $typeDescriptor->getParameterDescription($parameter->getName());
172
                        }
173
174 6
                        if ($parameter->isRequired()) {
175 1
                            $parameterData->required = true;
176
                        }
177
178 6
                        if (null !== $parameter->getDefaultValue()) {
179 3
                            $parameterData->default = $parameter->getDefaultValue();
180
                        }
181
182 6
                        $parametersData[$parameter->getName()] = $parameterData;
183
                    }
184
185 6
                    ksort($parametersData);
186
187 6
                    $typeData->parameters = (object) $parametersData;
188
                }
189
190 8
                $bindingTypesData[$type->getName()] = $typeData;
191
            }
192
193 8
            ksort($bindingTypesData);
194
195 8
            $jsonData->{'binding-types'} = (object) $bindingTypesData;
196
        }
197
198 20
        if (count($overrides) > 0) {
199 3
            $jsonData->override = count($overrides) > 1 ? $overrides : reset($overrides);
200
        }
201
202 20
        if (count($extra) > 0) {
203 2
            $jsonData->extra = (object) $extra;
204
        }
205 20
    }
206
207 38
    protected function addJsonToPackageFile(stdClass $jsonData, PackageFile $packageFile)
208
    {
209 38
        if (isset($jsonData->name)) {
210 28
            $packageFile->setPackageName($jsonData->name);
211
        }
212
213 38
        if (isset($jsonData->{'path-mappings'})) {
214 2
            foreach ($jsonData->{'path-mappings'} as $path => $relativePaths) {
215 2
                $packageFile->addPathMapping(new PathMapping($path, (array) $relativePaths));
216
            }
217
        }
218
219 38
        if (isset($jsonData->bindings)) {
220 6
            foreach ($jsonData->bindings as $uuid => $bindingData) {
221 6
                $binding = null;
0 ignored issues
show
Unused Code introduced by
$binding is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
222 6
                $class = isset($bindingData->_class)
223 4
                    ? $bindingData->_class
224 6
                    : 'Puli\Discovery\Binding\ResourceBinding';
225
226
                // Move this code to external classes to allow use of custom
227
                // bindings
228
                switch ($class) {
229 6
                    case 'Puli\Discovery\Binding\ClassBinding':
230 3
                        $binding = new ClassBinding(
231 3
                            $bindingData->class,
232 3
                            $bindingData->type,
233 3
                            isset($bindingData->parameters) ? (array) $bindingData->parameters : array(),
234 3
                            Uuid::fromString($uuid)
235
                        );
236 3
                        break;
237
                    case 'Puli\Discovery\Binding\ResourceBinding':
238 5
                        $binding = new ResourceBinding(
239 5
                            $bindingData->query,
240 5
                            $bindingData->type,
241 5
                            isset($bindingData->parameters) ? (array) $bindingData->parameters : array(),
242 5
                            isset($bindingData->language) ? $bindingData->language : 'glob',
243 5
                            Uuid::fromString($uuid)
244
                        );
245 5
                        break;
246
                    default:
247
                        continue 2;
248
                }
249
250 6
                $packageFile->addBindingDescriptor(new BindingDescriptor($binding));
251
            }
252
        }
253
254 38
        if (isset($jsonData->{'binding-types'})) {
255 3
            foreach ((array) $jsonData->{'binding-types'} as $typeName => $data) {
256 3
                $parameters = array();
257 3
                $parameterDescriptions = array();
258
259 3
                if (isset($data->parameters)) {
260 3
                    foreach ((array) $data->parameters as $parameterName => $parameterData) {
261 3
                        $required = isset($parameterData->required) ? $parameterData->required : false;
262
263 3
                        $parameters[] = new BindingParameter(
264
                            $parameterName,
265 3
                            $required ? BindingParameter::REQUIRED : BindingParameter::OPTIONAL,
266 3
                            isset($parameterData->default) ? $parameterData->default : null
267
                        );
268
269 3
                        if (isset($parameterData->description)) {
270 3
                            $parameterDescriptions[$parameterName] = $parameterData->description;
271
                        };
272
                    }
273
                }
274
275 3
                $packageFile->addTypeDescriptor(new BindingTypeDescriptor(
276 3
                    new BindingType($typeName, $parameters),
277 3
                    isset($data->description) ? $data->description : null,
278
                    $parameterDescriptions
279
                ));
280
            }
281
        }
282
283 38
        if (isset($jsonData->override)) {
284 2
            $packageFile->setOverriddenPackages((array) $jsonData->override);
285
        }
286
287 38
        if (isset($jsonData->extra)) {
288 2
            $packageFile->setExtraKeys((array) $jsonData->extra);
289
        }
290 38
    }
291
}
292