Completed
Pull Request — master (#87)
by Vladimir
02:24
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\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
    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 6
        {
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 1
        {
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[][]
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...
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 36
        {
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 36
            ]);
142
143 36
            $collectionFolder = fs::absolutePath($collection['folder']);
0 ignored issues
show
Documentation introduced by
$collection['folder'] is of type string, but the function expects a object<string>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
144
145 36
            if (!fs::exists($collectionFolder))
146 36
            {
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 36
            ]);
162 36
        }
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 1
        ]);
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 36
        ]);
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 36
        ]);
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 1
        {
226 1
            return $this->collectionDefinitions[$index]['name'];
227
        }
228
229
        return '';
230
    }
231
}
232