Passed
Push — di ( 61d74f...f00c6d )
by Arnaud
15:03 queued 11:43
created

Convert::convertPage()   A

Complexity

Conditions 6
Paths 7

Size

Total Lines 27
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 16
nc 7
nop 4
dl 0
loc 27
rs 9.1111
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * This file is part of Cecil.
5
 *
6
 * (c) Arnaud Ligny <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Cecil\Step\Pages;
15
16
use Cecil\Builder;
17
use Cecil\Collection\Page\Page;
18
use Cecil\Converter\Converter;
19
use Cecil\Converter\ConverterInterface;
20
use Cecil\Exception\RuntimeException;
21
use Cecil\Step\AbstractStep;
22
use Cecil\Util;
23
24
/**
25
 * Convert step.
26
 *
27
 * This step is responsible for converting pages from their source format
28
 * (i.e. Markdown) to HTML, applying front matter processing,
29
 * and ensuring that the pages are ready for rendering. It handles both
30
 * published and draft pages, depending on the build options.
31
 */
32
class Convert extends AbstractStep
33
{
34
    /** @var Converter */
35
    protected $converter;
36
37
    public function __construct(Converter $converter)
38
    {
39
        $this->converter = $converter;
40
    }
41
42
    /**
43
     * {@inheritdoc}
44
     */
45
    public function getName(): string
46
    {
47
        if ($this->builder->getBuildOptions()['drafts']) {
48
            return 'Converting pages (drafts included)';
49
        }
50
51
        return 'Converting pages';
52
    }
53
54
    /**
55
     * {@inheritdoc}
56
     */
57
    public function init(array $options): void
58
    {
59
        parent::init($options);
60
61
        if (\is_null($this->builder->getPages())) {
62
            $this->canProcess = false;
63
        }
64
    }
65
66
    /**
67
     * {@inheritdoc}
68
     */
69
    public function process(): void
70
    {
71
        if (!is_iterable($this->builder->getPages()) || \count($this->builder->getPages()) == 0) {
72
            return;
73
        }
74
75
        $total = \count($this->builder->getPages());
76
        $count = 0;
77
        /** @var Page $page */
78
        foreach ($this->builder->getPages() as $page) {
79
            if (!$page->isVirtual()) {
80
                $count++;
81
82
                try {
83
                    $convertedPage = $this->convertPage($this->builder, $page);
84
                    // set default language (ex: "en") if necessary
85
                    if ($convertedPage->getVariable('language') === null) {
86
                        $convertedPage->setVariable('language', $this->config->getLanguageDefault());
87
                    }
88
                } catch (RuntimeException $e) {
89
                    $this->builder->getLogger()->error(\sprintf('Unable to convert "%s:%s": %s', $e->getFile(), $e->getLine(), $e->getMessage()));
90
                    $this->builder->getPages()->remove($page->getId());
91
                    continue;
92
                } catch (\Exception $e) {
93
                    $this->builder->getLogger()->error(\sprintf('Unable to convert "%s": %s', Util::joinPath(Util\File::getFS()->makePathRelative($page->getFilePath(), $this->config->getPagesPath())), $e->getMessage()));
94
                    $this->builder->getPages()->remove($page->getId());
95
                    continue;
96
                }
97
                $message = \sprintf('Page "%s" converted', $page->getId());
98
                $statusMessage = ' (not published)';
99
                // forces drafts convert?
100
                if ($this->builder->getBuildOptions()['drafts']) {
101
                    $page->setVariable('published', true);
102
                }
103
                // replaces page in collection
104
                if ($page->getVariable('published')) {
105
                    $this->builder->getPages()->replace($page->getId(), $convertedPage);
106
                    $statusMessage = '';
107
                }
108
                $this->builder->getLogger()->info($message . $statusMessage, ['progress' => [$count, $total]]);
109
            }
110
        }
111
    }
112
113
    /**
114
     * Converts page content:
115
     *  - front matter to PHP array
116
     *  - body to HTML.
117
     *
118
     * @throws RuntimeException
119
     */
120
    public function convertPage(Builder $builder, Page $page, ?string $format = null, ?ConverterInterface $converter = null): Page
121
    {
122
        $format = $format ?? (string) $builder->getConfig()->get('pages.frontmatter');
123
        $converter = $converter ?? $this->converter;
124
125
        // converts front matter
126
        if ($page->getFrontmatter()) {
127
            try {
128
                $variables = $converter->convertFrontmatter($page->getFrontmatter(), $format);
129
            } catch (RuntimeException $e) {
130
                throw new RuntimeException($e->getMessage(), file: $page->getFilePath(), line: $e->getLine());
131
            }
132
            $page->setFmVariables($variables);
133
            $page->setVariables($variables);
134
        }
135
136
        // converts body (only if page is published or drafts option is enabled)
137
        if ($page->getVariable('published') || $this->options['drafts']) {
138
            try {
139
                $html = $converter->convertBody($page->getBody());
140
            } catch (RuntimeException $e) {
141
                throw new \Exception($e->getMessage());
142
            }
143
            $page->setBodyHtml($html);
144
        }
145
146
        return $page;
147
    }
148
}
149