Completed
Push — feature-output-formats ( f5696a...244939 )
by Arnaud
02:20
created

PagesRender::process()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 42

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 42
rs 8.9368
c 0
b 0
f 0
cc 5
nc 5
nop 0
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
            // WIP
66
            if ($page->getVariable('output')) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
67
68
            }
69
70
            foreach ($page->getVariable('output') as $format) {
71
                $rendered = $this->builder->getRenderer()->render(
72
                    $layout = (new Layout())->finder($page, $this->config),
0 ignored issues
show
Bug introduced by
The call to finder() misses a required argument $config.

This check looks for function calls that miss required arguments.

Loading history...
Documentation introduced by
$this->config is of type object<Cecil\Config>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
73
                    ['page' => $page]
74
                );
75
            }
76
77
78
            $page->setVariable('rendered', $rendered);
0 ignored issues
show
Bug introduced by
The variable $rendered does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
79
            $this->builder->getPages()->replace($page->getId(), $page);
80
81
            $message = sprintf('%s (%s)', ($page->getId() ?: 'index'), $layout);
0 ignored issues
show
Bug introduced by
The variable $layout does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
82
            call_user_func_array($this->builder->getMessageCb(), ['RENDER_PROGRESS', $message, $count, $max]);
83
        }
84
    }
85
86
    /**
87
     * Return an array of layouts directories.
88
     *
89
     * @return array Layouts directory
90
     */
91
    protected function getAllLayoutsPaths()
92
    {
93
        $paths = [];
94
95
        // layouts/
96
        if (is_dir($this->config->getLayoutsPath())) {
97
            $paths[] = $this->config->getLayoutsPath();
98
        }
99
        // <theme>/layouts/
100
        if ($this->config->hasTheme()) {
101
            $themes = $this->config->getTheme();
102
            foreach ($themes as $theme) {
103
                $paths[] = $this->config->getThemeDirPath($theme);
104
            }
105
        }
106
        // res/layouts/
107
        if (is_dir($this->config->getInternalLayoutsPath())) {
108
            $paths[] = $this->config->getInternalLayoutsPath();
109
        }
110
111
        return $paths;
112
    }
113
114
    /**
115
     * Add globals variables.
116
     */
117
    protected function addGlobals()
118
    {
119
        // adds global variables
120
        $this->builder->getRenderer()->addGlobal('site', array_merge(
121
            $this->config->get('site'),
122
            ['menus' => $this->builder->getMenus()],
123
            ['pages' => $this->builder->getPages()->filter(function (Page $page) {
124
                return $page->getVariable('published');
125
            })],
126
            ['time' => time()]
127
        ));
128
        $this->builder->getRenderer()->addGlobal('cecil', [
129
            'url'       => sprintf('https://cecil.app/#%s', $this->builder->getVersion()),
130
            'version'   => $this->builder->getVersion(),
131
            'poweredby' => sprintf('Cecil v%s', $this->builder->getVersion()),
132
        ]);
133
    }
134
}
135