Completed
Push — master ( 952fde...7bae76 )
by Vladimir
11s
created

CollectionManager::createNewItem()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 4
cts 4
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
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)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
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[][]
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
        {
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']);
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
            {
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