Completed
Push — master ( 7e0874...14a89c )
by Vladimir
04:01 queued 01:49
created

PageManager::handleTrackableRepeaterPageView()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 7
ccs 5
cts 5
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\BasePageView;
12
use allejo\stakx\Document\ContentItem;
13
use allejo\stakx\Document\DataItem;
14
use allejo\stakx\Document\DynamicPageView;
15
use allejo\stakx\Document\JailedDocument;
16
use allejo\stakx\Document\RepeaterPageView;
17
use allejo\stakx\Document\StaticPageView;
18
use allejo\stakx\Event\PageManagerPostProcess;
19
use allejo\stakx\Event\PageManagerPreProcess;
20
use allejo\stakx\Event\PageViewAdded;
21
use allejo\stakx\Event\PageViewDefinitionAdded;
22
use allejo\stakx\Exception\CollectionNotFoundException;
23
use allejo\stakx\Filesystem\File;
24
use allejo\stakx\Filesystem\FileExplorer;
25
use allejo\stakx\Filesystem\FilesystemLoader as fs;
26
use Psr\Log\LoggerInterface;
27
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
28
29
/**
30
 * This class is responsible for handling all of the PageViews within a website.
31
 *
32
 * PageManager will parse all available dynamic and static PageViews. After, dynamic PageViews will be prepared by
33
 * setting the appropriate values for each ContentItem such as permalinks.
34
 */
35
class PageManager extends TrackingManager
36
{
37
    /** @var StaticPageView[] A place to store a reference to static PageViews with titles. */
38
    private $staticPages;
39
    private $configuration;
40
    private $collectionManager;
41
    private $dataManager;
42
    private $eventDispatcher;
43
    private $logger;
44
45
    /**
46
     * PageManager constructor.
47
     */
48 20
    public function __construct(
49
        Configuration $configuration,
50
        CollectionManager $collectionManager,
51
        DataManager $dataManager,
52
        EventDispatcherInterface $eventDispatcher,
53
        LoggerInterface $logger
54
    ) {
55 20
        $this->trackedItems = [
56 20
            BasePageView::STATIC_TYPE => [],
57 20
            BasePageView::DYNAMIC_TYPE => [],
58 20
            BasePageView::REPEATER_TYPE => [],
59
        ];
60 20
        $this->staticPages = [];
61 20
        $this->configuration = $configuration;
62 20
        $this->collectionManager = $collectionManager;
63 20
        $this->dataManager = $dataManager;
64 20
        $this->eventDispatcher = $eventDispatcher;
65 20
        $this->logger = $logger;
66 20
    }
67
68
    /**
69
     * {@inheritdoc}
70
     */
71 7
    public function compileManager()
72
    {
73 7
        $this->parsePageViews($this->configuration->getPageViewFolders());
74 6
    }
75
76
    /**
77
     * Go through all of the PageView directories and create a respective PageView for each and classify them by type.
78
     *
79
     * @param string[] $pageViewFolders
80
     *
81
     * @since 0.1.0
82
     */
83 19
    public function parsePageViews(array $pageViewFolders)
84
    {
85 19
        $preEvent = new PageManagerPreProcess($this);
86 19
        $this->eventDispatcher->dispatch(PageManagerPreProcess::NAME, $preEvent);
87
88 19
        foreach ($pageViewFolders as $pageViewFolderName)
89
        {
90 19
            $pageViewFolderPath = fs::absolutePath($pageViewFolderName);
0 ignored issues
show
Documentation introduced by
$pageViewFolderName 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...
91
92 19
            if (!fs::exists($pageViewFolderPath))
93
            {
94 1
                $this->logger->warning("The '$pageViewFolderName' folder could not be found");
95 1
                continue;
96
            }
97
98 18
            $event = new PageViewDefinitionAdded($pageViewFolderName);
99 18
            $this->eventDispatcher->dispatch(PageViewDefinitionAdded::NAME, $event);
100
101 18
            $this->scanTrackableItems($pageViewFolderPath, [
102 18
                'fileExplorer' => FileExplorer::INCLUDE_ONLY_FILES,
103 18
            ], ['/.html$/', '/.twig$/']);
104
        }
105
106 18
        $postEvent = new PageManagerPostProcess($this);
107 18
        $this->eventDispatcher->dispatch(PageManagerPostProcess::NAME, $postEvent);
108 18
    }
109
110
    /**
111
     * Get all of the PageViews in an associative array with PageView types as the keys.
112
     *
113
     * @since  0.1.1
114
     *
115
     * @return BasePageView[][]
116
     */
117 1
    public function &getPageViews()
118
    {
119 1
        return $this->trackedItems;
120
    }
121
122
    /**
123
     * Get all of the PageViews in flat array.
124
     *
125
     * @since  0.1.1
126
     *
127
     * @return BasePageView[]
128
     */
129 17
    public function &getPageViewsFlattened()
130
    {
131 17
        return $this->trackedItemsFlattened;
132
    }
133
134
    /**
135
     * Get the static PageViews tracked by this manager indexed by their title.
136
     *
137
     * @since 0.1.0
138
     *
139
     * @return StaticPageView[]
140
     */
141 1
    public function getStaticPageViews()
142
    {
143 1
        return $this->staticPages;
144
    }
145
146
    /**
147
     * Get the jailed version of the static PageViews indexed by their title.
148
     *
149
     * @since 0.1.0
150
     *
151
     * @return JailedDocument[]
152
     */
153 13
    public function getJailedStaticPageViews()
154
    {
155 13
        $jailedObjects = [];
156
157 13
        foreach ($this->staticPages as $key => $value)
158
        {
159 1
            $jailedObjects[$key] = $value->createJail();
160
        }
161
162 13
        return $jailedObjects;
163
    }
164
165
    /**
166
     * Add a PageView for this PageManager to track.
167
     *
168
     * @param BasePageView|StaticPageView|DynamicPageView|RepeaterPageView $pageView
169
     *
170
     * @throws \LogicException             When a PageView is treated as the wrong type
171
     * @throws CollectionNotFoundException When the collection specified in a Dynamic PageView isn't found
172
     * @throws \Exception                  The permalink could not be built correctly
173
     *
174
     * @since 0.2.0
175
     */
176 19
    public function trackNewPageView(BasePageView $pageView)
177
    {
178 19
        $namespace = $pageView->getType();
179
180
        switch ($namespace)
181
        {
182 19
            case BasePageView::STATIC_TYPE:
183 12
                $this->handleTrackableStaticPageView($pageView);
0 ignored issues
show
Compatibility introduced by
$pageView of type object<allejo\stakx\Document\BasePageView> is not a sub-type of object<allejo\stakx\Document\StaticPageView>. It seems like you assume a child class of the class allejo\stakx\Document\BasePageView to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
184 12
                break;
185
186 7
            case BasePageView::DYNAMIC_TYPE:
187 4
                $this->handleTrackableDynamicPageView($pageView);
0 ignored issues
show
Compatibility introduced by
$pageView of type object<allejo\stakx\Document\BasePageView> is not a sub-type of object<allejo\stakx\Document\DynamicPageView>. It seems like you assume a child class of the class allejo\stakx\Document\BasePageView to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
188 3
                break;
189
190 3
            case BasePageView::REPEATER_TYPE:
191 3
                $this->handleTrackableRepeaterPageView($pageView);
0 ignored issues
show
Compatibility introduced by
$pageView of type object<allejo\stakx\Document\BasePageView> is not a sub-type of object<allejo\stakx\Document\RepeaterPageView>. It seems like you assume a child class of the class allejo\stakx\Document\BasePageView to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
192 3
                break;
193
194
            default:
195
                break;
196
        }
197
198 18
        $event = new PageViewAdded($pageView);
199 18
        $this->eventDispatcher->dispatch(PageViewAdded::NAME, $event);
200
201 18
        $this->addObjectToTracker($pageView, $namespace);
202 18
    }
203
204
    /**
205
     * Add a new ContentItem to the respective parent PageView of the ContentItem.
206
     *
207
     * @param ContentItem $contentItem
208
     *
209
     * @since 0.1.0
210
     */
211 1
    public function trackNewContentItem(&$contentItem)
212
    {
213 1
        $collection = $contentItem->getNamespace();
214 1
        $this->trackedItems[BasePageView::DYNAMIC_TYPE][$collection]->addCollectableItem($contentItem);
215 1
    }
216
217
    /**
218
     * {@inheritdoc}
219
     */
220 18
    protected function &handleTrackableItem(File $filePath, array $options = [])
221
    {
222 18
        $pageView = BasePageView::create($filePath, [
223 18
            'site' => $this->configuration->getConfiguration(),
224
        ]);
225
226 18
        $this->trackNewPageView($pageView);
227
228 17
        return $pageView;
229
    }
230
231
    /**
232
     * Handle special behavior and treatment for static PageViews while we're iterating through them.
233
     *
234
     * @param StaticPageView $pageView
235
     *
236
     * @since 0.1.0
237
     */
238 12
    private function handleTrackableStaticPageView(&$pageView)
239
    {
240 12
        $pageView->evaluateFrontMatter([], [
241 12
            'site' => $this->configuration->getConfiguration(),
242
        ]);
243
244 12
        if (empty($pageView['title']))
245
        {
246 12
            return;
247
        }
248
249 2
        $this->staticPages[$pageView['title']] = &$pageView;
250 2
    }
251
252
    /**
253
     * Handle special behavior and treatment for dynamic PageViews while we're iterating through them.
254
     *
255
     * @param DynamicPageView $pageView
256
     *
257
     * @since 0.1.0
258
     *
259
     * @throws \LogicException             An invalid PageView has been given as a Dynamic PageView
260
     * @throws CollectionNotFoundException When a collection or dataset specified in a Dynamic PageView doesn't exist
261
     * @throws \Exception                  When the permalink for the given PageView hasn't been set
262
     */
263 4
    private function handleTrackableDynamicPageView(&$pageView)
264
    {
265 4
        $frontMatter = $pageView->getRawFrontMatter();
266 4
        $dataSource = null;
267 4
        $namespace = null;
268
269 4
        if (isset($frontMatter['collection']))
270
        {
271 4
            $dataSource = &$this->collectionManager->getCollections();
272 4
            $namespace = 'collection';
273
        }
274
        elseif (isset($frontMatter['dataset']))
275
        {
276
            $dataSource = &$this->dataManager->getDataItems();
277
            $namespace = 'dataset';
278
        }
279
280 4
        if ($dataSource === null)
281
        {
282
            throw new \LogicException('Invalid Dynamic PageView defined');
283
        }
284
285 4
        $collection = $frontMatter[$namespace];
286
287 4
        if (!isset($dataSource[$collection]))
288
        {
289 1
            throw new CollectionNotFoundException("The '$collection' $namespace is not defined");
290
        }
291
292
        /** @var ContentItem|DataItem $item */
293 3
        foreach ($dataSource[$collection] as &$item)
294
        {
295 3
            $item->evaluateFrontMatter($frontMatter, [
296 3
                'site' => $this->configuration->getConfiguration(),
297
            ]);
298 3
            $item->saveParentPageView($pageView);
299 3
            $item->buildPermalink(true);
300
301 3
            $pageView->addCollectableItem($item);
302
        }
303 3
    }
304
305
    /**
306
     * Handle special behavior and treatment for repeater PageViews while we're iterating through them.
307
     *
308
     * @param RepeaterPageView $pageView
309
     *
310
     * @since 0.2.0
311
     */
312 3
    private function handleTrackableRepeaterPageView(&$pageView)
313
    {
314 3
        $pageView->evaluateFrontMatter([], [
315 3
            'site' => $this->configuration->getConfiguration(),
316
        ]);
317 3
        $pageView->configurePermalinks();
318 3
    }
319
}
320