Test Failed
Push — develop ( 76157d...9702e2 )
by Paul
08:08
created

Controller::runIntegrations()   B

Complexity

Conditions 7
Paths 11

Size

Total Lines 22
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 0
Metric Value
eloc 17
c 0
b 0
f 0
dl 0
loc 22
rs 8.8333
ccs 0
cts 13
cp 0
cc 7
nc 11
nop 0
crap 56
1
<?php
2
3
namespace GeminiLabs\SiteReviews\Addons;
4
5
use GeminiLabs\SiteReviews\Contracts\PluginContract;
6
use GeminiLabs\SiteReviews\Controllers\AbstractController;
7
use GeminiLabs\SiteReviews\Database\OptionManager;
8
use GeminiLabs\SiteReviews\Helpers\Arr;
9
use GeminiLabs\SiteReviews\Helpers\Cast;
10
use GeminiLabs\SiteReviews\Helpers\Str;
11
use GeminiLabs\SiteReviews\Install;
12
use GeminiLabs\SiteReviews\Modules\Assets\AssetCss;
13
use GeminiLabs\SiteReviews\Modules\Assets\AssetJs;
14
use GeminiLabs\SiteReviews\Modules\Html\Builder;
15
use GeminiLabs\SiteReviews\Modules\Html\Template;
16
use GeminiLabs\SiteReviews\Modules\Translation;
17
use GeminiLabs\SiteReviews\Modules\Translator;
18
use GeminiLabs\SiteReviews\Role;
19
20
abstract class Controller extends AbstractController
21
{
22
    /**
23
     * @action admin_enqueue_scripts
24
     */
25
    public function enqueueAdminAssets(): void
26
    {
27
        if ($this->isReviewAdminPage()) {
28
            $this->enqueueAsset('css', ['suffix' => 'admin']);
29
            $this->enqueueAsset('js', ['suffix' => 'admin']);
30
        }
31
    }
32
33
    /**
34
     * @action wp_enqueue_scripts
35
     */
36
    public function enqueuePublicAssets(): void
37
    {
38
        if (!glsr(AssetCss::class)->canOptimize() || !glsr(AssetCss::class)->isOptimized()) {
39
            $this->enqueueAsset('css');
40
        }
41
        if (!glsr(AssetJs::class)->canOptimize() || !glsr(AssetJs::class)->isOptimized()) {
42
            $this->enqueueAsset('js', ['in_footer' => true]);
43
        }
44
    }
45
46
    /**
47
     * @param array $actions
48
     *
49
     * @filter plugin_action_links_{$this->app()->id}/{$this->app()->id}.php
50
     */
51
    public function filterActionLinks($actions): array
52
    {
53
        $actions = Arr::consolidate($actions);
54
        if (glsr()->hasPermission('settings') && !empty($this->app()->config('settings'))) {
55
            $actions['settings'] = glsr(Builder::class)->a([
56
                'href' => glsr_admin_url('settings', 'addons', $this->app()->slug),
57
                'text' => _x('Settings', 'admin-text', 'site-reviews'),
58
            ]);
59
        }
60
        if (glsr()->hasPermission('documentation')) {
61
            $actions['documentation'] = glsr(Builder::class)->a([
62
                'data-expand' => "#addon-{$this->app()->id}",
63
                'href' => glsr_admin_url('documentation', 'addons'),
64
                'text' => _x('Help', 'admin-text', 'site-reviews'),
65
            ]);
66
        }
67
        return $actions;
68
    }
69
70
    /**
71
     * @filter site-reviews/capabilities
72
     */
73
    public function filterCapabilities(array $capabilities): array
74
    {
75
        if (!$this->app()->post_type) { // @phpstan-ignore-line
76
            return $capabilities;
77
        }
78
        $defaults = [
79
            'create_posts',
80
            'delete_others_posts',
81
            'delete_posts',
82
            'delete_private_posts',
83
            'delete_published_posts',
84
            'edit_others_posts',
85
            'edit_posts',
86
            'edit_private_posts',
87
            'edit_published_posts',
88
            'publish_posts',
89
            'read_private_posts',
90
        ];
91
        foreach ($defaults as $capability) {
92
            $capabilities[] = str_replace('post', $this->app()->post_type, $capability);
93
        }
94
        return $capabilities;
95
    }
96
97
    /**
98
     * @filter site-reviews/config
99
     */
100
    public function filterConfigPath(string $path): string
101
    {
102
        $prefix = trailingslashit($this->app()->id);
103
        return str_contains($path, $prefix)
104
            ? $prefix.str_replace($prefix, '', $path)
105
            : $path;
106
    }
107
108
    /**
109
     * @filter site-reviews/addon/documentation
110
     */
111
    public function filterDocumentation(array $documentation): array
112
    {
113
        $notice = glsr()->build('views/partials/addons/support-notice', [
114
            'addon_id' => $this->app()->id,
115
        ]);
116
        $support = $this->app()->build('views/documentation');
117
        $documentation[$this->app()->id] = $notice.$support;
118
        return $documentation;
119
    }
120
121
    /**
122
     * @filter site-reviews/path
123
     */
124
    public function filterFilePaths(string $path, string $file): string
125
    {
126
        $addonPrefix = trailingslashit($this->app()->id);
127
        return str_starts_with($file, $addonPrefix)
128
            ? $this->app()->path(Str::replaceFirst($addonPrefix, '', $file))
129
            : $path;
130
    }
131
132
    /**
133
     * @param string $translation
134
     * @param string $single
135
     *
136
     * @filter gettext_{$this->app()->id}
137
     */
138
    public function filterGettext($translation, $single): string
139
    {
140
        $translation = Cast::toString($translation);
141
        return glsr(Translator::class)->translate($translation, $this->app()->id, [
142
            'single' => Cast::toString($single),
143
        ]);
144
    }
145
146
    /**
147
     * @param string $translation
148
     * @param string $single
149
     * @param string $context
150
     *
151
     * @filter gettext_with_context_{$this->app()->id}
152
     */
153
    public function filterGettextWithContext($translation, $single, $context): string
154
    {
155
        $translation = Cast::toString($translation);
156
        return glsr(Translator::class)->translate($translation, $this->app()->id, [
157
            'context' => Cast::toString($context),
158
            'single' => Cast::toString($single),
159
        ]);
160
    }
161
162
    /**
163
     * @filter site-reviews/enqueue/public/localize
164
     */
165
    public function filterLocalizedPublicVariables(array $variables): array
166
    {
167
        $variables['addons'][$this->app()->id] = null;
168
        return $variables;
169
    }
170
171
    /**
172
     * @param string $translation
173
     * @param string $single
174
     * @param string $plural
175
     * @param int    $number
176
     *
177
     * @filter ngettext_{$this->app()->id}
178
     */
179
    public function filterNgettext($translation, $single, $plural, $number): string
180
    {
181
        $translation = Cast::toString($translation);
182
        return glsr(Translator::class)->translate($translation, $this->app()->id, [
183
            'number' => Cast::toInt($number),
184
            'plural' => Cast::toString($plural),
185
            'single' => Cast::toString($single),
186
        ]);
187
    }
188
189
    /**
190
     * @param string $translation
191
     * @param string $single
192
     * @param string $plural
193
     * @param int    $number
194
     * @param string $context
195
     *
196
     * @filter ngettext_with_context_{$this->app()->id}
197
     */
198
    public function filterNgettextWithContext($translation, $single, $plural, $number, $context): string
199
    {
200
        $translation = Cast::toString($translation);
201
        return glsr(Translator::class)->translate($translation, $this->app()->id, [
202
            'context' => Cast::toString($context),
203
            'number' => Cast::toInt($number),
204
            'plural' => Cast::toString($plural),
205
            'single' => Cast::toString($single),
206
        ]);
207
    }
208
209
    /**
210
     * @filter {$this->app()->id}/render/view
211
     */
212
    public function filterRenderView(string $view): string
213
    {
214
        $style = glsr(OptionManager::class)->get('settings.general.style', 'default');
215
        $styledView = sprintf('views/styles/%s/%s', $style, basename($view));
216
        if (file_exists($this->app()->file($styledView))) {
217
            return $styledView;
218
        }
219
        return $view;
220
    }
221
222
    /**
223
     * @filter site-reviews/roles
224
     */
225
    public function filterRoles(array $roles): array
226
    {
227
        if (!$this->app()->post_type) { // @phpstan-ignore-line
228
            return $roles;
229
        }
230
        $defaults = [
231
            'administrator' => [
232
                'create_posts',
233
                'delete_others_posts',
234
                'delete_posts',
235
                'delete_private_posts',
236
                'delete_published_posts',
237
                'edit_others_posts',
238
                'edit_posts',
239
                'edit_private_posts',
240
                'edit_published_posts',
241
                'publish_posts',
242
                'read_private_posts',
243
            ],
244
            'editor' => [
245
                'create_posts',
246
                'delete_others_posts',
247
                'delete_posts',
248
                'delete_private_posts',
249
                'delete_published_posts',
250
                'edit_others_posts',
251
                'edit_posts',
252
                'edit_private_posts',
253
                'edit_published_posts',
254
                'publish_posts',
255
                'read_private_posts',
256
            ],
257
            'author' => [
258
                'create_posts',
259
                'delete_posts',
260
                'delete_published_posts',
261
                'edit_posts',
262
                'edit_published_posts',
263
                'publish_posts',
264
            ],
265
            'contributor' => [
266
                'delete_posts',
267
                'edit_posts',
268
            ],
269
        ];
270
        foreach ($defaults as $role => $capabilities) {
271
            if (!array_key_exists($role, $roles)) {
272
                continue;
273
            }
274
            foreach ($capabilities as $capability) {
275
                $roles[$role][] = str_replace('post', $this->app()->post_type, $capability);
276
            }
277
        }
278
        return $roles;
279
    }
280
281
    /**
282
     * @filter site-reviews/settings
283
     */
284
    public function filterSettings(array $settings): array
285
    {
286
        return array_merge($this->app()->config('settings'), $settings);
287
    }
288
289
    /**
290
     * @filter site-reviews/addon/subsubsub
291
     */
292
    public function filterSubsubsub(array $subsubsub): array
293
    {
294
        return $subsubsub;
295
    }
296
297
    /**
298
     * @filter site-reviews/translation/entries
299
     */
300
    public function filterTranslationEntries(array $entries): array
301
    {
302
        $potFile = $this->app()->path("{$this->app()->languages}/{$this->app()->id}.pot");
303
        return glsr(Translation::class)->extractEntriesFromPotFile($potFile, $this->app()->id, $entries);
304
    }
305
306
    /**
307
     * @filter site-reviews/translator/domains
308
     */
309
    public function filterTranslatorDomains(array $domains): array
310
    {
311
        return [...$domains, $this->app()->id];
312
    }
313
314
    /**
315
     * @action {$this->app()->id}/activated
316
     */
317
    public function install(): void
318
    {
319
    }
320
321
    /**
322
     * @action admin_init
323
     */
324
    public function onActivation(): void
325
    {
326
        $option = glsr()->prefix."activated_{$this->app()->id}";
327
        if (empty(get_option($option))) {
328
            update_option($option, true);
329
            if ($this->app()->post_type) { // @phpstan-ignore-line
330
                glsr(Role::class)->reset($this->filterRoles([
331
                    'administrator' => [],
332
                    'author' => [],
333
                    'contributor' => [],
334
                    'editor' => [],
335
                ]));
336
            }
337
            $this->app()->action('activated');
338
        }
339
    }
340
341
    /**
342
     * @action deactivate_{$this->app()->basename}
343
     */
344
    public function onDeactivation(bool $isNetworkDeactivation): void
345
    {
346
        $option = glsr()->prefix."activated_{$this->app()->id}";
347
        if (!$isNetworkDeactivation) {
348
            delete_option($option);
349
            $this->app()->action('deactivated');
350
            return;
351
        }
352
        foreach (glsr(Install::class)->sites() as $siteId) {
353
            switch_to_blog($siteId);
354
            delete_option($option);
355
            $this->app()->action('deactivated');
356
            restore_current_blog();
357
        }
358
    }
359
360
    /**
361
     * @action init
362
     */
363
    public function registerLanguages(): void
364
    {
365
        $path = plugin_basename($this->app()->path());
366
        $path = trailingslashit("{$path}/{$this->app()->languages}");
367
        load_plugin_textdomain($this->app()->id, false, $path);
368
    }
369
370
    /**
371
     * @action init
372
     */
373
    public function registerShortcodes(): void
374
    {
375
    }
376
377
    /**
378
     * @action admin_init
379
     */
380
    public function registerTinymcePopups(): void
381
    {
382
    }
383
384
    /**
385
     * @action widgets_init
386
     */
387
    public function registerWidgets(): void
388
    {
389
    }
390
391
    /**
392
     * @action site-reviews/settings/{$this->app()->slug}
393
     */
394
    public function renderSettings(string $rows): void
395
    {
396
        glsr(Template::class)->render("{$this->app()->id}/views/settings", [
397
            'context' => [
398
                'rows' => $rows,
399
                'title' => $this->app()->name,
400
            ],
401
        ]);
402
    }
403
404
    protected function buildAssetArgs(string $ext, array $args = []): array
405
    {
406
        $args = wp_parse_args($args, [
407
            'defer' => true,
408
            'in_footer' => false,
409
            'suffix' => '',
410
        ]);
411
        $suffix = Str::prefix($args['suffix'], '-');
412
        $path = "assets/{$this->app()->id}{$suffix}.{$ext}";
413
        if (!file_exists($this->app()->path($path)) || !in_array($ext, ['css', 'js'])) {
414
            return [];
415
        }
416
        $suffix = Str::prefix($args['suffix'], '/');
417
        $dependencies = Arr::get($args, 'dependencies', [glsr()->id.$suffix]);
418
        $handle = $this->app()->id.$suffix;
419
        $funcArgs = [
420
            $handle,
421
            $this->app()->url($path),
422
            Arr::consolidate($dependencies),
423
            $this->app()->version,
424
        ];
425
        if ('js' === $ext && wp_validate_boolean($args['in_footer'])) {
426
            $funcArgs[] = true; // load script in the footer
427
        }
428
        return $funcArgs;
429
    }
430
431
    protected function enqueueAsset(string $extension, array $args = []): void
432
    {
433
        $defer = Arr::get($args, 'defer', false);
434
        if ($args = $this->buildAssetArgs($extension, $args)) {
435
            $function = 'js' === $extension
436
                ? 'wp_enqueue_script'
437
                : 'wp_enqueue_style';
438
            call_user_func_array($function, $args);
439
            if (wp_validate_boolean($defer)) {
440
                wp_script_add_data($args[0], 'strategy', 'defer');
441
            }
442
        }
443
    }
444
445
    protected function registerAsset(string $extension, array $args = []): void
446
    {
447
        $defer = Arr::get($args, 'defer', false);
448
        if ($args = $this->buildAssetArgs($extension, $args)) {
449
            $function = 'js' === $extension
450
                ? 'wp_register_script'
451
                : 'wp_register_style';
452
            call_user_func_array($function, $args);
453
            if (wp_validate_boolean($defer)) {
454
                wp_script_add_data($args[0], 'strategy', 'defer');
455
            }
456
        }
457
    }
458
}
459