Passed
Push — develop ( 403463...a93e70 )
by Brent
03:12
created

CollectionAdapter::createEntryPage()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 19
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 13
nc 2
nop 2
dl 0
loc 19
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace Brendt\Stitcher\Adapter;
4
5
use Pageon\Html\Meta\Meta;
6
use Brendt\Stitcher\Exception\ConfigurationException;
7
use Brendt\Stitcher\Exception\IdFieldNotFoundException;
8
use Brendt\Stitcher\Exception\VariableNotFoundException;
9
use Brendt\Stitcher\Factory\AdapterFactory;
10
use Brendt\Stitcher\factory\ParserFactory;
11
use Brendt\Stitcher\Site\Meta\MetaCompiler;
12
use Brendt\Stitcher\Site\Page;
13
14
/**
15
 * The CollectionAdapter takes a page with a collection of entries, and generates a detail page for each entry in the
16
 * collection.
17
 *
18
 * Sample configuration:
19
 *
20
 *  /examples/{id}:
21
 *      template: examples/detail
22
 *      data:
23
 *          variableName: collection.yml
24
 *      adapters:
25
 *          variableName:
26
 *              variable: example
27
 *              field: id
28
 */
29
class CollectionAdapter extends AbstractAdapter
30
{
31
    /**
32
     * @var MetaCompiler
33
     */
34
    private $metaCompiler;
35
    private $variable = null;
36
    private $field = null;
37
    private $entries = [];
38
39
    public function __construct(ParserFactory $parserFactory, MetaCompiler $metaCompiler) {
40
        parent::__construct($parserFactory);
41
42
        $this->metaCompiler = $metaCompiler;
43
    }
44
45
    public function transformPage(Page $page, $filter = null) : array {
46
        $config = $page->getAdapterConfig(AdapterFactory::COLLECTION_ADAPTER);
47
48
        $this->validateConfig($config, $page);
49
50
        $this->variable = $config['variable'];
51
        $this->field = $config['field'];
52
        $this->entries = $this->getData($page->getVariable($this->variable));
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->getData($page->ge...iable($this->variable)) of type * is incompatible with the declared type array of property $entries.

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...
53
54
        $result = [];
55
        reset($this->entries);
56
        while ($entry = current($this->entries)) {
57
            if (isset($entry[$this->field]) && (!$filter || $entry[$this->field] === $filter)) {
58
                $entryPage = $this->createEntryPage($page, $entry);
59
                $result[$entryPage->getId()] = $entryPage;
60
            }
61
62
            next($this->entries);
63
        }
64
65
        return $result;
66
    }
67
68
    private function createEntryPage(Page $page, array $entry) : Page {
69
        $url = str_replace('{' . $this->field . '}', $entry[$this->field], $page->getId());
70
        $entryPage = clone $page;
71
        $entryPage->meta = new Meta();
72
73
        foreach ($entry as $entryVariableName => $entryVariableValue) {
74
            $this->metaCompiler->compilePageVariable($entryPage, $entryVariableName, $entryVariableValue);
75
        }
76
77
        $entryPage
78
            ->removeAdapter(AdapterFactory::COLLECTION_ADAPTER)
79
            ->setVariableValue($this->variable, $entry)
80
            ->setVariableIsParsed($this->variable)
81
            ->setId($url);
82
83
        $this->parseBrowseData($entryPage);
84
85
        return $entryPage;
86
    }
87
88
    /**
89
     * @param Page  $entryPage
90
     *
91
     * @return void
92
     */
93
    private function parseBrowseData(Page $entryPage) {
94
        if ($entryPage->getVariable('browse')) {
95
            return;
96
        }
97
98
        $prev = prev($this->entries);
99
100
        if (!$prev) {
101
            reset($this->entries);
102
        } else {
103
            next($this->entries);
104
        }
105
106
        $next = next($this->entries);
107
108
        $entryPage->setVariableValue('browse', [
109
            'prev' => $prev,
110
            'next' => $next,
111
        ])->setVariableIsParsed('browse');
112
113
        prev($this->entries);
114
    }
115
116
    /**
117
     * @param array $config
118
     * @param Page  $page
119
     *
120
     * @return void
121
     * @throws ConfigurationException
122
     * @throws IdFieldNotFoundException
123
     * @throws VariableNotFoundException
124
     */
125
    protected function validateConfig(array $config, Page $page) {
126
        if (!isset($config['field'], $config['variable'])) {
127
            throw new ConfigurationException('Both the configuration entry `field` and `variable` are required when using the Collection adapter.');
128
        }
129
130
        $variable = $config['variable'];
131
132
        if (!$page->getVariable($variable)) {
133
            throw new VariableNotFoundException("Variable \"{$variable}\" was not set as a data variable for page \"{$page->getId()}\"");
134
        }
135
136
        $field = $config['field'];
137
        $pageId = $page->getId();
138
139
        if (strpos($pageId, '{' . $field . '}') === false) {
140
            throw new IdFieldNotFoundException("The field \"{{$field}}\" was not found in the URL \"{$page->getId()}\"");
141
        }
142
    }
143
}
144