• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Cecilapp / Cecil / 21143060241

19 Jan 2026 03:29PM UTC coverage: 82.458%. First build
21143060241

Pull #2285

github

web-flow
Merge 74346fd11 into 878eab640
Pull Request #2285: Integrate PHP-DI for dependency injection

60 of 76 new or added lines in 16 files covered. (78.95%)

3328 of 4036 relevant lines covered (82.46%)

0.82 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

80.43
/src/Step/Pages/Convert.php
1
<?php
2

3
/**
4
 * This file is part of Cecil.
5
 *
6
 * (c) Arnaud Ligny <arnaud@ligny.fr>
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 DI\Attribute\Inject;
25
use Psr\Log\LoggerInterface;
26

27
/**
28
 * Convert step.
29
 *
30
 * This step is responsible for converting pages from their source format
31
 * (i.e. Markdown) to HTML, applying front matter processing,
32
 * and ensuring that the pages are ready for rendering. It handles both
33
 * published and draft pages, depending on the build options.
34
 */
35
class Convert extends AbstractStep
36
{
37
    #[Inject]
38
    private Converter $converter;
39

40
    /**
41
     * {@inheritdoc}
42
     */
43
    public function getName(): string
44
    {
45
        if ($this->builder->getBuildOptions()['drafts']) {
1✔
46
            return 'Converting pages (drafts included)';
1✔
47
        }
48

49
        return 'Converting pages';
×
50
    }
51

52
    /**
53
     * {@inheritdoc}
54
     */
55
    public function init(array $options): void
56
    {
57
        parent::init($options);
1✔
58

59
        if (\is_null($this->builder->getPages())) {
1✔
60
            $this->canProcess = false;
×
61
        }
62
    }
63

64
    /**
65
     * {@inheritdoc}
66
     */
67
    public function process(): void
68
    {
69
        if (!is_iterable($this->builder->getPages()) || \count($this->builder->getPages()) == 0) {
1✔
70
            return;
×
71
        }
72

73
        $total = \count($this->builder->getPages());
1✔
74
        $count = 0;
1✔
75
        /** @var Page $page */
76
        foreach ($this->builder->getPages() as $page) {
1✔
77
            if (!$page->isVirtual()) {
1✔
78
                $count++;
1✔
79

80
                try {
81
                    $convertedPage = $this->convertPage($this->builder, $page);
1✔
82
                    // set default language (ex: "en") if necessary
83
                    if ($convertedPage->getVariable('language') === null) {
1✔
84
                        $convertedPage->setVariable('language', $this->config->getLanguageDefault());
1✔
85
                    }
86
                } catch (RuntimeException $e) {
1✔
87
                    $this->logger->error(\sprintf('Unable to convert "%s:%s": %s', $e->getFile(), $e->getLine(), $e->getMessage()));
1✔
88
                    $this->builder->getPages()->remove($page->getId());
1✔
89
                    continue;
1✔
90
                } catch (\Exception $e) {
×
NEW
91
                    $this->logger->error(\sprintf('Unable to convert "%s": %s', Util::joinPath(Util\File::getFS()->makePathRelative($page->getFilePath(), $this->config->getPagesPath())), $e->getMessage()));
×
92
                    $this->builder->getPages()->remove($page->getId());
×
93
                    continue;
×
94
                }
95
                $message = \sprintf('Page "%s" converted', $page->getId());
1✔
96
                $statusMessage = ' (not published)';
1✔
97
                // forces drafts convert?
98
                if ($this->builder->getBuildOptions()['drafts']) {
1✔
99
                    $page->setVariable('published', true);
1✔
100
                }
101
                // replaces page in collection
102
                if ($page->getVariable('published')) {
1✔
103
                    $this->builder->getPages()->replace($page->getId(), $convertedPage);
1✔
104
                    $statusMessage = '';
1✔
105
                }
106
                $this->logger->info($message . $statusMessage, ['progress' => [$count, $total]]);
1✔
107
            }
108
        }
109
    }
110

111
    /**
112
     * Converts page content:
113
     *  - front matter to PHP array
114
     *  - body to HTML.
115
     *
116
     * @throws RuntimeException
117
     */
118
    public function convertPage(Builder $builder, Page $page, ?string $format = null, ?ConverterInterface $converter = null): Page
119
    {
120
        $format = $format ?? (string) $builder->getConfig()->get('pages.frontmatter');
1✔
121
        $converter = $converter ?? $this->converter;
1✔
122

123
        // converts front matter
124
        if ($page->getFrontmatter()) {
1✔
125
            try {
126
                $variables = $converter->convertFrontmatter($page->getFrontmatter(), $format);
1✔
127
            } catch (RuntimeException $e) {
1✔
128
                throw new RuntimeException($e->getMessage(), file: $page->getFilePath(), line: $e->getLine());
1✔
129
            }
130
            $page->setFmVariables($variables);
1✔
131
            $page->setVariables($variables);
1✔
132
        }
133

134
        // converts body (only if page is published or drafts option is enabled)
135
        if ($page->getVariable('published') || $this->options['drafts']) {
1✔
136
            try {
137
                $html = $converter->convertBody($page->getBody());
1✔
138
            } catch (RuntimeException $e) {
×
139
                throw new \Exception($e->getMessage());
×
140
            }
141
            $page->setBodyHtml($html);
1✔
142
        }
143

144
        return $page;
1✔
145
    }
146
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc