Completed
Push — master ( b785dd...3df4eb )
by Vladimir
03:46
created

TrackingManager::saveFolderDefinition()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 2
dl 0
loc 5
ccs 4
cts 4
cp 1
crap 1
rs 9.4285
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\FrontMatter\Document;
11
use allejo\stakx\System\FileExplorer;
12
use Symfony\Component\Finder\SplFileInfo;
13
14
/**
15
 * Class TrackingManager.
16
 */
17
abstract class TrackingManager extends BaseManager
0 ignored issues
show
Coding Style introduced by
TrackingManager does not seem to conform to the naming convention (^Abstract|Factory$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
18
{
19
    /**
20
     * @var FileExplorer
21
     */
22
    protected $fileExplorer;
23
24
    /**
25
     * An array corresponding with $folderDefinitions to store metadata regarding a specificc folder.
26
     *
27
     * $folderDefinitionsOption['<folder path>'] = array()
28
     *
29
     * @var string[]
30
     */
31
    protected $folderDefinitionsOptions;
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $folderDefinitionsOptions exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
32
33
    /**
34
     * An array of folders which tracked items are stored in.
35
     *
36
     * $folderDefinitions[] = '<folder path>'
37
     *
38
     * @var string[]
39
     */
40
    protected $folderDefinitions;
41
42
    /**
43
     * The storage which contains the same information as $trackedItems but organized by relative file path instead of a
44
     * namespace or file name without extension.
45
     *
46
     * $trackedItemsOptions['<relative file path>'] = mixed
47
     *
48
     * @var array
49
     */
50
    protected $trackedItemsFlattened;
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $trackedItemsFlattened exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

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