Completed
Push — master ( 7b9015...c5b311 )
by Vladimir
26s queued 11s
created

CollectionManager::getCollectionNameFromPath()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2.0185

Importance

Changes 0
Metric Value
dl 0
loc 12
ccs 5
cts 6
cp 0.8333
rs 9.8666
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 2.0185
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\FileExplorer;
18
use allejo\stakx\Filesystem\FileExplorerDefinition;
19
use allejo\stakx\Filesystem\Folder;
20
use allejo\stakx\MarkupEngine\MarkupEngineManager;
21
use allejo\stakx\Templating\TemplateBridgeInterface;
22
use Psr\Log\LoggerInterface;
23
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
24
25
/**
26
 * The class that reads and saves information about all of the collections.
27
 */
28
class CollectionManager extends TrackingManager
29
{
30
    /** @var string[][] A copy of the collection definitions to be available for later usage. */
31
    private $collectionDefinitions;
32
    /** @var MarkupEngineManager */
33
    private $markupEngineManager;
34
    /** @var Configuration */
35
    private $configuration;
36
    /** @var EventDispatcherInterface */
37
    private $eventDispatcher;
38
    /** @var TemplateBridgeInterface */
39
    private $templateBridge;
40
    /** @var LoggerInterface */
41
    private $logger;
42
43
    /**
44
     * CollectionManager constructor.
45
     */
46 36
    public function __construct(
47
        MarkupEngineManager $markupEngineManager,
48
        Configuration $configuration,
49
        TemplateBridgeInterface $templateBridge,
50
        EventDispatcherInterface $eventDispatcher,
51
        LoggerInterface $logger
52
    ) {
53 36
        $this->markupEngineManager = $markupEngineManager;
54 36
        $this->configuration = $configuration;
55 36
        $this->eventDispatcher = $eventDispatcher;
56 36
        $this->templateBridge = $templateBridge;
57 36
        $this->logger = $logger;
58 36
    }
59
60
    /**
61
     * {@inheritdoc}
62
     */
63 6
    public function compileManager()
64
    {
65 6
        if (!$this->configuration->hasCollections())
66
        {
67
            $this->logger->notice('No Collections defined... Ignoring');
68
69
            return;
70
        }
71
72 6
        $this->parseCollections($this->configuration->getCollectionsFolders());
73 6
    }
74
75
    /**
76
     * Get all of the ContentItems grouped by Collection name.
77
     *
78
     * ```php
79
     * [
80
     *     'collection name' => [
81
     *         new ContentItem(),
82
     *         new ContentItem(),
83
     *     ]
84
     * ]
85
     * ```
86
     *
87
     * @return ContentItem[][]
88
     */
89 15
    public function &getCollections()
90
    {
91 15
        return $this->trackedItems;
92
    }
93
94
    /**
95
     * Get a ContentItem from a Collection passed on it's path.
96
     *
97
     * @param string $filePath
98
     *
99
     * @throws TrackedItemNotFoundException
100
     *
101
     * @return ContentItem
102
     */
103 1
    public function &getContentItem($filePath)
104
    {
105 1
        if (!isset($this->trackedItemsFlattened[$filePath]))
106
        {
107
            throw new TrackedItemNotFoundException("The ContentItem at '$filePath' was not found.");
108
        }
109
110 1
        return $this->trackedItemsFlattened[$filePath];
111
    }
112
113
    /**
114
     * A jailed representation of CollectionManager::getCollections().
115
     *
116
     * @return JailedDocument[][]
0 ignored issues
show
Documentation introduced by
Should the return type not be array<JailedDocument|JailedDocument[]>?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
117
     */
118
    public function getJailedCollections()
119
    {
120 19
        return self::getJailedTrackedItems($this->trackedItemsFlattened, function ($contentItem) {
121 19
            return $contentItem['basename'];
122 19
        });
123
    }
124
125
    /**
126
     * Parse every collection and store them in the manager.
127
     *
128
     * @param string[][] $collections An array of definitions for collections
129
     */
130 36
    public function parseCollections($collections)
131
    {
132 36
        if ($collections == null || empty($collections))
133
        {
134 1
            $this->logger->debug('No collections found, nothing to parse.');
135
136 1
            return;
137
        }
138
139 36
        $this->collectionDefinitions = $collections;
140
141
        /**
142
         * The information which each collection has taken from the configuration file.
143
         *
144
         * $collection['name']   string The name of the collection
145
         *            ['folder'] string The folder where this collection has its ContentItems
146
         *
147
         * @var array
148
         */
149 36
        foreach ($collections as $collection)
150
        {
151 36
            $this->logger->notice('Loading "{name}" collection...', [
152 36
                'name' => $collection['name'],
153
            ]);
154
155 36
            $folder = new Folder($collection['folder']);
156
157 36
            $event = new CollectionDefinitionAdded($collection['name'], $folder);
158 36
            $this->eventDispatcher->dispatch(CollectionDefinitionAdded::NAME, $event);
159
160
            // Only fetch ContentItems with supported extensions
161 36
            $def = new FileExplorerDefinition($folder);
162 36
            $def->flags |= FileExplorer::INCLUDE_ONLY_FILES;
163 36
            $def->includes = [
164 36
                sprintf('/\.(%s)$/', implode('|', $this->markupEngineManager->getSupportedExtensions())),
165
            ];
166
167 36
            $this->declareTrackingNamespace($collection['name']);
168 36
            $this->scanTrackableItems($def, [
169 36
                'namespace' => $collection['name'],
170
            ]);
171
        }
172 36
    }
173
174
    /**
175
     * {@inheritdoc}
176
     */
177 1
    public function createNewItem($filePath)
178
    {
179 1
        $collection = $this->getCollectionNameFromPath($filePath);
180
181 1
        return $this->handleTrackableItem($filePath, [
182 1
            'namespace' => $collection,
183
        ]);
184
    }
185
186
    /**
187
     * {@inheritdoc}
188
     */
189
    public function refreshItem($filePath)
190
    {
191
    }
192
193
    /**
194
     * {@inheritdoc}
195
     */
196 36
    protected function handleTrackableItem(File $filePath, array $options = [])
197
    {
198 36
        $collectionName = $options['namespace'];
199
200 36
        $contentItem = new ContentItem($filePath);
201 36
        $contentItem->setTemplateEngine($this->templateBridge);
202 36
        $contentItem->setMarkupEngine($this->markupEngineManager);
203 36
        $contentItem->setNamespace($collectionName);
204 36
        $contentItem->evaluateFrontMatter([], [
205 36
            'site' => $this->configuration->getConfiguration(),
206
        ]);
207
208 36
        $this->addObjectToTracker($contentItem, $collectionName);
209
210 36
        $this->logger->info('Loading ContentItem into "{name}" collection: {path}', [
211 36
            'name' => $collectionName,
212 36
            'path' => $filePath->getRelativeFilePath(),
213
        ]);
214
215 36
        $event = new CollectionItemAdded($contentItem);
216 36
        $this->eventDispatcher->dispatch(CollectionItemAdded::NAME, $event);
217
218 36
        return $contentItem;
219
    }
220
221
    /**
222
     * Get the name of the Collection this ContentItem belongs to based on its location.
223
     *
224
     * @param File $file
225
     *
226
     * @return string
227
     */
228 1
    private function getCollectionNameFromPath(File $file)
229
    {
230 1
        $folders = array_column($this->collectionDefinitions, 'folder');
231 1
        $index = array_search($file->getRelativeParentFolder(), $folders);
232
233 1
        if (isset($this->collectionDefinitions[$index]['name']))
234
        {
235 1
            return $this->collectionDefinitions[$index]['name'];
236
        }
237
238
        return '';
239
    }
240
}
241