Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
100.00% |
57 / 57 |
|
100.00% |
10 / 10 |
CRAP | |
100.00% |
1 / 1 |
| ValidationService | |
100.00% |
57 / 57 |
|
100.00% |
10 / 10 |
26 | |
100.00% |
1 / 1 |
| checks | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
3 | |||
| run | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
| check_validators_can_run | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| check_site_has_a_404_page | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 | |||
| check_site_has_an_index_page | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 | |||
| check_documentation_site_has_an_index_page | |
100.00% |
12 / 12 |
|
100.00% |
1 / 1 |
5 | |||
| check_site_has_an_app_css_stylesheet | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 | |||
| check_site_has_a_base_url_set | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
2 | |||
| check_a_torchlight_api_token_is_set | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
3 | |||
| check_for_conflicts_between_blade_and_markdown_pages | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
2 | |||
| 1 | <?php |
| 2 | |
| 3 | declare(strict_types=1); |
| 4 | |
| 5 | namespace Hyde\Framework\Services; |
| 6 | |
| 7 | use Hyde\Hyde; |
| 8 | use Hyde\Enums\Feature; |
| 9 | use Hyde\Facades\Config; |
| 10 | use Hyde\Facades\Features; |
| 11 | use Hyde\Pages\BladePage; |
| 12 | use Hyde\Pages\MarkdownPage; |
| 13 | use Hyde\Pages\DocumentationPage; |
| 14 | use Hyde\Support\Models\ValidationResult as Result; |
| 15 | |
| 16 | use function count; |
| 17 | use function get_class_methods; |
| 18 | use function array_intersect; |
| 19 | use function file_exists; |
| 20 | use function implode; |
| 21 | use function sprintf; |
| 22 | use function str_starts_with; |
| 23 | |
| 24 | class ValidationService |
| 25 | { |
| 26 | /** @return string[] */ |
| 27 | public static function checks(): array |
| 28 | { |
| 29 | $service = new self(); |
| 30 | $checks = []; |
| 31 | foreach (get_class_methods($service) as $method) { |
| 32 | if (str_starts_with($method, 'check_')) { |
| 33 | $checks[] = $method; |
| 34 | } |
| 35 | } |
| 36 | |
| 37 | return $checks; |
| 38 | } |
| 39 | |
| 40 | public function run(string $check): Result |
| 41 | { |
| 42 | $result = new Result; |
| 43 | $this->{$check}($result); |
| 44 | |
| 45 | return $result; |
| 46 | } |
| 47 | |
| 48 | public function check_validators_can_run(Result $result): Result |
| 49 | { |
| 50 | // Runs a rather useless check, but which forces the class to load, thus preventing skewed test results |
| 51 | // as the first test generally takes a little longer to run. |
| 52 | return $result->pass('Validators can run'); |
| 53 | } |
| 54 | |
| 55 | public function check_site_has_a_404_page(Result $result): Result |
| 56 | { |
| 57 | if (file_exists(MarkdownPage::path('404.md')) |
| 58 | || file_exists(BladePage::path('404.blade.php')) |
| 59 | ) { |
| 60 | return $result->pass('Your site has a 404 page'); |
| 61 | } |
| 62 | |
| 63 | return $result->fail('Could not find an 404.md or 404.blade.php file!') |
| 64 | ->withTip('You can publish the default one using `php hyde publish:views`'); |
| 65 | } |
| 66 | |
| 67 | public function check_site_has_an_index_page(Result $result): Result |
| 68 | { |
| 69 | if (file_exists(MarkdownPage::path('index.md')) |
| 70 | || file_exists(BladePage::path('index.blade.php')) |
| 71 | ) { |
| 72 | return $result->pass('Your site has an index page'); |
| 73 | } |
| 74 | |
| 75 | return $result->fail('Could not find an index.md or index.blade.php file!') |
| 76 | ->withTip('You can publish the one of the built in templates using `php hyde publish:homepage`'); |
| 77 | } |
| 78 | |
| 79 | public function check_documentation_site_has_an_index_page(Result $result): Result |
| 80 | { |
| 81 | if (! Features::hasDocumentationPages()) { |
| 82 | return $result->skip('Does documentation site have an index page?') |
| 83 | ->withTip('Skipped because: The documentation page feature is disabled in config'); |
| 84 | } |
| 85 | |
| 86 | if (count(DocumentationPage::files()) === 0) { |
| 87 | return $result->skip('Does documentation site have an index page?') |
| 88 | ->withTip('Skipped because: There are no documentation pages'); |
| 89 | } |
| 90 | |
| 91 | if (file_exists(DocumentationPage::path('index.md'))) { |
| 92 | return $result->pass('Your documentation site has an index page'); |
| 93 | } |
| 94 | |
| 95 | if (file_exists(DocumentationPage::path('README.md'))) { |
| 96 | return $result->fail('Could not find an index.md file in the _docs directory!') |
| 97 | ->withTip('However, a _docs/readme.md file was found. A suggestion would be to copy the _docs/readme.md to _docs/index.md.'); |
| 98 | } |
| 99 | |
| 100 | return $result->fail('Could not find an index.md file in the _docs directory!'); |
| 101 | } |
| 102 | |
| 103 | public function check_site_has_an_app_css_stylesheet(Result $result): Result |
| 104 | { |
| 105 | if (file_exists(Hyde::siteMediaPath('/app.css')) || file_exists(Hyde::mediaPath('app.css'))) { |
| 106 | return $result->pass('Your site has an app.css stylesheet'); |
| 107 | } |
| 108 | |
| 109 | return $result->fail(sprintf('Could not find an app.css file in the %s or %s directory!', |
| 110 | Hyde::pathToRelative(Hyde::siteMediaPath()), Hyde::getMediaDirectory() |
| 111 | ))->withTip('You may need to run `npm run dev`.`'); |
| 112 | } |
| 113 | |
| 114 | public function check_site_has_a_base_url_set(Result $result): Result |
| 115 | { |
| 116 | if (Hyde::hasSiteUrl()) { |
| 117 | return $result->pass('Your site has a base URL set') |
| 118 | ->withTip('This will allow Hyde to generate canonical URLs, sitemaps, RSS feeds, and more.'); |
| 119 | } |
| 120 | |
| 121 | return $result->fail('Could not find a site URL in the config or .env file!') |
| 122 | ->withTip('Adding it may improve SEO as it allows Hyde to generate canonical URLs, sitemaps, and RSS feeds'); |
| 123 | } |
| 124 | |
| 125 | public function check_a_torchlight_api_token_is_set(Result $result): Result |
| 126 | { |
| 127 | if (! Features::enabled(Feature::Torchlight)) { |
| 128 | return $result->skip('Check a Torchlight API token is set') |
| 129 | ->withTip('Torchlight is an API for code syntax highlighting. You can enable it in the Hyde config.'); |
| 130 | } |
| 131 | |
| 132 | if (Config::getNullableString('torchlight.token') !== null) { |
| 133 | return $result->pass('Your site has a Torchlight API token set'); |
| 134 | } |
| 135 | |
| 136 | return $result->fail('Torchlight is enabled in the config, but an API token could not be found in the .env file!') |
| 137 | ->withTip('Torchlight is an API for code syntax highlighting. You can get a free token at torchlight.dev.'); |
| 138 | } |
| 139 | |
| 140 | public function check_for_conflicts_between_blade_and_markdown_pages(Result $result): Result |
| 141 | { |
| 142 | $conflicts = array_intersect( |
| 143 | MarkdownPage::files(), |
| 144 | BladePage::files() |
| 145 | ); |
| 146 | |
| 147 | if (count($conflicts)) { |
| 148 | return $result->fail('Found naming conflicts between Markdown and Blade files: '.implode(', ', $conflicts)) |
| 149 | ->withTip('This may cause on of them being immediately overwritten by the other.'); |
| 150 | } |
| 151 | |
| 152 | return $result->pass('No naming conflicts found between Blade and Markdown pages'); |
| 153 | } |
| 154 | } |