Completed
Push — feature-output-formats ( 62e575...6f55bd )
by Arnaud
02:00
created

PagesRender::getFormats()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 21
rs 9.584
c 0
b 0
f 0
cc 4
nc 4
nop 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
        /* @var $page Page */
63
        foreach ($filteredPages as $page) {
64
            $count++;
65
            $formats = ['html'];
0 ignored issues
show
Unused Code introduced by
$formats is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
66
            $rendered = null;
67
            $alternates = [];
0 ignored issues
show
Unused Code introduced by
$alternates is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
68
69
            // get page's output formats
70
            $formats = $this->getFormats($page);
71
            $page->setVariable('output', $formats);
72
73
            // get pages's alternates links
74
            $alternates = $this->getAlternates($page, $formats);
75
            $page->setVariable('alternates', $alternates);
76
77
            // render each output format
78
            foreach ($formats as $format) {
79
                // escape redirect pages
80
                if ($format != 'html' && $page->hasVariable('destination')) {
81
                    continue;
82
                }
83
                // search for the template
84
                $layout = Layout::finder($page, $format, $this->config);
85
                // render with Twig
86
                $rendered[$format]['output'] = $this->builder->getRenderer()->render(
87
                    $layout,
88
                    ['page' => $page]
89
                );
90
                $rendered[$format]['template'] = $layout;
91
            }
92
            $page->setVariable('rendered', $rendered);
93
            $this->builder->getPages()->replace($page->getId(), $page);
94
95
            $layouts = implode(', ', array_column($rendered, 'template'));
96
            $message = sprintf('%s (%s)', ($page->getId() ?: 'index'), $layouts);
97
            call_user_func_array($this->builder->getMessageCb(), ['RENDER_PROGRESS', $message, $count, $max]);
98
        }
99
    }
100
101
    /**
102
     * Return an array of layouts directories.
103
     *
104
     * @return array
105
     */
106
    protected function getAllLayoutsPaths(): array
107
    {
108
        $paths = [];
109
110
        // layouts/
111
        if (is_dir($this->config->getLayoutsPath())) {
112
            $paths[] = $this->config->getLayoutsPath();
113
        }
114
        // <theme>/layouts/
115
        if ($this->config->hasTheme()) {
116
            $themes = $this->config->getTheme();
117
            foreach ($themes as $theme) {
118
                $paths[] = $this->config->getThemeDirPath($theme);
119
            }
120
        }
121
        // res/layouts/
122
        if (is_dir($this->config->getInternalLayoutsPath())) {
123
            $paths[] = $this->config->getInternalLayoutsPath();
124
        }
125
126
        return $paths;
127
    }
128
129
    /**
130
     * Add globals variables.
131
     */
132
    protected function addGlobals()
133
    {
134
        // adds global variables
135
        $this->builder->getRenderer()->addGlobal('site', array_merge(
136
            $this->config->get('site'),
137
            ['menus' => $this->builder->getMenus()],
138
            ['pages' => $this->builder->getPages()->filter(function (Page $page) {
139
                return $page->getVariable('published');
140
            })],
141
            ['time' => time()]
142
        ));
143
        $this->builder->getRenderer()->addGlobal('cecil', [
144
            'url'       => sprintf('https://cecil.app/#%s', $this->builder->getVersion()),
145
            'version'   => $this->builder->getVersion(),
146
            'poweredby' => sprintf('Cecil v%s', $this->builder->getVersion()),
147
        ]);
148
    }
149
150
    /**
151
     * Get available formats.
152
     *
153
     * @param Page $page
154
     *
155
     * @return array
156
     */
157
    protected function getFormats(Page $page): array
158
    {
159
        $formats = [];
160
161
        // Get page format(s).
162
        // ie: "output: txt"
163
        if ($page->getVariable('output')) {
164
            $formats = $page->getVariable('output');
165
            if (!\is_array($formats)) {
166
                $formats = [$formats];
167
            }
168
        } else {
169
            // get available formats for page type
170
            // ie: "'page' => ['html', 'json']"
171
            if (\is_array($this->config->get('site.output.pagetypeformats.'.$page->getType()))) {
172
                $formats = $this->config->get('site.output.pagetypeformats.'.$page->getType());
173
            }
174
        }
175
176
        return $formats;
177
    }
178
179
    /**
180
     * Get page's alternates.
181
     *
182
     * @param Page $page
183
     * @param array $formats
184
     *
185
     * @return array
186
     *
187
     * @todo do it better! :-D
188
     */
189
    protected function getAlternates(Page $page, array $formats): array
190
    {
191
        $alternates = [];
192
193
        if (count($formats) > 1 && array_key_exists('html', $formats)) {
194
            foreach ($formats as $format) {
195
                if ($format == 'html') {
196
                    $alternates[] = [
197
                        'rel'   => 'canonical',
198
                        'type'  => $this->config->get('site.output.formats.html.mediatype'),
199
                        'title' => 'HTML',
200
                        'href'  => $page->getPathname(), // you should use use "url()" in template
201
                    ];
202
                    continue;
203
                }
204
                $alternates[] = [
205
                    'rel'   => 'alternate',
206
                    'type'  => $this->config->get("site.output.formats.$format.mediatype"),
207
                    'title' => strtoupper($format),
208
                    'href'  => $page->getPathname(), // should use "url()" in template
209
                ];
210
            }
211
        }
212
213
        return $alternates;
214
    }
215
}
216