StandardIndexBuilder::buildIndex()   B
last analyzed

Complexity

Conditions 10
Paths 21

Size

Total Lines 50

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 50
rs 7.2242
c 0
b 0
f 0
cc 10
nc 21
nop 2

How to fix   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
namespace Storeman\IndexBuilder;
4
5
use Psr\Log\LoggerAwareInterface;
6
use Psr\Log\LoggerAwareTrait;
7
use Psr\Log\NullLogger;
8
use Storeman\FilesystemUtility;
9
use Storeman\Hash\HashContainer;
10
use Storeman\Index\Index;
11
use Storeman\Index\IndexObject;
12
use Symfony\Component\Finder\Finder;
13
use Symfony\Component\Finder\SplFileInfo;
14
15
class StandardIndexBuilder implements IndexBuilderInterface, LoggerAwareInterface
16
{
17
    use LoggerAwareTrait;
18
19
    public function __construct()
20
    {
21
        $this->logger = new NullLogger();
22
    }
23
24
    /**
25
     * {@inheritdoc}
26
     */
27
    public function buildIndex(string $path, array $excludedPathsRegexp = []): Index
28
    {
29
        $this->logger->info(sprintf("Building index using %s for path '%s' (excluded: %s)...", static::class, $path, implode(',', $excludedPathsRegexp) ?: '-'));
30
31
        if (!file_exists($path))
32
        {
33
            throw new \InvalidArgumentException("Given path '{$path}' does not exist.");
34
        }
35
        elseif (!is_dir($path))
36
        {
37
            throw new \InvalidArgumentException("Given path '{$path}' is not a directory.");
38
        }
39
        elseif (!is_readable($path))
40
        {
41
            throw new \InvalidArgumentException("Given directory '{$path}' is not readable.'");
42
        }
43
44
        $finder = new Finder();
45
        $finder->in($path);
46
        $finder->ignoreDotFiles(false);
47
48
        foreach ($excludedPathsRegexp as $excludedPathRegexp)
49
        {
50
            $finder->notPath($excludedPathRegexp);
51
        }
52
53
        $index = new Index();
54
55
        foreach ($finder->directories() as $fileInfo)
56
        {
57
            /** @var SplFileInfo $fileInfo */
58
59
            if ($indexObject = $this->buildIndexObject($path, $fileInfo->getRelativePathname()))
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $indexObject is correct as $this->buildIndexObject(...>getRelativePathname()) (which targets Storeman\IndexBuilder\St...der::buildIndexObject()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
60
            {
61
                $index->addObject($indexObject);
62
            }
63
        }
64
65
        foreach ($finder->files() as $fileInfo)
66
        {
67
            /** @var SplFileInfo $fileInfo */
68
69
            if ($indexObject = $this->buildIndexObject($path, $fileInfo->getRelativePathname()))
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $indexObject is correct as $this->buildIndexObject(...>getRelativePathname()) (which targets Storeman\IndexBuilder\St...der::buildIndexObject()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
70
            {
71
                $index->addObject($indexObject);
72
            }
73
        }
74
75
        return $index;
76
    }
77
78
    /**
79
     * {@inheritdoc}
80
     */
81
    public function buildIndexObject(string $basePath, string $relativePath): ?IndexObject
82
    {
83
        $absolutePath = rtrim($basePath, '/') . '/' . $relativePath;
84
85
        $stat = FilesystemUtility::lstat($absolutePath);
86
87
        $size = $linkTarget = $hashContainer = null;
88
89
        switch ($stat['mode'] & 0xF000)
90
        {
91
            case 0x4000:
92
93
                $type = IndexObject::TYPE_DIR;
94
95
                break;
96
97
            case 0x8000:
98
99
                $type = IndexObject::TYPE_FILE;
100
                $size = $stat['size'];
101
                $hashContainer = new HashContainer();
102
103
                break;
104
105
            case 0xA000:
106
107
                $type = IndexObject::TYPE_LINK;
108
                $linkTarget = readlink($absolutePath);
109
110
                if ($linkTarget === false)
111
                {
112
                    $this->logger->notice("Found broken link: {$absolutePath}");
113
114
                    // silently ignore broken links
115
                    return null;
116
                }
117
118
                break;
119
120
            default:
121
122
                // sockets, pipes, etc.
123
                return null;
124
        }
125
126
        return new IndexObject(
127
            $relativePath,
128
            $type,
129
            $stat['mtime'],
130
            $stat['ctime'],
131
            $stat['mode'] & 0777,
132
            $size,
133
            $stat['ino'],
134
            $linkTarget,
135
            null,
136
            $hashContainer
137
        );
138
    }
139
}
140