Completed
Push — master ( 630d51...b56cdf )
by Pol
02:40
created

FilesystemNode   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 108
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 36
c 3
b 0
f 0
dl 0
loc 108
ccs 39
cts 39
cp 1
rs 10
wmc 16

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 15 3
A getPath() 0 11 2
A root() 0 9 2
A contains() 0 10 3
A add() 0 29 6
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace drupol\phpvfs\Node;
6
7
use drupol\phptree\Node\AttributeNode;
8
use drupol\phptree\Node\NodeInterface;
9
use drupol\phpvfs\Utils\Path;
10
11
/**
12
 * Class Vfs.
13
 */
14
abstract class FilesystemNode extends AttributeNode implements FilesystemNodeInterface
15
{
16
    /**
17
     * FilesystemNode constructor.
18
     *
19
     * @param array $attributes
20
     * @param null|int $capacity
21
     */
22 22
    public function __construct(
23
        array $attributes = [],
24
        ?int $capacity = 0
25
    ) {
26 22
        $time = \time();
27
28
        $attributes = [
29 22
            'uid' => \function_exists('posix_getuid') ? \posix_getuid() : 0,
30 22
            'gid' => \function_exists('posix_getgid') ? \posix_getgid() : 0,
31 22
            'atime' => $time,
32 22
            'mtime' => $time,
33 22
            'ctime' => $time,
34 22
        ] + $attributes;
35
36 22
        parent::__construct($attributes, $capacity);
37 22
    }
38
39
    /**
40
     * {@inheritdoc}
41
     *
42
     * @throws \Exception
43
     *
44
     * @return \drupol\phpvfs\Node\DirectoryInterface
45
     */
46 18
    public function add(NodeInterface ...$nodes): NodeInterface
47
    {
48
        /** @var \drupol\phpvfs\Node\FilesystemNodeInterface $node */
49 18
        foreach ($nodes as $node) {
50 18
            if (!($node instanceof FilesystemNodeInterface)) {
51 1
                throw new \Exception('Invalid filesystem node type.');
52
            }
53
54 18
            $node = $node->root();
55
56 18
            if ($this->getAttribute('id') === $node->getAttribute('id')) {
57 10
                $this->add($node[0]->setParent(null));
58
59 10
                continue;
60
            }
61
62
            // If the $cwd contains the nodechild.
63 18
            if (null !== $child = $this->contains($node)) {
64 3
                if (0 !== $node->degree()) {
65 3
                    $child->add($node[0]->setParent(null));
66
                }
67
68 3
                continue;
69
            }
70
71 18
            parent::add($node->setParent(null));
72
        }
73
74 18
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type drupol\phpvfs\Node\FilesystemNode which is incompatible with the documented return type drupol\phpvfs\Node\DirectoryInterface.
Loading history...
75
    }
76
77
    /**
78
     * {@inheritdoc}
79
     */
80 1
    public function getPath(): Path
81
    {
82
        $paths = [
83 1
            $this->getAttribute('id'),
84
        ];
85
86 1
        foreach ($this->getAncestors() as $ancestor) {
87 1
            \array_unshift($paths, $ancestor->getAttribute('id'));
0 ignored issues
show
Bug introduced by
The method getAttribute() does not exist on drupol\phptree\Node\NodeInterface. It seems like you code against a sub-type of drupol\phptree\Node\NodeInterface such as drupol\phptree\Node\AttributeNode or drupol\phptree\Node\AttributeNodeInterface or drupol\phptree\Node\AttributeNode. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

87
            \array_unshift($paths, $ancestor->/** @scrutinizer ignore-call */ getAttribute('id'));
Loading history...
88
        }
89
90 1
        return Path::fromString(\str_replace('//', '/', \implode('/', $paths)));
91
    }
92
93
    /**
94
     * {@inheritdoc}
95
     */
96 19
    public function root(): FilesystemNodeInterface
97
    {
98 19
        $root = $this;
99
100 19
        foreach ($this->getAncestors() as $ancestor) {
101 16
            $root = $ancestor;
102
        }
103
104 19
        return $root;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $root could return the type drupol\phptree\Node\NodeInterface which includes types incompatible with the type-hinted return drupol\phpvfs\Node\FilesystemNodeInterface. Consider adding an additional type-check to rule them out.
Loading history...
105
    }
106
107
    /**
108
     * @param \drupol\phpvfs\Node\FilesystemNodeInterface $node
109
     *
110
     * @return null|\drupol\phpvfs\Node\FilesystemNodeInterface
111
     */
112 18
    protected function contains(FilesystemNodeInterface $node): ?FilesystemNodeInterface
113
    {
114
        /** @var \drupol\phpvfs\Node\FilesystemNodeInterface $child */
115 18
        foreach ($this->children() as $child) {
116 4
            if ($node->getAttribute('id') === $child->getAttribute('id')) {
0 ignored issues
show
Bug introduced by
The method getAttribute() does not exist on ArrayObject. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

116
            if ($node->getAttribute('id') === $child->/** @scrutinizer ignore-call */ getAttribute('id')) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
117 4
                return $child;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $child returns the type ArrayObject which is incompatible with the type-hinted return drupol\phpvfs\Node\FilesystemNodeInterface|null.
Loading history...
118
            }
119
        }
120
121 18
        return null;
122
    }
123
}
124