Completed
Push — master ( 827100...0aed89 )
by Vladimir
02:24
created

TrackingManager::isHandled()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
eloc 5
nc 3
nop 1
dl 0
loc 12
rs 9.4285
c 0
b 0
f 0
ccs 0
cts 7
cp 0
crap 12
1
<?php
2
3
/**
4
 * @copyright 2016 Vladimir Jimenez
5
 * @license   https://github.com/allejo/stakx/blob/master/LICENSE.md MIT
6
 */
7
8
namespace allejo\stakx\Manager;
9
10
use allejo\stakx\Object\FrontMatterObject;
11
use Symfony\Component\Finder\Finder;
12
use Symfony\Component\Finder\SplFileInfo;
13
14
/**
15
 * Class TrackingManager
16
 *
17
 * @package allejo\stakx\Manager
18
 */
19
abstract class TrackingManager extends BaseManager
20
{
21
    /**
22
     * An array corresponding with $folderDefinitions to store metadata regarding a specificc folder
23
     *
24
     * $folderDefinitionsOption['<folder path>'] = array()
25
     *
26
     * @var string[]
27
     */
28
    protected $folderDefinitionsOptions;
29
30
    /**
31
     * An array of folders which tracked items are stored in
32
     *
33
     * $folderDefinitions[] = '<folder path>'
34
     *
35
     * @var string[]
36
     */
37
    protected $folderDefinitions;
38
39
    /**
40
     * The storage which contains the same information as $trackedItems but organized by relative file path instead of a
41
     * namespace or file name without extension.
42
     *
43
     * $trackedItemsOptions['<relative file path>'] = mixed
44
     *
45
     * @var array
46
     */
47
    protected $trackedItemsFlattened;
48
49
    /**
50
     * The storage used to cache any information needed for a specific FrontMatterObject or DataItem.
51
     *
52
     * For example, with a DataItem, which is just an array, the file path to the original file can be stored in this
53
     * array to be accessible in the future to refresh the contents without parsing all of the files again.
54
     *
55
     * $trackedItemsOptions['<relative file path>'] = array
56
     *
57
     * @var array
58
     */
59
    protected $trackedItemsOptions;
60
61
    /**
62
     * The storage used for either FrontMatterObjects or DataItems in the respective static classes
63
     *
64
     * $trackedItems['<namespace>']['<file name w/o extension>'] = mixed
65
     * $trackedItems['<file name w/o extension>'] = mixed
66
     *
67
     * @var array
68
     */
69
    protected $trackedItems;
70
71
    /**
72
     * Set to true when file tracking is enabled
73
     *
74
     * @var bool
75
     */
76
    protected $tracking;
77
78 4
    public function __construct()
79
    {
80 4
        parent::__construct();
81
82 4
        $this->folderDefinitionsOptions = array();
83 4
        $this->folderDefinitions = array();
84 4
        $this->trackedItemsFlattened = array();
85 4
        $this->trackedItemsOptions = array();
86 4
        $this->trackedItems = array();
87 4
        $this->tracking = false;
88 4
    }
89
90
    /**
91
     * Save data to the tracker with a reference to the file it came from
92
     *
93
     * @param string      $key       The name of the file
94
     * @param mixed       $data      The data to save the
95
     * @param string      $filePath  The relative file path from the root of the website
96
     * @param string|null $namespace The name of the collection this data belongs to, if any
97
     */
98 4
    public function addArrayToTracker ($key, $data, $filePath, $namespace = null)
99
    {
100 4
        if (is_null($namespace))
101 4
        {
102
            $this->trackedItems[$key] = $data;
103
            $this->trackedItemsFlattened[$filePath] = &$this->trackedItems[$key];
104
        }
105
        else
106
        {
107 4
            $this->trackedItems[$namespace][$key] = $data;
108 4
            $this->trackedItemsFlattened[$filePath] = &$this->trackedItems[$namespace][$key];
109
        }
110 4
    }
111
112
    /**
113
     * Add a FrontMatterObject based object to the tracker
114
     *
115
     * @param FrontMatterObject $trackedItem
116
     * @param string            $key
117
     * @param string|null       $namespace
118
     */
119 4
    public function addObjectToTracker ($trackedItem, $key, $namespace = null)
120
    {
121 4
        if (!($trackedItem instanceof FrontMatterObject))
122 4
        {
123
            throw new \InvalidArgumentException('Only objects can be added to the tracker');
124
        }
125
126 4
        $this->addArrayToTracker($key, $trackedItem, $trackedItem->getRelativeFilePath(), $namespace);
127 4
    }
128
129
    /**
130
     * Remove all data related to an array that was saved
131
     *
132
     * @param string      $key
133
     * @param string      $filePath
134
     * @param string|null $namespace
135
     */
136
    public function delArrayFromTracker($key, $filePath, $namespace = null)
137
    {
138
        if (is_null($namespace))
139
        {
140
            unset($this->trackedItems[$key]);
141
        }
142
        else
143
        {
144
            unset($this->trackedItems[$namespace][$key]);
145
        }
146
147
        unset($this->trackedItemsFlattened[$filePath]);
148
    }
149
150
    /**
151
     * Remove an entry from the tracked items array
152
     *
153
     * @param mixed       $trackedItem
154
     * @param string|null $namespace
155
     */
156
    public function delObjectFromTracker ($trackedItem, $namespace = null)
157
    {
158
        $this->delArrayFromTracker(
159
            $trackedItem->getFileName(),
160
            $trackedItem->getRelativeFilePath(),
161
            $namespace
162
        );
163
    }
164
165
    /**
166
     * Whether or not to enable tracking of files.
167
     *
168
     * Setting this to false will disable a lot of the overhead and caching done when a project is being watched
169
     *
170
     * @param bool $enabled
171
     */
172
    public function enableTracking ($enabled)
173
    {
174
        $this->tracking = $enabled;
175
    }
176
177
    /**
178
     * Check to see if the file belongs inside of one the folders being tracked by this manager
179
     *
180
     * @param  string $filePath
181
     *
182
     * @return bool True if the file is inside a tracked folder
183
     */
184
    public function isHandled ($filePath)
185
    {
186
        foreach ($this->folderDefinitions as $folder)
187
        {
188
            if (substr($filePath, 0, strlen($folder)) === $folder)
189
            {
190
                return true;
191
            }
192
        }
193
194
        return false;
195
    }
196
197
    /**
198
     * Check whether a file is tracked
199
     *
200
     * @param  string $filePath The relative path of the file
201
     *
202
     * @return bool
203
     */
204 1
    public function isTracked ($filePath)
205
    {
206 1
        return array_key_exists($filePath, $this->trackedItemsFlattened);
207
    }
208
209
    /**
210
     * @param SplFileInfo|string $filePath
211
     */
212
    public function createNewItem ($filePath)
213
    {
214
        $this->handleTrackableItem($filePath);
0 ignored issues
show
Bug introduced by
It seems like $filePath defined by parameter $filePath on line 212 can also be of type string; however, allejo\stakx\Manager\Tra...::handleTrackableItem() does only seem to accept object<Symfony\Component\Finder\SplFileInfo>, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
215
    }
216
217
    /**
218
     * Update the contents of a specified file
219
     *
220
     * @param SplFileInfo|string $filePath The relative path of the file
221
     *
222
     * @return mixed|null
223
     */
224
    public function refreshItem ($filePath)
225
    {
226
        return $this->handleTrackableItem(
227
            $filePath,
0 ignored issues
show
Bug introduced by
It seems like $filePath defined by parameter $filePath on line 224 can also be of type string; however, allejo\stakx\Manager\Tra...::handleTrackableItem() does only seem to accept object<Symfony\Component\Finder\SplFileInfo>, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
228
            $this->trackedItemsOptions[$filePath]
229
        );
230
    }
231
232
    /**
233
     * Save a folder that is tracked by this manager and its respective options
234
     *
235
     * @param string $folderPath
236
     * @param array  $options
237
     */
238
    public function saveFolderDefinition ($folderPath, $options = array())
239
    {
240
        $this->folderDefinitions[] = $folderPath;
241
        $this->folderDefinitionsOptions[$folderPath] = $options;
242
    }
243
244
    /**
245
     * Save any options related to an item needed in order to refresh the content
246
     *
247
     * @param string $filePath
248
     * @param array $options
249
     */
250
    public function saveTrackerOptions ($filePath, $options = array())
251
    {
252
        $this->trackedItemsOptions[$filePath] = $options;
253
    }
254
255
    /**
256
     * Parse the specified folder for items to track
257
     *
258
     * @param Finder|string $pathOrFinder
259
     * @param mixed  $options  Special options that will be passed to the static::parseTrackableItem() implementation
260
     * @param array  $includes
261
     * @param array  $excludes
262
     */
263 4
    protected function scanTrackableItems ($pathOrFinder, $options = array(), $includes = array(), $excludes = array())
264
    {
265 4
        if ($pathOrFinder instanceof Finder)
266 4
        {
267
            $finder = $pathOrFinder;
268
        }
269
        else
270
        {
271 4
            $finder = $this->fs->getFinder(
272 4
                $includes,
273 4
                $excludes,
274 4
                $this->fs->absolutePath($pathOrFinder)
275 4
            );
276
        }
277
278
        /** @var SplFileInfo $file */
279 4
        foreach ($finder as $file)
280
        {
281 4
            $this->handleTrackableItem($file, $options);
282 4
        }
283 4
    }
284
285
    /**
286
     * @param  SplFileInfo $filePath
287
     * @param  mixed       $options
288
     *
289
     * @return mixed|null
290
     */
291
    abstract protected function handleTrackableItem ($filePath, $options = array());
292
}