Completed
Push — master ( a41cf5...7efa4f )
by Vladimir
02:55
created

PageManager::handleTrackableDynamicPageView()   B

Complexity

Conditions 6
Paths 12

Size

Total Lines 41
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 6.2163

Importance

Changes 0
Metric Value
dl 0
loc 41
ccs 18
cts 22
cp 0.8182
rs 8.439
c 0
b 0
f 0
cc 6
eloc 21
nc 12
nop 1
crap 6.2163
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\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\Filesystem\FilesystemLoader as fs;
19
use allejo\stakx\Event\PageViewsCompleted;
20
use allejo\stakx\Exception\CollectionNotFoundException;
21
use allejo\stakx\Filesystem\FileExplorer;
22
23
/**
24
 * This class is responsible for handling all of the PageViews within a website.
25
 *
26
 * PageManager will parse all available dynamic and static PageViews. After, dynamic PageViews will be prepared by
27
 * setting the appropriate values for each ContentItem such as permalinks.
28
 *
29
 * @internal
30
 */
31
class PageManager extends TrackingManager
32
{
33
    /** @var StaticPageView[] A place to store a reference to static PageViews with titles. */
34
    private $staticPages;
35
    private $configuration;
36
    private $collectionManager;
37
    private $dataManager;
38
39
    /**
40
     * PageManager constructor.
41
     */
42 19
    public function __construct(Configuration $configuration, CollectionManager $collectionManager = null, DataManager $dataManager = null)
43
    {
44 19
        parent::__construct();
45
46 19
        $this->trackedItems = array(
0 ignored issues
show
Documentation Bug introduced by
It seems like array(\allejo\stakx\Docu...PEATER_TYPE => array()) of type array<string|integer,array> is incompatible with the declared type array<integer,object<all...ment\ReadableDocument>> of property $trackedItems.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
47
            BasePageView::STATIC_TYPE   => array(),
48
            BasePageView::DYNAMIC_TYPE  => array(),
49
            BasePageView::REPEATER_TYPE => array(),
50
        );
51 19
        $this->staticPages = array();
52 19
        $this->configuration = $configuration;
53 19
        $this->collectionManager = $collectionManager;
54 19
        $this->dataManager = $dataManager;
55 19
    }
56
57
    /**
58
     * Go through all of the PageView directories and create a respective PageView for each and classify them by type.
59
     *
60
     * @param string[] $pageViewFolders
61
     *
62
     * @since 0.1.0
63
     *
64
     * @throws \Exception When the EventDispatcher service couldn't be found.
65
     */
66 19
    public function parsePageViews(array $pageViewFolders)
67
    {
68 19
        foreach ($pageViewFolders as $pageViewFolderName)
69
        {
70 19
            $pageViewFolderPath = fs::absolutePath($pageViewFolderName);
71
72 19
            if (!fs::exists($pageViewFolderPath))
73
            {
74 1
                $this->output->warning("The '$pageViewFolderName' folder could not be found");
75 1
                continue;
76
            }
77
78 18
            $this->scanTrackableItems($pageViewFolderPath, [
79 18
                'fileExplorer' => FileExplorer::INCLUDE_ONLY_FILES,
80 18
            ], ['/.html$/', '/.twig$/']);
81
        }
82
83 18
        if ($this->container !== null)
84
        {
85
            $ed = $this->container->get('event_dispatcher');
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $ed. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
86
            $ed->dispatch(PageViewsCompleted::NAME, null);
87
        }
88 18
    }
89
90
    /**
91
     * {@inheritdoc}
92
     *
93
     * @throws \Exception
94
     */
95 7
    public function compileManager()
96
    {
97 7
        $this->parsePageViews($this->configuration->getPageViewFolders());
98 6
    }
99
100
    /**
101
     * Get all of the PageViews in an associative array with PageView types as the keys.
102
     *
103
     * @since  0.1.1
104
     *
105
     * @return BasePageView[][]
0 ignored issues
show
Documentation introduced by
Should the return type not be \allejo\stakx\Document\ReadableDocument[]?

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...
106
     */
107 12
    public function &getPageViews()
108
    {
109 12
        return $this->trackedItems;
110
    }
111
112
    /**
113
     * Get all of the PageViews in flat array.
114
     *
115
     * @since  0.1.1
116
     *
117
     * @return BasePageView[]
0 ignored issues
show
Documentation introduced by
Should the return type not be \allejo\stakx\Document\ReadableDocument[]?

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...
118
     */
119 17
    public function &getPageViewsFlattened()
120
    {
121 17
        return $this->trackedItemsFlattened;
122
    }
123
124
    /**
125
     * Get the static PageViews tracked by this manager indexed by their title.
126
     *
127
     * @since 0.1.0
128
     *
129
     * @return StaticPageView[]
130
     */
131 1
    public function getStaticPageViews()
132
    {
133 1
        return $this->staticPages;
134
    }
135
136
    /**
137
     * Get the jailed version of the static PageViews indexed by their title.
138
     *
139
     * @since 0.1.0
140
     *
141
     * @return JailedDocument[]
142
     */
143 1
    public function getJailedStaticPageViews()
144
    {
145 1
        $jailedObjects = array();
146
147 1
        foreach ($this->staticPages as $key => $value)
148
        {
149 1
            $jailedObjects[$key] = $value->createJail();
150
        }
151
152 1
        return $jailedObjects;
153
    }
154
155
    /**
156
     * Add a new ContentItem to the respective parent PageView of the ContentItem.
157
     *
158
     * @param ContentItem $contentItem
159
     *
160
     * @since 0.1.0
161
     */
162 1
    public function trackNewContentItem(&$contentItem)
163
    {
164 1
        $collection = $contentItem->getNamespace();
165 1
        $this->trackedItems[BasePageView::DYNAMIC_TYPE][$collection]->addCollectableItem($contentItem);
166 1
    }
167
168
    /**
169
     * {@inheritdoc}
170
     */
171 18
    protected function &handleTrackableItem($filePath, array $options = array())
172
    {
173 18
        $pageView = BasePageView::create($filePath, [
174 18
            'site' => $this->configuration->getConfiguration(),
175
        ]);
176 18
        $namespace = $pageView->getType();
177
178
        switch ($namespace)
179
        {
180 18
            case BasePageView::STATIC_TYPE:
181 12
                $this->handleTrackableStaticPageView($pageView);
0 ignored issues
show
Bug introduced by
It seems like $pageView defined by \allejo\stakx\Document\B...n->getConfiguration())) on line 173 can also be of type object<allejo\stakx\Document\DynamicPageView> or object<allejo\stakx\Document\RepeaterPageView>; however, allejo\stakx\Manager\Pag...ackableStaticPageView() does only seem to accept object<allejo\stakx\Document\StaticPageView>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
182 12
                break;
183
184 6
            case BasePageView::DYNAMIC_TYPE:
185 4
                $this->handleTrackableDynamicPageView($pageView);
0 ignored issues
show
Bug introduced by
It seems like $pageView defined by \allejo\stakx\Document\B...n->getConfiguration())) on line 173 can also be of type object<allejo\stakx\Document\RepeaterPageView> or object<allejo\stakx\Document\StaticPageView>; however, allejo\stakx\Manager\Pag...ckableDynamicPageView() does only seem to accept object<allejo\stakx\Document\DynamicPageView>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
186 3
                break;
187
188 2
            case BasePageView::REPEATER_TYPE:
189 2
                $this->handleTrackableRepeaterPageView($pageView);
0 ignored issues
show
Bug introduced by
It seems like $pageView defined by \allejo\stakx\Document\B...n->getConfiguration())) on line 173 can also be of type object<allejo\stakx\Document\DynamicPageView> or object<allejo\stakx\Document\StaticPageView>; however, allejo\stakx\Manager\Pag...kableRepeaterPageView() does only seem to accept object<allejo\stakx\Document\RepeaterPageView>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
190 2
                break;
191
192
            default:
193
                break;
194
        }
195
196 17
        $this->addObjectToTracker($pageView, $namespace);
197
198 17
        return $pageView;
199
    }
200
201
    /**
202
     * Handle special behavior and treatment for static PageViews while we're iterating through them.
203
     *
204
     * @param StaticPageView $pageView
205
     *
206
     * @since 0.1.0
207
     */
208 12
    private function handleTrackableStaticPageView(&$pageView)
209
    {
210 12
        $pageView->evaluateFrontMatter([], [
211 12
            'site' => $this->configuration->getConfiguration(),
212
        ]);
213
214 12
        if (empty($pageView['title']))
215
        {
216 12
            return;
217
        }
218
219 2
        $this->staticPages[$pageView['title']] = &$pageView;
220 2
    }
221
222
    /**
223
     * Handle special behavior and treatment for dynamic PageViews while we're iterating through them.
224
     *
225
     * @param DynamicPageView $pageView
226
     *
227
     * @since 0.1.0
228
     *
229
     * @throws \Exception
230
     */
231 4
    private function handleTrackableDynamicPageView(&$pageView)
232
    {
233 4
        $frontMatter = $pageView->getRawFrontMatter();
234 4
        $dataSource = null;
235 4
        $namespace = null;
236
237 4
        if (isset($frontMatter['collection']))
238
        {
239 4
            $dataSource = &$this->collectionManager->getCollections();
240 4
            $namespace = 'collection';
241
        }
242
        elseif (isset($frontMatter['dataset']))
243
        {
244
            $dataSource = &$this->dataManager->getDataItems();
245
            $namespace = 'dataset';
246
        }
247
248 4
        if ($dataSource === null)
249
        {
250
            throw new \Exception('Invalid Dynamic PageView defined');
251
        }
252
253 4
        $collection = $frontMatter[$namespace];
254
255 4
        if (!isset($dataSource[$collection]))
256
        {
257 1
            throw new CollectionNotFoundException("The '$collection' $namespace is not defined");
258
        }
259
260
        /** @var ContentItem|DataItem $item */
261 3
        foreach ($dataSource[$collection] as &$item)
262
        {
263 3
            $item->evaluateFrontMatter($frontMatter, [
264 3
                'site' => $this->configuration->getConfiguration(),
265
            ]);
266 3
            $item->setParentPageView($pageView);
267 3
            $item->buildPermalink(true);
268
269 3
            $pageView->addCollectableItem($item);
270
        }
271 3
    }
272
273
    /**
274
     * Handle special behavior and treatment for repeater PageViews while we're iterating through them.
275
     *
276
     * @param RepeaterPageView $pageView
277
     *
278
     * @since 0.2.0
279
     */
280 2
    private function handleTrackableRepeaterPageView(&$pageView)
281
    {
282 2
        $pageView->evaluateFrontMatter([], [
283 2
            'site' => $this->configuration->getConfiguration(),
284
        ]);
285 2
        $pageView->configurePermalinks();
286 2
    }
287
}
288