StandardIndexBuilder   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 125
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 9

Importance

Changes 0
Metric Value
wmc 16
lcom 0
cbo 9
dl 0
loc 125
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
B buildIndex() 0 50 10
B buildIndexObject() 0 58 5
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