Passed
Push — analysis-A7yJ5k ( c97a2e )
by Arnaud
10:56 queued 05:11
created

Convert::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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