Passed
Push — master ( 7d3c20...ef46df )
by Caen
04:13 queued 29s
created

Features::hasThemeToggleButtons()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 1
nc 2
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Hyde\Facades;
6
7
use Hyde\Hyde;
8
use Hyde\Enums\Feature;
9
use Hyde\Pages\MarkdownPost;
10
use Hyde\Pages\DocumentationPage;
11
use JetBrains\PhpStorm\Deprecated;
12
use Hyde\Support\Concerns\Serializable;
13
use Hyde\Support\Contracts\SerializableContract;
14
use Hyde\Framework\Concerns\Internal\MockableFeatures;
15
use Illuminate\Support\Str;
16
17
use function get_class_methods;
18
use function extension_loaded;
19
use function str_starts_with;
20
use function in_array;
21
use function collect;
22
use function substr;
23
use function count;
24
use function app;
25
26
/**
27
 * Allows features to be enabled and disabled in a simple object-oriented manner.
28
 *
29
 * @internal Until this class is split into a service/manager class, it should not be used outside of Hyde as the API is subject to change.
30
 *
31
 * @todo Split facade logic to service/manager class. (Initial and mock data could be set with boot/set methods)
32
 * Based entirely on Laravel Jetstream (License MIT)
33
 *
34
 * @see https://jetstream.laravel.com/
35
 */
36
class Features implements SerializableContract
37
{
38
    use Serializable;
39
    use MockableFeatures;
40
41
    /**
42
     * Determine if the given specified is enabled.
43
     */
44
    public static function enabled(Feature $feature): bool
45
    {
46
        return static::resolveMockedInstance($feature->name) ?? in_array(
0 ignored issues
show
Bug introduced by
The property name does not seem to exist on Hyde\Enums\Feature.
Loading history...
47
            $feature, Config::getArray('hyde.features', static::getDefaultOptions())
48
        );
49
    }
50
51
    // ================================================
52
    // Determine if a given feature is enabled.
53
    // ================================================
54
55
    public static function hasHtmlPages(): bool
56
    {
57
        return static::enabled(Feature::HtmlPages);
58
    }
59
60
    public static function hasBladePages(): bool
61
    {
62
        return static::enabled(Feature::BladePages);
63
    }
64
65
    public static function hasMarkdownPages(): bool
66
    {
67
        return static::enabled(Feature::MarkdownPages);
68
    }
69
70
    public static function hasMarkdownPosts(): bool
71
    {
72
        return static::enabled(Feature::MarkdownPosts);
73
    }
74
75
    public static function hasDocumentationPages(): bool
76
    {
77
        return static::enabled(Feature::DocumentationPages);
78
    }
79
80
    public static function hasDocumentationSearch(): bool
81
    {
82
        return static::enabled(Feature::DocumentationSearch)
83
            && static::hasDocumentationPages()
84
            && count(DocumentationPage::files()) > 0;
85
    }
86
87
    public static function hasDarkmode(): bool
88
    {
89
        return static::enabled(Feature::Darkmode);
90
    }
91
92
    public static function hasThemeToggleButtons(): bool
93
    {
94
        return static::hasDarkmode() && Config::getBool('hyde.theme_toggle_buttons', true);
95
    }
96
97
    /**
98
     * Torchlight is by default enabled automatically when an API token
99
     * is set in the .env file but is disabled when running tests.
100
     */
101
    public static function hasTorchlight(): bool
102
    {
103
        return static::enabled(Feature::Torchlight)
104
            && (Config::getNullableString('torchlight.token') !== null)
105
            && (app('env') !== 'testing');
106
    }
107
108
    // =================================================
109
    // Configure features to be used in the config file.
110
    // =================================================
111
112
    /**
113
     * @codeCoverageIgnore Deprecated method.
114
     *
115
     * @deprecated This method will be removed in v2.0. Please use `Feature::HtmlPages` instead.
116
     */
117
    #[Deprecated(reason: 'Replaced by the \Hyde\Enums\Feature::HtmlPages Enum case', replacement: 'Feature::HtmlPages', since: '1.6.0')]
118
    public static function htmlPages(): Feature
119
    {
120
        return Feature::HtmlPages;
121
    }
122
123
    /**
124
     * @codeCoverageIgnore Deprecated method.
125
     *
126
     * @deprecated This method will be removed in v2.0. Please use `Feature::BladePages` instead.
127
     */
128
    #[Deprecated(reason: 'Replaced by the \Hyde\Enums\Feature::BladePages Enum case', replacement: 'Feature::BladePages', since: '1.6.0')]
129
    public static function bladePages(): Feature
130
    {
131
        return Feature::BladePages;
132
    }
133
134
    /**
135
     * @codeCoverageIgnore Deprecated method.
136
     *
137
     * @deprecated This method will be removed in v2.0. Please use `Feature::MarkdownPages` instead.
138
     */
139
    #[Deprecated(reason: 'Replaced by the \Hyde\Enums\Feature::MarkdownPages Enum case', replacement: 'Feature::MarkdownPages', since: '1.6.0')]
140
    public static function markdownPages(): Feature
141
    {
142
        return Feature::MarkdownPages;
143
    }
144
145
    /**
146
     * @codeCoverageIgnore Deprecated method.
147
     *
148
     * @deprecated This method will be removed in v2.0. Please use `Feature::MarkdownPosts` instead.
149
     */
150
    #[Deprecated(reason: 'Replaced by the \Hyde\Enums\Feature::MarkdownPosts Enum case', replacement: 'Feature::MarkdownPosts', since: '1.6.0')]
151
    public static function markdownPosts(): Feature
152
    {
153
        return Feature::MarkdownPosts;
154
    }
155
156
    /**
157
     * @codeCoverageIgnore Deprecated method.
158
     *
159
     * @deprecated This method will be removed in v2.0. Please use `Feature::DocumentationPages` instead.
160
     */
161
    #[Deprecated(reason: 'Replaced by the \Hyde\Enums\Feature::DocumentationPages Enum case', replacement: 'Feature::DocumentationPages', since: '1.6.0')]
162
    public static function documentationPages(): Feature
163
    {
164
        return Feature::DocumentationPages;
165
    }
166
167
    /**
168
     * @codeCoverageIgnore Deprecated method.
169
     *
170
     * @deprecated This method will be removed in v2.0. Please use `Feature::DocumentationSearch` instead.
171
     */
172
    #[Deprecated(reason: 'Replaced by the \Hyde\Enums\Feature::DocumentationSearch Enum case', replacement: 'Feature::DocumentationSearch', since: '1.6.0')]
173
    public static function documentationSearch(): Feature
174
    {
175
        return Feature::DocumentationSearch;
176
    }
177
178
    /**
179
     * @codeCoverageIgnore Deprecated method.
180
     *
181
     * @deprecated This method will be removed in v2.0. Please use `Feature::Darkmode` instead.
182
     */
183
    #[Deprecated(reason: 'Replaced by the \Hyde\Enums\Feature::Darkmode Enum case', replacement: 'Feature::Darkmode', since: '1.6.0')]
184
    public static function darkmode(): Feature
185
    {
186
        return Feature::Darkmode;
187
    }
188
189
    /**
190
     * @codeCoverageIgnore Deprecated method.
191
     *
192
     * @deprecated This method will be removed in v2.0. Please use `Feature::Torchlight` instead.
193
     */
194
    #[Deprecated(reason: 'Replaced by the \Hyde\Enums\Feature::Torchlight Enum case', replacement: 'Feature::Torchlight', since: '1.6.0')]
195
    public static function torchlight(): Feature
196
    {
197
        return Feature::Torchlight;
198
    }
199
200
    // ====================================================
201
    // Dynamic features that in addition to being enabled
202
    // in the config file, require preconditions to be met.
203
    // ====================================================
204
205
    /** Can a sitemap be generated? */
206
    public static function sitemap(): bool
207
    {
208
        return static::resolveMockedInstance('sitemap') ?? Hyde::hasSiteUrl()
209
            && Config::getBool('hyde.generate_sitemap', true)
210
            && extension_loaded('simplexml');
211
    }
212
213
    /** Can an RSS feed be generated? */
214
    public static function rss(): bool
215
    {
216
        return static::resolveMockedInstance('rss') ?? Hyde::hasSiteUrl()
217
            && static::hasMarkdownPosts()
218
            && Config::getBool('hyde.rss.enabled', true)
219
            && extension_loaded('simplexml')
220
            && count(MarkdownPost::files()) > 0;
221
    }
222
223
    /**
224
     * Get an array representation of the features and their status.
225
     *
226
     * @return array<string, bool>
227
     *
228
     * @example ['html-pages' => true, 'markdown-pages' => false, ...]
229
     */
230
    public function toArray(): array
231
    {
232
        return collect(get_class_methods(static::class))
0 ignored issues
show
Bug introduced by
get_class_methods(static::class) of type string[] is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $value of collect(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

232
        return collect(/** @scrutinizer ignore-type */ get_class_methods(static::class))
Loading history...
233
            ->filter(fn (string $method): bool => str_starts_with($method, 'has'))
234
            ->mapWithKeys(fn (string $method): array => [
235
                Str::kebab(substr($method, 3)) => static::{$method}(),
236
            ])->toArray();
237
    }
238
239
    protected static function getDefaultOptions(): array
240
    {
241
        return [
242
            // Page Modules
243
            Feature::HtmlPages,
244
            Feature::MarkdownPosts,
245
            Feature::BladePages,
246
            Feature::MarkdownPages,
247
            Feature::DocumentationPages,
248
249
            // Frontend Features
250
            Feature::Darkmode,
251
            Feature::DocumentationSearch,
252
253
            // Integrations
254
            Feature::Torchlight,
255
        ];
256
    }
257
}
258