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

aphiria / aphiria.com / 19786314830

29 Nov 2025 04:18PM UTC coverage: 65.472% (-1.6%) from 67.052%
19786314830

push

github

web-flow
Fixed Psalm and PHP-CS-Fixer issues (#88)

60 of 85 new or added lines in 12 files covered. (70.59%)

3 existing lines in 2 files now uncovered.

347 of 530 relevant lines covered (65.47%)

7.1 hits per line

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

1.37
/src/Web/ViewCompiler.php
1
<?php
2

3
/**
4
 * Aphiria
5
 *
6
 * @link      https://www.aphiria.com
7
 * @copyright Copyright (C) 2025 David Young
8
 * @license   https://github.com/aphiria/aphiria.com/blob/master/LICENSE.md
9
 */
10

11
declare(strict_types=1);
12

13
namespace App\Web;
14

15
use App\Documentation\DocumentationMetadata;
16
use League\Flysystem\FilesystemException;
17
use League\Flysystem\FilesystemOperator;
18
use League\Flysystem\StorageAttributes;
19

20
/**
21
 * Defines the compiler for our views
22
 */
23
final class ViewCompiler
24
{
25
    /**
26
     * @param string $rawViewPath The path to our raw views
27
     * @param string $compiledViewPath The path to store our compiled views
28
     * @param DocumentationMetadata $docMetadata The doc metadata
29
     * @param FilesystemOperator $files The file system helper
30
     */
31
    public function __construct(
32
        private readonly string $rawViewPath,
33
        private readonly string $compiledViewPath,
34
        private readonly DocumentationMetadata $docMetadata,
35
        private readonly FilesystemOperator $files,
36
    ) {}
12✔
37

38
    /**
39
     * Compiles all of our views
40
     *
41
     * @throws FilesystemException Thrown if a file we expected to be there was not or if we attempted to write to a file that already existed
42
     */
43
    public function compileViews(): void
44
    {
45
        $this->cleanUpExistingCompiledViews();
×
46
        $this->compileHomepage();
×
47
        $this->compileDocs();
×
48
    }
49

50
    /**
51
     * Cleans up any existing compiled views
52
     *
53
     * @throws FilesystemException Thrown if we could not delete the compiled views
54
     */
55
    private function cleanUpExistingCompiledViews(): void
56
    {
57
        /** @var list<string> $compiledHtmlDocPaths */
58
        $compiledHtmlDocPaths = $this->files
×
59
            ->listContents($this->compiledViewPath, true)
×
60
            ->filter(fn(StorageAttributes $attributes) => $attributes->isFile() && \str_ends_with($attributes->path(), '.html'))
×
61
            ->map(fn(StorageAttributes $attributes) => $attributes->path())
×
62
            ->toArray();
×
63

64
        // Delete any compiled views
65
        foreach ($compiledHtmlDocPaths as $compiledHtmlDocPath) {
×
66
            $this->files->delete($compiledHtmlDocPath);
×
67
        }
68

69
        // Delete any compiled doc directories
70
        $this->files->deleteDirectory("$this->compiledViewPath/docs");
×
71
    }
72

73
    /**
74
     * Compiles the partials that are common to all pages
75
     *
76
     * @param string $pageContents The contents of the page to compile
77
     * @param list<string> $metadataKeywords The list of metadata keywords to display
78
     * @param string $metadataDescription The metadata description to display
79
     * @return string The compiled contents
80
     * @throws FilesystemException Thrown if a view partial did not exist
81
     */
82
    private function compileCommonPartials(
83
        string $pageContents,
84
        array $metadataKeywords,
85
        string $metadataDescription,
86
    ): string {
87
        // Compile the head
88
        $headContents = $this->files->read("$this->rawViewPath/partials/head.html");
×
89
        $compiledHeadContents = $this->compileTag('metadataKeywords', \implode(',', $metadataKeywords), $headContents);
×
90
        $compiledHeadContents = $this->compileTag('metadataDescription', $metadataDescription, $compiledHeadContents);
×
91
        $compiledPageContents = $this->compileTag('head', $compiledHeadContents, $pageContents);
×
92

93
        // Compile the main nav
94
        $mainNavContents = $this->files->read("$this->rawViewPath/partials/main-nav.html");
×
95
        $mainNavLinksContents = $this->files->read("$this->rawViewPath/partials/main-nav-links.html");
×
96
        $compiledMainNavContents = $this->compileTag('mainNavLinks', $mainNavLinksContents, $mainNavContents);
×
97
        $compiledPageContents = $this->compileTag('mainNav', $compiledMainNavContents, $compiledPageContents);
×
98

99
        // Compile the footer
100
        $footerContents = $this->files->read("$this->rawViewPath/partials/footer.html");
×
101
        $compiledPageContents = $this->compileTag('footer', $footerContents, $compiledPageContents);
×
102

103
        return $compiledPageContents;
×
104
    }
105

106
    /**
107
     * Compiles our docs
108
     *
109
     * @throws FilesystemException Thrown if a partial file did not exist or if we attempted to write to a file that already existed
110
     */
111
    private function compileDocs(): void
112
    {
113
        $this->files->createDirectory("$this->compiledViewPath/docs", ['visibility' => 'public']);
×
114
        $docTemplatePageContents = $this->files->read("$this->rawViewPath/doc.html");
×
115

116
        // Compile each doc page
117
        foreach ($this->docMetadata->docVersions as $version) {
×
118
            $this->files->createDirectory("$this->compiledViewPath/docs/$version", ['visibility' => 'public']);
×
119

120
            // Compile the doc side nav for each version
121
            $sideNavSectionContents = $this->files->read("$this->rawViewPath/partials/doc-side-nav-contents.html");
×
122
            $allCompiledSectionContents = '';
×
123

124
            foreach ($this->docMetadata->getDocSections($version) as $section => $docs) {
×
125
                $compiledSectionContents = $this->compileTag('docSectionTitle', $section, $sideNavSectionContents);
×
126
                $docSectionListItems = '';
×
127

128
                foreach ($docs as $docName => $doc) {
×
129
                    $docSectionListItems .= '<li><a href="/docs/' . $version . '/' . $docName . '.html" title="View documentation for ' . \strtolower($doc['title']) . '">' . $doc['linkText'] . '</a></li>';
×
130
                }
131

132
                $compiledSectionContents = $this->compileTag('docSectionListItems', $docSectionListItems, $compiledSectionContents);
×
133
                $allCompiledSectionContents .= $compiledSectionContents;
×
134
            }
135

136
            $sideNavContents = $this->files->read("$this->rawViewPath/partials/side-nav.html");
×
137
            $compiledSideNav = $this->compileTag('contents', $allCompiledSectionContents, $sideNavContents);
×
138

139
            // Compile the page
140
            foreach ($this->docMetadata->getDocSections($version) as $docs) {
×
141
                foreach ($docs as $docName => $doc) {
×
142
                    $compiledDocPageContents = $this->compileCommonPartials(
×
143
                        $docTemplatePageContents,
×
144
                        $doc['keywords'],
×
NEW
145
                        $doc['description'],
×
146
                    );
×
147
                    $docContents = $this->files->read("$this->rawViewPath/partials/docs/$version/$docName.html");
×
148
                    $compiledDocPageContents = $this->compileTag('doc', $docContents, $compiledDocPageContents);
×
149
                    $compiledDocPageContents = $this->compileTag('docTitle', $doc['title'], $compiledDocPageContents);
×
150
                    $compiledDocPageContents = $this->compileTag('docVersion', $version, $compiledDocPageContents);
×
151
                    $compiledDocPageContents = $this->compileTag('docFilename', $docName, $compiledDocPageContents);
×
152
                    $compiledDocPageContents = $this->compileTag('sideNav', $compiledSideNav, $compiledDocPageContents);
×
153
                    $this->files->write("$this->compiledViewPath/docs/$version/$docName.html", $compiledDocPageContents);
×
154
                }
155
            }
156
        }
157
    }
158

159
    /**
160
     * Compiles the homepage
161
     *
162
     * @throws FilesystemException Thrown if we could not read a view partial or if we attempted to write to a file that already existed
163
     */
164
    private function compileHomepage(): void
165
    {
166
        $homepageContents = $this->files->read("$this->rawViewPath/index.html");
×
167
        $compiledHomepageContents = $this->compileCommonPartials(
×
168
            $homepageContents,
×
169
            ['aphiria', 'php', 'framework', 'rest', 'api'],
×
NEW
170
            'A simple, extensible REST API framework',
×
171
        );
×
172
        $sideNavContents = $this->files->read("$this->rawViewPath/partials/side-nav.html");
×
173
        $mainNavLinksContents = $this->files->read("$this->rawViewPath/partials/main-nav-links.html");
×
174
        $nonDocSideNavContents = $this->files->read("$this->rawViewPath/partials/non-doc-side-nav-contents.html");
×
175
        $compiledSideNav = $this->compileTag(
×
176
            'contents',
×
177
            $this->compileTag(
×
178
                'mainNavLinks',
×
179
                $mainNavLinksContents,
×
NEW
180
                $nonDocSideNavContents,
×
181
            ),
×
NEW
182
            $sideNavContents,
×
183
        );
×
184
        $compiledHomepageContents = $this->compileTag('sideNav', $compiledSideNav, $compiledHomepageContents);
×
185
        $this->files->write("$this->compiledViewPath/index.html", $compiledHomepageContents);
×
186
    }
187

188
    /**
189
     * Compiles a tag
190
     *
191
     * @param string $name The name of the tag to compile
192
     * @param string $tagContents The contents to fill the tag with
193
     * @param string $subject The subject to compile that tag in
194
     * @return string The compiled tag
195
     */
196
    private function compileTag(string $name, string $tagContents, string $subject): string
197
    {
198
        return \str_replace("{{ $name }}", $tagContents, $subject);
×
199
    }
200
}
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