Passed
Push — develop ( 7fa55c...bce364 )
by Brent
02:48
created

CollectionAdapter::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 2
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace Brendt\Stitcher\Adapter;
4
5
use Brendt\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
36
    public function __construct(ParserFactory $parserFactory, MetaCompiler $metaCompiler) {
37
        parent::__construct($parserFactory);
38
39
        $this->metaCompiler = $metaCompiler;
40
    }
41
42
    /**
43
     * @param Page $page
44
     * @param null $filter
45
     *
46
     * @return Page[]
47
     */
48
    public function transformPage(Page $page, $filter = null) : array {
49
        $config = $page->getAdapterConfig(AdapterFactory::COLLECTION_ADAPTER);
50
51
        $this->validateConfig($config, $page);
52
53
        $variable = $config['variable'];
54
        $source = $page->getVariable($variable);
55
        $field = $config['field'];
56
        $pageId = $page->getId();
57
        $entries = $this->getData($source);
58
59
        $result = [];
60
        foreach ($entries as $entry) {
61
            if (!isset($entry[$field]) || ($filter && $entry[$field] !== $filter)) {
62
                continue;
63
            }
64
65
            $fieldValue = $entry[$field];
66
67
            $url = str_replace('{' . $field . '}', $fieldValue, $pageId);
68
            $entryPage = clone $page;
69
70
            foreach ($entry as $entryVariableName => $entryVariableValue) {
71
                $this->metaCompiler->compilePageVariable($entryPage, $entryVariableName, $entryVariableValue);
72
            }
73
74
            $entryPage
75
                ->removeAdapter(AdapterFactory::COLLECTION_ADAPTER)
76
                ->setVariableValue($variable, $entry)
77
                ->setVariableIsParsed($variable)
78
                ->setId($url);
79
80
            $result[$url] = $entryPage;
81
        }
82
83
        return $result;
84
    }
85
86
    /**
87
     * @param array $config
88
     * @param Page  $page
89
     *
90
     * @return void
91
     * @throws ConfigurationException
92
     * @throws IdFieldNotFoundException
93
     * @throws VariableNotFoundException
94
     */
95
    protected function validateConfig(array $config, Page $page) {
96
        if (!isset($config['field'], $config['variable'])) {
97
            throw new ConfigurationException('Both the configuration entry `field` and `variable` are required when using the Collection adapter.');
98
        }
99
100
        $variable = $config['variable'];
101
102
        if (!$page->getVariable($variable)) {
103
            throw new VariableNotFoundException("Variable \"{$variable}\" was not set as a data variable for page \"{$page->getId()}\"");
104
        }
105
106
        $field = $config['field'];
107
        $pageId = $page->getId();
108
109
        if (strpos($pageId, '{' . $field . '}') === false) {
110
            throw new IdFieldNotFoundException("The field \"{{$field}}\" was not found in the URL \"{$page->getId()}\"");
111
        }
112
    }
113
}
114