Completed
Pull Request — master (#48)
by Vladimir
02:47
created

TrackingManager::getJailedTrackedItems()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 17
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 4

Importance

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