1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* @copyright 2018 Vladimir Jimenez |
5
|
|
|
* @license https://github.com/stakx-io/stakx/blob/master/LICENSE.md MIT |
6
|
|
|
*/ |
7
|
|
|
|
8
|
|
|
namespace allejo\stakx\Manager; |
9
|
|
|
|
10
|
|
|
use allejo\stakx\Configuration; |
11
|
|
|
use allejo\stakx\Document\ContentItem; |
12
|
|
|
use allejo\stakx\Document\JailedDocument; |
13
|
|
|
use allejo\stakx\Event\CollectionDefinitionAdded; |
14
|
|
|
use allejo\stakx\Event\CollectionItemAdded; |
15
|
|
|
use allejo\stakx\Exception\TrackedItemNotFoundException; |
16
|
|
|
use allejo\stakx\Filesystem\File; |
17
|
|
|
use allejo\stakx\Filesystem\FilesystemLoader as fs; |
18
|
|
|
use allejo\stakx\MarkupEngine\MarkupEngineManager; |
19
|
|
|
use allejo\stakx\Templating\TemplateBridgeInterface; |
20
|
|
|
use Psr\Log\LoggerInterface; |
21
|
|
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface; |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
* The class that reads and saves information about all of the collections. |
25
|
|
|
*/ |
26
|
|
|
class CollectionManager extends TrackingManager |
27
|
|
|
{ |
28
|
|
|
/** @var string[][] A copy of the collection definitions to be available for later usage. */ |
29
|
|
|
private $collectionDefinitions; |
30
|
|
|
private $markupEngineManager; |
31
|
|
|
private $configuration; |
32
|
|
|
private $eventDispatcher; |
33
|
|
|
private $templateBridge; |
34
|
|
|
private $logger; |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* CollectionManager constructor. |
38
|
|
|
*/ |
39
|
36 |
View Code Duplication |
public function __construct(MarkupEngineManager $markupEngineManager, Configuration $configuration, TemplateBridgeInterface $templateBridge, EventDispatcherInterface $eventDispatcher, LoggerInterface $logger) |
|
|
|
|
40
|
|
|
{ |
41
|
36 |
|
$this->markupEngineManager = $markupEngineManager; |
42
|
36 |
|
$this->configuration = $configuration; |
43
|
36 |
|
$this->eventDispatcher = $eventDispatcher; |
44
|
36 |
|
$this->templateBridge = $templateBridge; |
45
|
36 |
|
$this->logger = $logger; |
46
|
36 |
|
} |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* {@inheritdoc} |
50
|
|
|
*/ |
51
|
6 |
|
public function compileManager() |
52
|
|
|
{ |
53
|
6 |
|
if (!$this->configuration->hasCollections()) |
54
|
|
|
{ |
55
|
|
|
$this->logger->notice('No Collections defined... Ignoring'); |
56
|
|
|
|
57
|
|
|
return; |
58
|
|
|
} |
59
|
|
|
|
60
|
6 |
|
$this->parseCollections($this->configuration->getCollectionsFolders()); |
61
|
6 |
|
} |
62
|
|
|
|
63
|
|
|
/** |
64
|
|
|
* Get all of the ContentItems grouped by Collection name. |
65
|
|
|
* |
66
|
|
|
* ```php |
67
|
|
|
* [ |
68
|
|
|
* 'collection name' => [ |
69
|
|
|
* new ContentItem(), |
70
|
|
|
* new ContentItem(), |
71
|
|
|
* ] |
72
|
|
|
* ] |
73
|
|
|
* ``` |
74
|
|
|
* |
75
|
|
|
* @return ContentItem[][] |
76
|
|
|
*/ |
77
|
15 |
|
public function &getCollections() |
78
|
|
|
{ |
79
|
15 |
|
return $this->trackedItems; |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
/** |
83
|
|
|
* Get a ContentItem from a Collection passed on it's path. |
84
|
|
|
* |
85
|
|
|
* @param string $filePath |
86
|
|
|
* |
87
|
|
|
* @throws TrackedItemNotFoundException |
88
|
|
|
* |
89
|
|
|
* @return ContentItem |
90
|
|
|
*/ |
91
|
1 |
|
public function &getContentItem($filePath) |
92
|
|
|
{ |
93
|
1 |
|
if (!isset($this->trackedItemsFlattened[$filePath])) |
94
|
|
|
{ |
95
|
|
|
throw new TrackedItemNotFoundException("The ContentItem at '$filePath' was not found."); |
96
|
|
|
} |
97
|
|
|
|
98
|
1 |
|
return $this->trackedItemsFlattened[$filePath]; |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
/** |
102
|
|
|
* A jailed representation of CollectionManager::getCollections(). |
103
|
|
|
* |
104
|
|
|
* @return JailedDocument[][] |
|
|
|
|
105
|
|
|
*/ |
106
|
|
|
public function getJailedCollections() |
107
|
|
|
{ |
108
|
19 |
|
return self::getJailedTrackedItems($this->trackedItemsFlattened, function ($contentItem) { |
109
|
19 |
|
return $contentItem['basename']; |
110
|
19 |
|
}); |
111
|
|
|
} |
112
|
|
|
|
113
|
|
|
/** |
114
|
|
|
* Parse every collection and store them in the manager. |
115
|
|
|
* |
116
|
|
|
* @param string[][] $collections An array of definitions for collections |
117
|
|
|
*/ |
118
|
36 |
|
public function parseCollections($collections) |
119
|
|
|
{ |
120
|
36 |
|
if ($collections == null || empty($collections)) |
121
|
|
|
{ |
122
|
1 |
|
$this->logger->debug('No collections found, nothing to parse.'); |
123
|
|
|
|
124
|
1 |
|
return; |
125
|
|
|
} |
126
|
|
|
|
127
|
36 |
|
$this->collectionDefinitions = $collections; |
128
|
|
|
|
129
|
|
|
/** |
130
|
|
|
* The information which each collection has taken from the configuration file. |
131
|
|
|
* |
132
|
|
|
* $collection['name'] string The name of the collection |
133
|
|
|
* ['folder'] string The folder where this collection has its ContentItems |
134
|
|
|
* |
135
|
|
|
* @var array |
136
|
|
|
*/ |
137
|
36 |
|
foreach ($collections as $collection) |
138
|
|
|
{ |
139
|
36 |
|
$this->logger->notice('Loading "{name}" collection...', [ |
140
|
36 |
|
'name' => $collection['name'], |
141
|
|
|
]); |
142
|
|
|
|
143
|
36 |
|
$collectionFolder = fs::absolutePath($collection['folder']); |
|
|
|
|
144
|
|
|
|
145
|
36 |
|
if (!fs::exists($collectionFolder)) |
146
|
|
|
{ |
147
|
|
|
$this->logger->warning('The folder "{folder}" could not be found for the "{name}" collection', [ |
148
|
|
|
'folder' => $collection['folder'], |
149
|
|
|
'name' => $collection['name'], |
150
|
|
|
]); |
151
|
|
|
|
152
|
|
|
continue; |
153
|
|
|
} |
154
|
|
|
|
155
|
36 |
|
$event = new CollectionDefinitionAdded($collection['name'], $collection['folder']); |
156
|
36 |
|
$this->eventDispatcher->dispatch(CollectionDefinitionAdded::NAME, $event); |
157
|
|
|
|
158
|
36 |
|
$this->saveFolderDefinition($collection['folder'], $collection); |
159
|
36 |
|
$this->scanTrackableItems($collectionFolder, [ |
160
|
36 |
|
'namespace' => $collection['name'], |
161
|
|
|
]); |
162
|
|
|
} |
163
|
36 |
|
} |
164
|
|
|
|
165
|
|
|
/** |
166
|
|
|
* {@inheritdoc} |
167
|
|
|
*/ |
168
|
1 |
|
public function createNewItem($filePath) |
169
|
|
|
{ |
170
|
1 |
|
$collection = $this->getCollectionNameFromPath($filePath); |
171
|
|
|
|
172
|
1 |
|
return $this->handleTrackableItem($filePath, [ |
173
|
1 |
|
'namespace' => $collection, |
174
|
|
|
]); |
175
|
|
|
} |
176
|
|
|
|
177
|
|
|
/** |
178
|
|
|
* {@inheritdoc} |
179
|
|
|
*/ |
180
|
|
|
public function refreshItem($filePath) |
181
|
|
|
{ |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
/** |
185
|
|
|
* {@inheritdoc} |
186
|
|
|
*/ |
187
|
36 |
|
protected function handleTrackableItem(File $filePath, array $options = []) |
188
|
|
|
{ |
189
|
36 |
|
$collectionName = $options['namespace']; |
190
|
|
|
|
191
|
36 |
|
$contentItem = new ContentItem($filePath); |
192
|
36 |
|
$contentItem->setTemplateEngine($this->templateBridge); |
193
|
36 |
|
$contentItem->setMarkupEngine($this->markupEngineManager); |
194
|
36 |
|
$contentItem->setNamespace($collectionName); |
195
|
36 |
|
$contentItem->evaluateFrontMatter([], [ |
196
|
36 |
|
'site' => $this->configuration->getConfiguration(), |
197
|
|
|
]); |
198
|
|
|
|
199
|
36 |
|
$this->addObjectToTracker($contentItem, $collectionName); |
200
|
|
|
|
201
|
36 |
|
$this->logger->info('Loading ContentItem into "{name}" collection: {path}', [ |
202
|
36 |
|
'name' => $collectionName, |
203
|
36 |
|
'path' => $filePath->getRelativeFilePath(), |
204
|
|
|
]); |
205
|
|
|
|
206
|
36 |
|
$event = new CollectionItemAdded($contentItem); |
207
|
36 |
|
$this->eventDispatcher->dispatch(CollectionItemAdded::NAME, $event); |
208
|
|
|
|
209
|
36 |
|
return $contentItem; |
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
/** |
213
|
|
|
* Get the name of the Collection this ContentItem belongs to based on its location. |
214
|
|
|
* |
215
|
|
|
* @param File $file |
216
|
|
|
* |
217
|
|
|
* @return string |
218
|
|
|
*/ |
219
|
1 |
|
private function getCollectionNameFromPath(File $file) |
220
|
|
|
{ |
221
|
1 |
|
$folders = array_column($this->collectionDefinitions, 'folder'); |
222
|
1 |
|
$index = array_search($file->getRelativeParentFolder(), $folders); |
223
|
|
|
|
224
|
1 |
|
if (isset($this->collectionDefinitions[$index]['name'])) |
225
|
|
|
{ |
226
|
1 |
|
return $this->collectionDefinitions[$index]['name']; |
227
|
|
|
} |
228
|
|
|
|
229
|
|
|
return ''; |
230
|
|
|
} |
231
|
|
|
} |
232
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.