Completed
Pull Request — master (#61)
by Vladimir
03:14
created

CollectionManager   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 194
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 7

Test Coverage

Coverage 83.87%

Importance

Changes 0
Metric Value
wmc 17
lcom 2
cbo 7
dl 0
loc 194
ccs 52
cts 62
cp 0.8387
rs 10
c 0
b 0
f 0

10 Methods

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