Completed
Branch 1.2 (bd6c12)
by Johnny
03:57
created

ScanService::addExclude()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 9
rs 9.6666
ccs 0
cts 7
cp 0
cc 2
eloc 6
nc 2
nop 1
crap 6
1
<?php
2
namespace Redbox\Scan;
3
4
/**
5
 * The ScanService indexes of scans the filesystem for changes. If there are
6
 * any changes since the last index() then scan() will notify you about any changes
7
 * made to the file system (Changes or added files).
8
 *
9
 * @package Redbox\Scan
10
 */
11
class ScanService
12
{
13
    /**
14
     * @var Adapter\AdapterInterface $adapter ;
15
     */
16
    protected $adapter;
17
18
    /**
19
     * @var array
20
     */
21
    protected $exclude;
22
23
    /**
24
     * ScanService constructor.
25
     * @param Adapter\AdapterInterface|null $adapter
26
     */
27 40
    public function __construct(Adapter\AdapterInterface $adapter = null)
28
    {
29 40
        if ($adapter) {
30 28
            $this->adapter = $adapter;
31 14
        }
32
33 40
        $this->exclude = array();
34 40
    }
35
36
    /**
37
     * Exclude a directory from being scanned or indexed.
38
     *
39
     * @param $arg
40
     * @return $this
41
     */
42
    public function addExclude($arg)
43
    {
44
        if (is_array($arg) == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
45
            $this->addManyExcludes($arg);
46
        }
47
        $this->exclude[] = $arg;
48
        print_r($this->exclude);
49
        return $this;
50
    }
51
52
    /**
53
     * Exclude a whole range of directories to skip while
54
     * scanning or indexing the filesystem.
55
     *
56
     * @param array $args
57
     * @return $this
58
     */
59
    public function addManyExcludes(array $args = array())
60
    {
61
        foreach ($args as $dir) {
62
            $this->addExclude($dir);
63
        }
64
        return $this;
65
    }
66
67
    /**
68
     * Return the adapter, this could any kind of adapter.
69
     *
70
     * @return Adapter\AdapterInterface
71
     */
72 36
    public function getAdapter()
73
    {
74 36
        return $this->adapter;
75
    }
76
77
    /**
78
     * Index the filesystem based on the given $path. The results will the stored
79
     * via the given adapter.
80
     *
81
     * @param string $path
82
     * @param string $name
83
     * @param string $date
84
     * @param Adapter\AdapterInterface|null $adapter
85
     * @return bool|Report\Report
86
     */
87 24
    public function index($path = "", $name = "", $date = "", Adapter\AdapterInterface $adapter = null)
88
    {
89 24
        if (!$adapter) {
90 20
            if (!$this->getAdapter()) {
91 4
                throw new Exception\RuntimeException('An Adapter must been set before calling index()');
92
            }
93 16
            $adapter = $this->getAdapter();
94 8
        }
95
96
        /**
97
         * Start building a basic report
98
         */
99 20
        $report = new Report\Report();
100 20
        $report->setName(($name) ? $name : 'a scan'); // FIXME
101 20
        $report->setDate(($date) ? $date : 'a date'); // FIXME
102 20
        $report->setPath($path);
103
104 20
        $activePath = $path;
105 20
        $items = array();
106
107 20
        $objects = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path), \RecursiveIteratorIterator::SELF_FIRST);
108
109
        /** @var \SplFileInfo $object */
110 20
        foreach ($objects as $object) {
111
112 20
            $filename = $object->getFilename();
113
114 20
            if ($filename == '.' || $filename == '..') {
115 20
                continue;
116
            }
117
118 20
            $pathname = $object->getPathname();
119 20
            $realpath = $object->getRealPath();
120
121 20
            if ($object->isDir()) {
122 12
                $activePath = $pathname;
123 12
                $items[$activePath] = array();
124 6
            } else {
125 20
                if (isset($items[$activePath]) == true)
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
126 20
                $items[$activePath][$pathname] = Filesystem\FileInfo::getFileHash($realpath);
127
            }
128 10
        }
129
130 20
        $report->setItems($items);
131 20
        if ($adapter->write($report) === false) {
132 8
            return false;
133
        }
134 12
        return $report;
135
    }
136
137
    /**
138
     * Scan() will scan the file system based on reports given by the adapter.
139
     * There should be a report from the history to call this function.
140
     *
141
     * @param Adapter\AdapterInterface|null $adapter
142
     * @return bool|mixed|Report\Report
143
     */
144 20
    public function scan(Adapter\AdapterInterface $adapter = null)
145
    {
146 20
        if (!$adapter) {
147 20
            if (!$this->getAdapter()) {
148 4
                throw new Exception\RuntimeException('An Adapter must been set before calling scan()');
149
            }
150 16
            $adapter = $this->getAdapter();
151 8
        }
152
153 16
        $report = $adapter->read();
154
155 16
        if ($report === false)
156 10
            return false;
157
158 12
        $items = $report->getItems();
159 12
        $report->setDate(new \DateTime());
160
161 12
        $new = array();
162 12
        $modified = array();
163
164 12
        if (count($items) > 0) {
165 4
            foreach ($items as $path => $files) {
166 4
                $objects = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path), \RecursiveIteratorIterator::SELF_FIRST);
167 4
                foreach ($objects as $object) {
168 4
                    $pathname = $object->getPathname();
169 4
                    $realpath = $object->getRealPath();
170
171 4
                    if ($object->isFile() && isset($files[$pathname])) {
172 4
                        if ($files[$pathname] != Filesystem\FileInfo::getFileHash($realpath)) {
173 2
                            $modified[] = $object;
174
                        }
175 4
                    } elseif ($object->isFile() && !isset($files[$pathname])) {
176 4
                        $new[] = $object;
177 2
                    }
178 2
                }
179 2
            }
180 2
        }
181 12
        $report->setModifiedFiles($modified);
182 12
        $report->setNewfiles($new);
183 12
        return $report;
184
    }
185
}