Passed
Push — master ( 29bd61...08926b )
by Brent
06:03
created

CollectionAdapter::transform()   B

Complexity

Conditions 5
Paths 3

Size

Total Lines 33
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 22
nc 3
nop 2
dl 0
loc 33
rs 8.439
c 0
b 0
f 0
1
<?php
2
3
namespace Brendt\Stitcher\Adapter;
4
5
use Brendt\Stitcher\Exception\ConfigurationException;
6
use Brendt\Stitcher\Exception\IdFieldNotFoundException;
7
use Brendt\Stitcher\Exception\VariableNotFoundException;
8
use Brendt\Stitcher\Factory\AdapterFactory;
9
use Brendt\Stitcher\Site\Page;
10
11
/**
12
 * The CollectionAdapter takes a page with a collection of entries, and generates a detail page for each entry in the
13
 * collection.
14
 *
15
 * Sample configuration:
16
 *
17
 *  /examples/{id}:
18
 *      template: examples/detail
19
 *      data:
20
 *          example: collection.yml
21
 *      adapters:
22
 *          collection:
23
 *              variable: example
24
 *              field: id
25
 */
26
class CollectionAdapter extends AbstractAdapter
27
{
28
    /**
29
     * @param Page $page
30
     * @param null $filter
31
     *
32
     * @return Page[]
33
     */
34
    public function transformPage(Page $page, $filter = null) : array {
35
        $config = $page->getAdapterConfig(AdapterFactory::COLLECTION_ADAPTER);
36
37
        $this->validateConfig($config, $page);
38
39
        $variable = $config['variable'];
40
        $source = $page->getVariable($variable);
41
        $field = $config['field'];
42
        $pageId = $page->getId();
43
        $entries = $this->getData($source);
44
45
        $result = [];
46
        foreach ($entries as $entry) {
47
            if (!isset($entry[$field]) || ($filter && $entry[$field] !== $filter)) {
48
                continue;
49
            }
50
51
            $fieldValue = $entry[$field];
52
53
            $url = str_replace('{' . $field . '}', $fieldValue, $pageId);
54
            $entryPage = clone $page;
55
56
            $entryPage
57
                ->removeAdapter(AdapterFactory::COLLECTION_ADAPTER)
58
                ->setVariableValue($variable, $entry)
59
                ->setVariableIsParsed($variable)
60
                ->setId($url);
61
62
            $result[$url] = $entryPage;
63
        }
64
65
        return $result;
66
    }
67
68
    /**
69
     * @param array $config
70
     * @param Page  $page
71
     *
72
     * @return void
73
     * @throws ConfigurationException
74
     * @throws IdFieldNotFoundException
75
     * @throws VariableNotFoundException
76
     */
77
    protected function validateConfig(array $config, Page $page) {
78
        if (!isset($config['field'], $config['variable'])) {
79
            throw new ConfigurationException('Both the configuration entry `field` and `variable` are required when using the Collection adapter.');
80
        }
81
82
        $variable = $config['variable'];
83
84
        if (!$page->getVariable($variable)) {
85
            throw new VariableNotFoundException("Variable \"{$variable}\" was not set as a data variable for page \"{$page->getId()}\"");
86
        }
87
88
        $field = $config['field'];
89
        $pageId = $page->getId();
90
91
        if (strpos($pageId, '{' . $field . '}') === false) {
92
            throw new IdFieldNotFoundException("The field \"{{$field}}\" was not found in the URL \"{$page->getId()}\"");
93
        }
94
    }
95
96
}
97