Completed
Push — master ( c6728e...bf498d )
by Raffael
14:18 queued 04:37
created

AttributeDecorator::getAttributes()   C

Complexity

Conditions 14
Paths 1

Size

Total Lines 93

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 49
CRAP Score 16.9249

Importance

Changes 0
Metric Value
dl 0
loc 93
ccs 49
cts 65
cp 0.7538
rs 5.166
c 0
b 0
f 0
cc 14
nc 1
nop 2
crap 16.9249

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-2018 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
     * @param Decorator $role_decorator
62
     */
63 6
    public function __construct(Server $server, Acl $acl, RoleAttributeDecorator $role_decorator)
64
    {
65 6
        $this->server = $server;
66 6
        $this->acl = $acl;
67 6
        $this->role_decorator = $role_decorator;
68 6
    }
69
70
    /**
71
     * Decorate attributes.
72
     */
73 6
    public function decorate(NodeInterface $node, array $attributes = []): array
74
    {
75 6
        $requested = $attributes;
76 6
        $attributes = $node->getAttributes();
77
78 6
        $attrs = array_merge(
79 6
            $this->getAttributes($node, $attributes),
80 6
            $this->getTimeAttributes($node, $attributes),
81 6
            $this->getTypeAttributes($node, $attributes),
82 6
            $this->custom
83
        );
84
85 6
        if (0 === count($requested)) {
86 2
            return $this->translateAttributes($node, $attrs);
87
        }
88
89 4
        return $this->translateAttributes($node, array_intersect_key($attrs, array_flip($requested)));
90
    }
91
92
    /**
93
     * Add decorator.
94
     *
95
     *
96
     * @return AttributeDecorator
97
     */
98 2
    public function addDecorator(string $attribute, Closure $decorator): self
99
    {
100 2
        $this->custom[$attribute] = $decorator;
101
102 2
        return $this;
103
    }
104
105
    /**
106
     * Get Attributes.
107
     *
108
     * @param NodeInterface
109
     */
110 6
    protected function getAttributes(NodeInterface $node, array $attributes): array
111
    {
112 6
        $acl = $this->acl;
113 6
        $server = $this->server;
114 6
        $fs = $this->server->getFilesystem();
115 6
        $decorator = $this->role_decorator;
116
117
        return [
118 6
            'id' => (string) $attributes['_id'],
119 6
            'name' => (string) $attributes['name'],
120 6
            'mime' => (string) $attributes['mime'],
121 6
            'readonly' => (bool) $attributes['readonly'],
122 6
            'directory' => $node instanceof Collection,
123 6
            'meta' => function ($node) {
124 2
                return (object) $node->getMetaAttributes();
125 6
            },
126 6
            'size' => function ($node) {
127 2
                return $node->getSize();
128 6
            },
129 6
            'path' => function ($node) {
130
                try {
131 2
                    return $node->getPath();
132
                } catch (\Exception $e) {
133
                    return null;
134
                }
135 6
            },
136 6
            'parent' => function ($node) {
137 2
                $parent = $node->getParent();
138
139 2
                if (null === $parent || $parent->isRoot()) {
140 2
                    return null;
141
                }
142
143
                return $this->decorate($node->getParent(), ['id', 'name', '_links']);
144 6
            },
145 6
            'access' => function ($node) use ($acl) {
146 2
                return $acl->getAclPrivilege($node);
147 6
            },
148 6
            'acl' => function ($node) use ($attributes) {
149 2
                if ($node->isShareMember() && count($attributes['acl']) > 0) {
150
                    return $node->getAcl();
151
                }
152
153 2
                return null;
154 6
            },
155 6
            'share' => function ($node) {
156 2
                if ($node->isShared() || !$node->isSpecial()) {
157 2
                    return null;
158
                }
159
160
                try {
161
                    return $this->decorate($node->getShareNode(), ['id', 'name', '_links']);
162
                } catch (\Exception $e) {
163
                    return null;
164
                }
165 6
            },
166 6
            'sharename' => function ($node) {
167 2
                if (!$node->isShared()) {
168 2
                    return null;
169
                }
170
171
                try {
172
                    return $node->getShareName();
173
                } catch (\Exception $e) {
174
                    return null;
175
                }
176 6
            },
177 6
            'shareowner' => function ($node) use ($server, $fs, $decorator) {
178 2
                if (!$node->isSpecial()) {
179 2
                    return null;
180
                }
181
182
                try {
183
                    return $decorator->decorate(
184
                        $server->getUserById($fs->findRawNode($node->getShareId())['owner']),
185
                        ['id', 'name', '_links']
186
                    );
187
                } catch (\Exception $e) {
188
                    return null;
189
                }
190 6
            },
191 6
            'owner' => function ($node) use ($server, $decorator) {
192
                try {
193 2
                    return $decorator->decorate(
194 2
                        $server->getUserById($node->getOwner()),
195
                        ['id', 'name', '_links']
196
                    );
197 2
                } catch (\Exception $e) {
198 2
                    return null;
199
                }
200 6
            },
201
        ];
202
    }
203
204
    /**
205
     * Get Attributes.
206
     *
207
     * @param NodeInterface
208
     */
209
    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...
210
    {
211
        return [
212 6
            '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...
213 2
                return $attributes['created']->toDateTime()->format('c');
214 6
            },
215 6
            '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...
216 2
                return $attributes['changed']->toDateTime()->format('c');
217 6
            },
218 6
            '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...
219 2
                if (false === $attributes['deleted']) {
220
                    return null;
221
                }
222
223 2
                return $attributes['deleted']->toDateTime()->format('c');
224 6
            },
225 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...
226 2
                if (null === $attributes['destroy']) {
227
                    return null;
228
                }
229
230 2
                return $attributes['destroy']->toDateTime()->format('c');
231 6
            },
232
        ];
233
    }
234
235
    /**
236
     * Get Attributes.
237
     *
238
     * @param NodeInterface
239
     */
240 6
    protected function getTypeAttributes(NodeInterface $node, array $attributes): array
241
    {
242 6
        $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...
243 6
        $fs = $this->server->getFilesystem();
0 ignored issues
show
Unused Code introduced by
$fs 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...
244
245 6
        if ($node instanceof File) {
246
            return [
247 4
                'version' => $attributes['version'],
248 4
                'hash' => $attributes['hash'],
249
            ];
250
        }
251
252
        return [
253 3
            'shared' => $node->isShared(),
254 3
            'reference' => $node->isReference(),
255 3
            '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...
256 1
                if (null === $attributes['filter']) {
257
                    return null;
258
                }
259
260 1
                return json_decode($attributes['filter'], true);
261 3
            },
262
        ];
263
    }
264
265
    /**
266
     * Execute closures.
267
     *
268
     * @param NodeInterface
269
     */
270 6 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...
271
    {
272 6
        foreach ($attributes as $key => &$value) {
273 6
            if ($value instanceof Closure) {
274 4
                $result = $value->call($this, $node);
275
276 4
                if (null === $result) {
277 3
                    unset($attributes[$key]);
278
                } else {
279 4
                    $value = $result;
280
                }
281 4
            } elseif ($value === null) {
282 6
                unset($attributes[$key]);
283
            }
284
        }
285
286 6
        return $attributes;
287
    }
288
}
289