Completed
Pull Request — master (#48)
by Vladimir
03:04
created

TrackingManager::handleTrackableItem()

Size

Total Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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