Completed
Push — master ( 37faaa...541bbf )
by Raffael
10:18 queued 06:30
created

AttributeDecorator::getAttributes()   C

Complexity

Conditions 14
Paths 1

Size

Total Lines 111

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 50
CRAP Score 22.4467

Importance

Changes 0
Metric Value
dl 0
loc 111
ccs 50
cts 77
cp 0.6494
rs 5.0133
c 0
b 0
f 0
cc 14
crap 22.4467
nc 1
nop 2

How to fix   Long Method    Complexity   

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
declare(strict_types=1);
4
5
/**
6
 * balloon
7
 *
8
 * @copyright   Copryright (c) 2012-2019 gyselroth GmbH (https://gyselroth.com)
9
 * @license     GPL-3.0 https://opensource.org/licenses/GPL-3.0
10
 */
11
12
namespace Balloon\Filesystem\Node;
13
14
use Balloon\AttributeDecorator\AttributeDecoratorInterface;
15
use Balloon\Filesystem;
16
use Balloon\Filesystem\Acl;
17
use Balloon\Server;
18
use Balloon\Server\AttributeDecorator as RoleAttributeDecorator;
19
use Closure;
20
21
class AttributeDecorator implements AttributeDecoratorInterface
22
{
23
    /**
24
     * Server.
25
     *
26
     * @var Server
27
     */
28
    protected $server;
29
30
    /**
31
     * Filesystem.
32
     *
33
     * @var Filesystem
34
     */
35
    protected $fs;
36
37
    /**
38
     * Acl.
39
     *
40
     * @var Acl
41
     */
42
    protected $acl;
43
44
    /**
45
     * Role decorator.
46
     *
47
     * @var RoleAttributeDecorator
48
     */
49
    protected $role_decorator;
50
51
    /**
52
     * Custom attributes.
53
     *
54
     * @var array
55
     */
56
    protected $custom = [];
57
58
    /**
59
     * Init.
60
     */
61 6
    public function __construct(Server $server, Acl $acl, RoleAttributeDecorator $role_decorator)
62
    {
63 6
        $this->server = $server;
64 6
        $this->acl = $acl;
65 6
        $this->role_decorator = $role_decorator;
66 6
    }
67
68
    /**
69
     * Decorate attributes.
70
     */
71 6
    public function decorate(NodeInterface $node, array $attributes = []): array
72
    {
73 6
        $requested = $attributes;
74 6
        $attributes = $node->getAttributes();
75
76 6
        $attrs = array_merge(
77 6
            $this->getAttributes($node, $attributes),
78 6
            $this->getTimeAttributes($node, $attributes),
79 6
            $this->getTypeAttributes($node, $attributes),
80 6
            $this->custom
81
        );
82
83 6
        if (0 === count($requested)) {
84 2
            return $this->translateAttributes($node, $attrs);
85
        }
86
87 4
        return $this->translateAttributes($node, array_intersect_key($attrs, array_flip($requested)));
88
    }
89
90
    /**
91
     * Add decorator.
92
     */
93 2
    public function addDecorator(string $attribute, Closure $decorator): self
94
    {
95 2
        $this->custom[$attribute] = $decorator;
96
97 2
        return $this;
98
    }
99
100
    /**
101
     * Get Attributes.
102
     */
103 6
    protected function getAttributes(NodeInterface $node, array $attributes): array
104
    {
105 6
        $acl = $this->acl;
106 6
        $server = $this->server;
107 6
        $fs = $this->server->getFilesystem();
108 6
        $decorator = $this->role_decorator;
109
110
        return [
111 6
            'id' => (string) $attributes['_id'],
112 6
            'name' => (string) $attributes['name'],
113 6
            'mime' => (string) $attributes['mime'],
114 6
            'readonly' => (bool) $attributes['readonly'],
115 6
            'directory' => $node instanceof Collection,
116 6
            'meta' => function ($node) {
117 2
                return (object) $node->getMetaAttributes();
118 6
            },
119 6
            'size' => function ($node) {
120 2
                return $node->getSize();
121 6
            },
122 6
            'path' => function ($node) {
123
                try {
124 2
                    return $node->getPath();
125
                } catch (\Exception $e) {
126
                    return null;
127
                }
128 6
            },
129 6
            'parent' => function ($node) {
130 2
                $parent = $node->getParent();
131
132 2
                if (null === $parent || $parent->isRoot()) {
133 2
                    return null;
134
                }
135
136
                return $this->decorate($node->getParent(), ['id', 'name', '_links']);
137 6
            },
138 6
            'access' => function ($node) use ($acl) {
139 2
                return $acl->getAclPrivilege($node);
140 6
            },
141 6
            'lock' => function ($node) use ($server, $decorator, $attributes) {
142 2
                if (!$node->isLocked()) {
143
                    return null;
144
                }
145
146 2
                $lock = $attributes['lock'];
147 6
148 6
                try {
149 2
                    $user = $decorator->decorate(
150 2
                        $server->getUserById($lock['owner']),
151
                        ['id', 'name', '_links']
152
                    );
153
                } catch (\Exception $e) {
154
                    $user = null;
155
                }
156
157
                $lock = $attributes['lock'];
158
159
                return [
160
                    'owner' => $user,
161
                    'created' => $lock['created']->toDateTime()->format('c'),
162
                    'expire' => $lock['expire']->toDateTime()->format('c'),
163
                    'id' => $lock['id'],
164
                ];
165
            },
166
            'share' => function ($node) use ($fs) {
167
                if ($node->isShared() || !$node->isSpecial()) {
168
                    return null;
169
                }
170
171
                try {
172 6
                    return $this->decorate($fs->findNodeById($node->getShareId(true)), ['id', 'name', '_links']);
173 6
                } catch (\Exception $e) {
174 2
                    return null;
175 2
                }
176
            },
177
            'sharename' => function ($node) {
178
                if (!$node->isShared()) {
179
                    return null;
180
                }
181
182
                try {
183 6
                    return $node->getShareName();
184 6
                } catch (\Exception $e) {
185 2
                    return null;
186 2
                }
187
            },
188
            'shareowner' => function ($node) use ($server, $fs, $decorator) {
189
                if (!$node->isSpecial()) {
190
                    return null;
191
                }
192
193
                try {
194 6
                    return $decorator->decorate(
195 6
                        $server->getUserById($fs->findRawNode($node->getShareId())['owner']),
196 2
                        ['id', 'name', '_links']
197 2
                    );
198
                } catch (\Exception $e) {
199
                    return null;
200
                }
201
            },
202
            'owner' => function ($node) use ($server, $decorator) {
203
                try {
204
                    return $decorator->decorate(
205
                        $server->getUserById($node->getOwner()),
206
                        ['id', 'name', '_links']
207
                    );
208 6
                } catch (\Exception $e) {
209 6
                    return null;
210
                }
211 2
            },
212 2
        ];
213
    }
214
215 2
    /**
216 2
     * Get Attributes.
217
     *
218 6
     * @param NodeInterface
219
     */
220
    protected function getTimeAttributes(NodeInterface $node, array $attributes): array
0 ignored issues
show
Unused Code introduced by
The parameter $node is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
221
    {
222
        return [
223
            'created' => function ($node) use ($attributes) {
0 ignored issues
show
Unused Code introduced by
The parameter $node is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
224
                return $attributes['created']->toDateTime()->format('c');
225
            },
226
            'changed' => function ($node) use ($attributes) {
0 ignored issues
show
Unused Code introduced by
The parameter $node is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
227
                return $attributes['changed']->toDateTime()->format('c');
228
            },
229
            'deleted' => function ($node) use ($attributes) {
0 ignored issues
show
Unused Code introduced by
The parameter $node is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
230 6
                if (false === $attributes['deleted']) {
231 2
                    return null;
232 6
                }
233 6
234 2
                return $attributes['deleted']->toDateTime()->format('c');
235 6
            },
236 6
            'destroy' => function ($node) use ($attributes) {
0 ignored issues
show
Unused Code introduced by
The parameter $node is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
237 2
                if (null === $attributes['destroy']) {
238
                    return null;
239
                }
240
241 2
                return $attributes['destroy']->toDateTime()->format('c');
242 6
            },
243 6
        ];
244 2
    }
245
246
    /**
247
     * Get Attributes.
248 2
     */
249 6
    protected function getTypeAttributes(NodeInterface $node, array $attributes): array
250
    {
251
        $server = $this->server;
0 ignored issues
show
Unused Code introduced by
$server 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...
252
        $fs = $this->server->getFilesystem();
253
254
        if ($node instanceof File) {
255
            return [
256 6
                'version' => $attributes['version'],
257
                'hash' => $attributes['hash'],
258 6
            ];
259 6
        }
260
261 6
        return [
262
            'shared' => $node->isShared(),
263 4
            'reference' => $node->isReference(),
264 4
            'filter' => function ($node) use ($attributes) {
0 ignored issues
show
Unused Code introduced by
The parameter $node is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
265
                if (null === $attributes['filter']) {
266
                    return null;
267
                }
268
269 3
                return json_decode($attributes['filter'], true, 512, JSON_THROW_ON_ERROR);
270 3
            },
271 3
            'mount' => function ($node) use ($fs, $attributes) {
272 1
                $mount = $node->getAttributes()['mount'];
273
274
                if (!$node->isMounted() && !$node->isReference()) {
275
                    return null;
276 1
                }
277 3
278 3
                if ($node->isReference()) {
279
                    $attributes = $fs->findRawNode($node->getShareId());
0 ignored issues
show
Bug introduced by
Consider using a different name than the imported variable $attributes, or did you forget to import by reference?

It seems like you are assigning to a variable which was imported through a use statement which was not imported by reference.

For clarity, we suggest to use a different name or import by reference depending on whether you would like to have the change visibile in outer-scope.

Change not visible in outer-scope

$x = 1;
$callable = function() use ($x) {
    $x = 2; // Not visible in outer scope. If you would like this, how
            // about using a different variable name than $x?
};

$callable();
var_dump($x); // integer(1)

Change visible in outer-scope

$x = 1;
$callable = function() use (&$x) {
    $x = 2;
};

$callable();
var_dump($x); // integer(2)
Loading history...
280
                    if (isset($attributes['mount']) && count($attributes['mount']) > 0) {
281
                        $mount = $attributes['mount'];
282
                        unset($mount['username'], $mount['password']);
283
284
                        return $mount;
285
                    }
286
287
                    return null;
288
                }
289
290
                if (!empty($mount['password'])) {
291
                    unset($mount['password']);
292
                    $mount['has_password'] = true;
293
                }
294
295
                return $mount;
296
            },
297
        ];
298
    }
299
300
    /**
301
     * Execute closures.
302
     */
303 3 View Code Duplication
    protected function translateAttributes(NodeInterface $node, array $attributes): 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...
304
    {
305
        foreach ($attributes as $key => &$value) {
306
            if ($value instanceof Closure) {
307
                $result = $value->call($this, $node);
308
309
                if (null === $result) {
310 6
                    unset($attributes[$key]);
311
                } else {
312 6
                    $value = $result;
313 6
                }
314 4
            } elseif ($value === null) {
315
                unset($attributes[$key]);
316 4
            }
317 3
        }
318
319 3
        return $attributes;
320
    }
321
}
322