Completed
Push — feature/unit-test-improvements ( 50162b )
by Vladimir
01:52
created

CollectionManager::getCollectionNameFromPath()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2.0116

Importance

Changes 0
Metric Value
dl 0
loc 12
ccs 6
cts 7
cp 0.8571
rs 9.8666
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 2.0116
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 6
        {
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 1
        {
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 36
        {
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 36
            ]);
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->scanTrackableItems($def, [
168 36
                'namespace' => $collection['name'],
169 36
            ]);
170 36
        }
171 36
    }
172
173
    /**
174
     * {@inheritdoc}
175
     */
176 1
    public function createNewItem($filePath)
177
    {
178 1
        $collection = $this->getCollectionNameFromPath($filePath);
179
180 1
        return $this->handleTrackableItem($filePath, [
181 1
            'namespace' => $collection,
182 1
        ]);
183
    }
184
185
    /**
186
     * {@inheritdoc}
187
     */
188
    public function refreshItem($filePath)
189
    {
190
    }
191
192
    /**
193
     * {@inheritdoc}
194
     */
195 36
    protected function handleTrackableItem(File $filePath, array $options = [])
196
    {
197 36
        $collectionName = $options['namespace'];
198
199 36
        $contentItem = new ContentItem($filePath);
200 36
        $contentItem->setTemplateEngine($this->templateBridge);
201 36
        $contentItem->setMarkupEngine($this->markupEngineManager);
202 36
        $contentItem->setNamespace($collectionName);
203 36
        $contentItem->evaluateFrontMatter([], [
204 36
            'site' => $this->configuration->getConfiguration(),
205 36
        ]);
206
207 36
        $this->addObjectToTracker($contentItem, $collectionName);
208
209 36
        $this->logger->info('Loading ContentItem into "{name}" collection: {path}', [
210 36
            'name' => $collectionName,
211 36
            'path' => $filePath->getRelativeFilePath(),
212 36
        ]);
213
214 36
        $event = new CollectionItemAdded($contentItem);
215 36
        $this->eventDispatcher->dispatch(CollectionItemAdded::NAME, $event);
216
217 36
        return $contentItem;
218
    }
219
220
    /**
221
     * Get the name of the Collection this ContentItem belongs to based on its location.
222
     *
223
     * @param File $file
224
     *
225
     * @return string
226
     */
227 1
    private function getCollectionNameFromPath(File $file)
228
    {
229 1
        $folders = array_column($this->collectionDefinitions, 'folder');
230 1
        $index = array_search($file->getRelativeParentFolder(), $folders);
231
232 1
        if (isset($this->collectionDefinitions[$index]['name']))
233 1
        {
234 1
            return $this->collectionDefinitions[$index]['name'];
235
        }
236
237
        return '';
238
    }
239
}
240