Completed
Pull Request — master (#41)
by Vladimir
02:46
created

TrackingManager::addObjectToTracker()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2.032

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 3
dl 0
loc 9
ccs 4
cts 5
cp 0.8
crap 2.032
rs 9.6666
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * @copyright 2017 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 allejo\stakx\System\FileExplorer;
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
     * @var FileExplorer
23
     */
24
    protected $fileExplorer;
25
26
    /**
27
     * An array corresponding with $folderDefinitions to store metadata regarding a specificc folder
28
     *
29
     * $folderDefinitionsOption['<folder path>'] = array()
30
     *
31
     * @var string[]
32
     */
33
    protected $folderDefinitionsOptions;
34
35
    /**
36
     * An array of folders which tracked items are stored in
37
     *
38
     * $folderDefinitions[] = '<folder path>'
39
     *
40
     * @var string[]
41
     */
42
    protected $folderDefinitions;
43
44
    /**
45
     * The storage which contains the same information as $trackedItems but organized by relative file path instead of a
46
     * namespace or file name without extension.
47
     *
48
     * $trackedItemsOptions['<relative file path>'] = mixed
49
     *
50
     * @var array
51
     */
52
    protected $trackedItemsFlattened;
53
54
    /**
55
     * The storage used to cache any information needed for a specific FrontMatterObject or DataItem.
56
     *
57
     * For example, with a DataItem, which is just an array, the file path to the original file can be stored in this
58
     * array to be accessible in the future to refresh the contents without parsing all of the files again.
59
     *
60
     * $trackedItemsOptions['<relative file path>'] = array
61
     *
62
     * @var array
63
     */
64
    protected $trackedItemsOptions;
65
66
    /**
67
     * The storage used for either FrontMatterObjects or DataItems in the respective static classes
68
     *
69
     * $trackedItems['<namespace>']['<file name w/o extension>'] = mixed
70
     * $trackedItems['<file name w/o extension>'] = mixed
71
     *
72
     * @var array
73
     */
74
    protected $trackedItems;
75
76
    /**
77
     * Set to true when file tracking is enabled
78
     *
79
     * @var bool
80
     */
81
    protected $tracking;
82
83 30
    public function __construct()
84
    {
85 30
        parent::__construct();
86
87 30
        $this->folderDefinitionsOptions = array();
88 30
        $this->folderDefinitions = array();
89 30
        $this->trackedItemsFlattened = array();
90 30
        $this->trackedItemsOptions = array();
91 30
        $this->trackedItems = array();
92 30
        $this->tracking = false;
93 30
    }
94
95
    /**
96
     * Whether or not to enable tracking of files.
97
     *
98
     * Setting this to false will disable a lot of the overhead and caching done when a project is being watched
99
     *
100
     * @param bool $enabled
101
     */
102
    public function enableTracking ($enabled)
103
    {
104
        $this->tracking = $enabled;
105
    }
106
107
    /**
108
     * Check to see if the file belongs inside of one the folders being tracked by this manager
109
     *
110
     * @param  string $filePath
111
     *
112
     * @return bool True if the file is inside a tracked folder
113
     */
114
    public function isHandled ($filePath)
115
    {
116
        foreach ($this->folderDefinitions as $folder)
117
        {
118
            if (substr($filePath, 0, strlen($folder)) === $folder)
119
            {
120
                return true;
121
            }
122
        }
123
124
        return false;
125
    }
126
127
    /**
128
     * Check whether a file is tracked
129
     *
130
     * @param  string $filePath The relative path of the file
131
     *
132
     * @return bool
133
     */
134 1
    public function isTracked ($filePath)
135
    {
136 1
        return array_key_exists($filePath, $this->trackedItemsFlattened);
137
    }
138
139
    /**
140
     * @param SplFileInfo|string $filePath
141
     *
142
     * @return mixed|null
143
     */
144
    public function createNewItem ($filePath)
145
    {
146
        return $this->handleTrackableItem($filePath);
0 ignored issues
show
Bug introduced by
It seems like $filePath defined by parameter $filePath on line 144 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...
147
    }
148
149
    /**
150
     * Update the contents of a specified file
151
     *
152
     * @param SplFileInfo|string $filePath The relative path of the file
153
     *
154
     * @return mixed|null
155
     */
156
    public function refreshItem ($filePath)
157
    {
158
        return $this->handleTrackableItem(
159
            $filePath,
0 ignored issues
show
Bug introduced by
It seems like $filePath defined by parameter $filePath on line 156 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...
160
            $this->trackedItemsOptions[$filePath]
161
        );
162
    }
163
164
    /**
165
     * Save data to the tracker with a reference to the file it came from
166
     *
167
     * @param string      $key       The name of the file
168
     * @param mixed       $data      The data to save the
169
     * @param string      $filePath  The relative file path from the root of the website
170
     * @param string|null $namespace The name of the collection this data belongs to, if any
171
     */
172 30
    protected function addArrayToTracker ($key, $data, $filePath, $namespace = null)
173
    {
174 30
        if (is_null($namespace))
175
        {
176
            $this->trackedItems[$key] = $data;
177
            $this->trackedItemsFlattened[$filePath] = &$this->trackedItems[$key];
178
        }
179
        else
180
        {
181 30
            $this->trackedItems[$namespace][$key] = $data;
182 30
            $this->trackedItemsFlattened[$filePath] = &$this->trackedItems[$namespace][$key];
183
        }
184 30
    }
185
186
    /**
187
     * Add a FrontMatterObject based object to the tracker
188
     *
189
     * @param FrontMatterObject $trackedItem
190
     * @param string            $key
191
     * @param string|null       $namespace
192
     */
193 30
    protected function addObjectToTracker ($trackedItem, $key, $namespace = null)
194
    {
195 30
        if (!($trackedItem instanceof FrontMatterObject))
196
        {
197
            throw new \InvalidArgumentException('Only objects can be added to the tracker');
198
        }
199
200 30
        $this->addArrayToTracker($key, $trackedItem, $trackedItem->getRelativeFilePath(), $namespace);
201 30
    }
202
203
    /**
204
     * Remove all data related to an array that was saved
205
     *
206
     * @param string      $key
207
     * @param string      $filePath
208
     * @param string|null $namespace
209
     */
210
    protected function delArrayFromTracker ($key, $filePath, $namespace = null)
211
    {
212
        if (is_null($namespace))
213
        {
214
            unset($this->trackedItems[$key]);
215
        }
216
        else
217
        {
218
            unset($this->trackedItems[$namespace][$key]);
219
        }
220
221
        unset($this->trackedItemsFlattened[$filePath]);
222
    }
223
224
    /**
225
     * Remove an entry from the tracked items array
226
     *
227
     * @param mixed       $trackedItem
228
     * @param string|null $namespace
229
     */
230
    protected function delObjectFromTracker ($trackedItem, $namespace = null)
231
    {
232
        $this->delArrayFromTracker(
233
            $trackedItem->getFileName(),
234
            $trackedItem->getRelativeFilePath(),
235
            $namespace
236
        );
237
    }
238
239
    /**
240
     * Save a folder that is tracked by this manager and its respective options
241
     *
242
     * @param string $folderPath
243
     * @param array  $options
244
     */
245 30
    protected function saveFolderDefinition ($folderPath, $options = array())
246
    {
247 30
        $this->folderDefinitions[] = $folderPath;
248 30
        $this->folderDefinitionsOptions[$folderPath] = $options;
249 30
    }
250
251
    /**
252
     * Save any options related to an item needed in order to refresh the content
253
     *
254
     * @param string $filePath
255
     * @param array $options
256
     */
257
    protected function saveTrackerOptions ($filePath, $options = array())
258
    {
259
        $this->trackedItemsOptions[$filePath] = $options;
260
    }
261
262
    /**
263
     * Parse the specified folder for items to track
264
     *
265
     * @param string $path
266
     * @param mixed  $options  Special options that will be passed to the static::parseTrackableItem() implementation
267
     * @param array  $includes
268
     * @param array  $excludes
269
     */
270 30
    protected function scanTrackableItems ($path, $options = array(), $includes = array(), $excludes = array())
271
    {
272 30
        $fileExplorerFlags  = array_key_exists('fileExplorer', $options) ? $options['fileExplorer'] : null;
273 30
        $this->fileExplorer = FileExplorer::create($path, $excludes, $includes, $fileExplorerFlags);
274 30
        $fileExplorer = $this->fileExplorer->getExplorer();
275
276 30
        foreach ($fileExplorer as $file)
277
        {
278 30
            $this->handleTrackableItem($file, $options);
279
        }
280 30
    }
281
282
    /**
283
     * Handle a specific file type, parse it into the appropriate object type, and add it to the tracker
284
     *
285
     * This function should make use of the appropriate functions:
286
     *
287
     *  - TrackingManager::addObjectToTracker()
288
     *  - TrackingManager::addArrayToTracker()
289
     *  - TrackingManager::saveTrackerOptions()
290
     *
291
     * @param  SplFileInfo $filePath
292
     * @param  mixed       $options
293
     *
294
     * @return mixed|null
295
     */
296
    abstract protected function handleTrackableItem ($filePath, $options = array());
297
}