Completed
Push — code ( eb95c2 )
by Arnaud
02:14
created

PagesRender   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 107
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Importance

Changes 0
Metric Value
wmc 12
lcom 1
cbo 8
dl 0
loc 107
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A init() 0 11 3
A process() 0 33 3
A getAllLayoutsPaths() 0 22 5
A addGlobals() 0 17 1
1
<?php
2
/*
3
 * Copyright (c) Arnaud Ligny <[email protected]>
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
9
namespace Cecil\Step;
10
11
use Cecil\Collection\Page\Page;
12
use Cecil\Exception\Exception;
13
use Cecil\Renderer\Layout;
14
use Cecil\Renderer\Twig as Twig;
15
16
/**
17
 * Pages rendering.
18
 */
19
class PagesRender extends AbstractStep
20
{
21
    /**
22
     * {@inheritdoc}
23
     *
24
     * @throws Exception
25
     */
26
    public function init($options)
27
    {
28
        if (!is_dir($this->config->getLayoutsPath()) && !$this->config->hasTheme()) {
29
            throw new Exception(sprintf(
30
                "'%s' is not a valid layouts directory",
31
                $this->config->getLayoutsPath()
32
            ));
33
        }
34
35
        $this->process = true;
36
    }
37
38
    /**
39
     * {@inheritdoc}
40
     *
41
     * @throws Exception
42
     */
43
    public function process()
44
    {
45
        // prepares renderer
46
        $this->builder->setRenderer(new Twig($this->getAllLayoutsPaths(), $this->config));
47
48
        // add globals variables
49
        $this->addGlobals();
50
51
        call_user_func_array($this->builder->getMessageCb(), ['RENDER', 'Rendering pages']);
52
53
        // collect published pages
54
        /* @var $page Page */
55
        $filteredPages = $this->builder->getPages()->filter(function (Page $page) {
56
            return !empty($page->getVariable('published'));
57
        });
58
        $max = count($filteredPages);
59
60
        // render each page
61
        $count = 0;
62
        foreach ($filteredPages as $page) {
63
            $count++;
64
65
            $rendered = $this->builder->getRenderer()->render(
66
                $layout = (new Layout())->finder($page, $this->config),
67
                ['page' => $page]
68
            );
69
            $page->setVariable('rendered', $rendered);
70
            $this->builder->getPages()->replace($page->getId(), $page);
71
72
            $message = sprintf('%s (%s)', ($page->getId() ?: 'index'), $layout);
73
            call_user_func_array($this->builder->getMessageCb(), ['RENDER_PROGRESS', $message, $count, $max]);
74
        }
75
    }
76
77
    /**
78
     * Return an array of layouts directories.
79
     *
80
     * @return array Layouts directory
81
     */
82
    protected function getAllLayoutsPaths()
83
    {
84
        $paths = [];
85
86
        // layouts/
87
        if (is_dir($this->config->getLayoutsPath())) {
88
            $paths[] = $this->config->getLayoutsPath();
89
        }
90
        // <theme>/layouts/
91
        if ($this->config->hasTheme()) {
92
            $themes = $this->config->getTheme();
93
            foreach ($themes as $theme) {
94
                $paths[] = $this->config->getThemeDirPath($theme);
95
            }
96
        }
97
        // res/layouts/
98
        if (is_dir($this->config->getInternalLayoutsPath())) {
99
            $paths[] = $this->config->getInternalLayoutsPath();
100
        }
101
102
        return $paths;
103
    }
104
105
    /**
106
     * Add globals variables.
107
     */
108
    protected function addGlobals()
109
    {
110
        // adds global variables
111
        $this->builder->getRenderer()->addGlobal('site', array_merge(
112
            $this->config->get('site'),
113
            ['menus' => $this->builder->getMenus()],
114
            ['pages' => $this->builder->getPages()->filter(function (Page $page) {
115
                return $page->getVariable('published');
116
            })],
117
            ['time' => time()]
118
        ));
119
        $this->builder->getRenderer()->addGlobal('cecil', [
120
            'url'       => sprintf('https://cecil.app/#%s', $this->builder->getVersion()),
121
            'version'   => $this->builder->getVersion(),
122
            'poweredby' => sprintf('Cecil v%s', $this->builder->getVersion()),
123
        ]);
124
    }
125
}
126