Test Failed
Push — develop ( dad6af...9b7eec )
by Paul
08:46
created

AdminController::renderPageHeader()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 30
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
eloc 23
c 0
b 0
f 0
dl 0
loc 30
ccs 0
cts 22
cp 0
rs 8.9297
cc 6
nc 5
nop 0
crap 42
1
<?php
2
3
namespace GeminiLabs\SiteReviews\Controllers;
4
5
use GeminiLabs\SiteReviews\Commands\ApproveReview;
6
use GeminiLabs\SiteReviews\Commands\EnqueueAdminAssets;
7
use GeminiLabs\SiteReviews\Commands\ExportRatings;
8
use GeminiLabs\SiteReviews\Commands\ImportRatings;
9
use GeminiLabs\SiteReviews\Commands\RegisterTinymcePopups;
10
use GeminiLabs\SiteReviews\Commands\TogglePinned;
11
use GeminiLabs\SiteReviews\Commands\ToggleStatus;
12
use GeminiLabs\SiteReviews\Database;
13
use GeminiLabs\SiteReviews\Defaults\ColumnFilterbyDefaults;
14
use GeminiLabs\SiteReviews\Helper;
15
use GeminiLabs\SiteReviews\Helpers\Arr;
16
use GeminiLabs\SiteReviews\Helpers\Str;
17
use GeminiLabs\SiteReviews\Install;
18
use GeminiLabs\SiteReviews\License;
19
use GeminiLabs\SiteReviews\Modules\Html\Builder;
20
use GeminiLabs\SiteReviews\Modules\Migrate;
21
use GeminiLabs\SiteReviews\Modules\Notice;
22
use GeminiLabs\SiteReviews\Modules\Queue;
23
use GeminiLabs\SiteReviews\Modules\Sanitizer;
24
use GeminiLabs\SiteReviews\Modules\Translation;
25
use GeminiLabs\SiteReviews\Request;
26
27
class AdminController extends AbstractController
28
{
29
    /**
30
     * @action site-reviews/route/get/admin/approve
31
     */
32
    public function approveReview(Request $request): void
33
    {
34
        $postId = Arr::get($request->data, 0);
35
        $review = glsr_get_review($postId);
36
        if ($review->isValid()) {
37
            $command = $this->execute(new ApproveReview($review));
38
            if ($command->successful()) {
39
                glsr(Notice::class)->store(); // because of the redirect
40
            }
41
        }
42
        wp_redirect(glsr_admin_url());
43
        exit;
44
    }
45
46
    /**
47
     * @action in_plugin_update_message-{glsr()->basename}
48
     */
49
    public function displayUpdateWarning(array $data): void
50
    {
51
        $version = Arr::get($data, 'new_version');
52
        $parts = explode('.', $version);
53
        $newVersion = Arr::getAs('int', $parts, 0, 0);
54
        if ($newVersion > (int) glsr()->version('major')) {
55
            glsr()->render('views/partials/update-warning');
56
        }
57
    }
58
59
    /**
60
     * @action admin_enqueue_scripts
61
     */
62
    public function enqueueAssets(): void
63
    {
64
        $this->execute(new EnqueueAdminAssets());
65
    }
66
67
    /**
68
     * @filter plugin_action_links_site-reviews/site-reviews.php
69
     */
70
    public function filterActionLinks(array $links): array
71
    {
72
        if (glsr()->hasPermission('settings')) {
73
            $links['settings'] = glsr(Builder::class)->a([
74
                'href' => glsr_admin_url('settings'),
75
                'text' => _x('Settings', 'admin-text', 'site-reviews'),
76
            ]);
77
        }
78
        if (glsr()->hasPermission('documentation')) {
79
            $links['documentation'] = glsr(Builder::class)->a([
80
                'href' => glsr_admin_url('documentation'),
81
                'text' => _x('Help', 'admin-text', 'site-reviews'),
82
            ]);
83
        }
84
        return $links;
85
    }
86
87
    /**
88
     * @filter export_args
89
     */
90
    public function filterExportArgs(array $args): array
91
    {
92
        if (in_array(Arr::get($args, 'content'), ['all', glsr()->post_type])) {
93
            $this->execute(new ExportRatings(glsr()->args($args)));
94
        }
95
        return $args;
96
    }
97
98
    /**
99
     * @filter screen_options_show_submit
100
     */
101
    public function filterScreenOptionsButton(bool $showButton): bool
102
    {
103
        global $post_type_object, $title, $typenow;
104
        if (!str_starts_with($typenow, glsr()->post_type)) {
105
            return $showButton;
106
        }
107
        $submit = get_submit_button(_x('Apply', 'admin-text', 'site-reviews'), 'primary', 'screen-options-apply', false);
108
        $close = glsr(Builder::class)->button([
109
            'aria-controls' => 'screen-options-wrap',
110
            'class' => 'button button-secondary glsr-screen-meta-toggle',
111
            'text' => _x('Close Panel', 'admin-text', 'site-reviews'),
112
            'type' => 'button',
113
        ]);
114
        echo glsr(Builder::class)->p([
115
            'style' => 'display:inline-flex;gap:6px;',
116
            'text' => $submit.$close,
117
        ]);
118
        return false; // don't display the default submit button
119
    }
120
121
    /**
122
     * @filter mce_external_plugins
123
     */
124
    public function filterTinymcePlugins(array $plugins): array
125
    {
126
        if (glsr()->can('edit_posts')) {
127
            $plugins['glsr_shortcode'] = glsr()->url('assets/scripts/mce-plugin.js');
128
        }
129
        return $plugins;
130
    }
131
132
    /**
133
     * @action admin_init
134 8
     */
135
    public function onActivation(): void
136 8
    {
137 8
        if (empty(get_option(glsr()->prefix.'activated'))) {
138 8
            glsr(Install::class)->run(); // this hard-resets role permissions
139 8
            glsr(Migrate::class)->run();
140
            update_option(glsr()->prefix.'activated', true);
141
            glsr()->action('activated');
142
        }
143
    }
144
145
    /**
146
     * @action deactivate_{glsr()->basename}
147
     */
148
    public function onDeactivation(bool $isNetworkDeactivation): void
149
    {
150
        glsr(Install::class)->deactivate($isNetworkDeactivation);
151
    }
152
153
    /**
154
     * @action import_end
155
     */
156
    public function onImportEnd(): void
157
    {
158
        $this->execute(new ImportRatings());
159
    }
160
161
    /**
162
     * @action admin_head
163
     */
164
    public function printInlineStyle(): void
165
    {
166
        $prefix = Str::dashCase(glsr()->prefix);
167
        $url = "edit.php?post_type=site-review&page={$prefix}addons";
168
        echo ''.
169
        '<style type="text/css">'.
170 8
            "a[href=\"{$url}\"]:not(.current),a[href=\"{$url}\"]:focus,a[href=\"{$url}\"]:hover{".
171
                'color:#e8ff5e!important;'.
172 8
            '}'.
173
        '</style>';
174
    }
175
176
    /**
177
     * @action admin_init
178
     */
179
    public function registerTinymcePopups(): void
180
    {
181
        $this->execute(new RegisterTinymcePopups());
182
    }
183
184
    /**
185
     * @action in_admin_header
186
     */
187
    public function renderPageHeader(): void
188
    {
189
        global $post_type_object, $title;
190
        if (!$this->isReviewAdminScreen()) {
191
            return;
192
        }
193
        $buttons = [];
194
        $screen = glsr_current_screen();
195
        if (glsr()->post_type === $screen->post_type && !glsr(License::class)->isPremium()) {
196
            $buttons['premium'] = [
197
                'class' => 'components-button is-primary glsr-try-premium',
198
                'href' => 'https://niftyplugins.com/plugins/site-reviews-premium/',
199
                'target' => '_blank',
200
                'text' => _x('Try Premium', 'admin-text', 'site-reviews'),
201
            ];
202
        }
203
        if (glsr()->can('create_posts') && in_array($screen->base, ['edit', 'post'])) {
204
            $buttons['new'] = [
205
                'class' => 'components-button is-secondary glsr-new-post',
206
                'data-new' => '',
207
                'href' => admin_url("post-new.php?post_type={$screen->post_type}"),
208
                'text' => Arr::get($post_type_object, 'labels.add_new'),
209
            ];
210
        }
211
        $buttons = glsr()->filterArray('page-header/buttons', $buttons);
212
        glsr()->render('views/partials/page-header', [
213
            'buttons' => $buttons,
214
            'hasScreenOptions' => in_array($screen->base, ['edit', 'edit-tags', 'post']),
215
            'logo' => Helper::svg('assets/images/icon.svg', false),
216
            'title' => esc_html($title),
217
        ]);
218
    }
219
220
    /**
221
     * @action media_buttons
222
     */
223
    public function renderTinymceButton(string $editorId): void
224
    {
225
        $allowedEditors = glsr()->filterArray('tinymce/editor-ids', ['content'], $editorId);
226
        if ('post' !== glsr_current_screen()->base || !in_array($editorId, $allowedEditors)) {
227
            return;
228
        }
229
        $shortcodes = [];
230
        foreach (glsr()->retrieveAs('array', 'mce', []) as $shortcode => $values) {
231
            $shortcodes[$shortcode] = $values;
232
        }
233
        if (!empty($shortcodes)) {
234
            $shortcodes = wp_list_sort($shortcodes, 'label', 'ASC', true); // preserve keys
235 8
            glsr()->render('partials/editor/tinymce', [
236
                'shortcodes' => $shortcodes,
237 8
            ]);
238 8
        }
239
    }
240
241
    /**
242
     * @action admin_init
243
     */
244
    public function scheduleMigration(): void
245
    {
246
        if (defined('GLSR_UNIT_TESTS')) {
247
            return;
248
        }
249
        if (!$this->isReviewAdminScreen()) {
250
            return;
251
        }
252
        if (glsr(Queue::class)->isPending('queue/migration')) {
253
            return;
254
        }
255
        if (!glsr(Migrate::class)->isMigrationNeeded() && !glsr(Database::class)->isMigrationNeeded()) {
256
            return;
257
        }
258
        glsr(Queue::class)->once(time() + MINUTE_IN_SECONDS, 'queue/migration');
259
    }
260
261
    /**
262
     * @action site-reviews/route/ajax/filter-assigned_post
263
     */
264
    public function searchAssignedPostsAjax(Request $request): void
265
    {
266
        $search = glsr(Sanitizer::class)->sanitizeText($request->search);
267
        $results = glsr(Database::class)->searchAssignedPosts($search)->results();
268
        wp_send_json_success([
269
            'items' => $results,
270
        ]);
271
    }
272
273
    /**
274
     * @action site-reviews/route/ajax/filter-assigned_user
275
     */
276
    public function searchAssignedUsersAjax(Request $request): void
277
    {
278
        $search = glsr(Sanitizer::class)->sanitizeText($request->search);
279
        $results = glsr(Database::class)->searchAssignedUsers($search)->results();
280
        array_walk($results, function ($user) {
281
            $user->name = glsr(Sanitizer::class)->sanitizeUserName($user->name, $user->nickname);
282
        });
283
        wp_send_json_success([
284
            'items' => $results,
285
        ]);
286
    }
287
288
    /**
289
     * @action site-reviews/route/ajax/filter-author
290
     */
291
    public function searchAuthorsAjax(Request $request): void
292
    {
293
        $search = glsr(Sanitizer::class)->sanitizeText($request->search);
294
        $results = glsr(Database::class)->searchUsers($search)->results();
295
        array_walk($results, function ($user) {
296
            $user->name = glsr(Sanitizer::class)->sanitizeUserName($user->name, $user->nickname);
297
        });
298
        wp_send_json_success([
299
            'items' => $results,
300
        ]);
301
    }
302
303
    /**
304
     * @action site-reviews/route/ajax/search-posts
305
     */
306
    public function searchPostsAjax(Request $request): void
307
    {
308
        $search = glsr(Sanitizer::class)->sanitizeText($request->search);
309
        $results = glsr(Database::class)->searchPosts($search)->render();
310
        wp_send_json_success([
311
            'empty' => '<div>'._x('Nothing found.', 'admin-text', 'site-reviews').'</div>',
312
            'items' => $results,
313
        ]);
314
    }
315
316
    /**
317
     * @action site-reviews/route/ajax/search-strings
318
     */
319
    public function searchStringsAjax(Request $request): void
320
    {
321
        $search = glsr(Sanitizer::class)->sanitizeText($request->search);
322
        $exclude = Arr::consolidate($request->exclude);
323
        $results = glsr(Translation::class)
324
            ->search($search)
325
            ->exclude()
326
            ->exclude($exclude)
327
            ->renderResults();
328
        wp_send_json_success([
329
            'empty' => '<div>'._x('Nothing found.', 'admin-text', 'site-reviews').'</div>',
330
            'items' => $results,
331
        ]);
332
    }
333
334
    /**
335
     * @action site-reviews/route/ajax/search-users
336
     */
337
    public function searchUsersAjax(Request $request): void
338
    {
339
        $search = glsr(Sanitizer::class)->sanitizeText($request->search);
340
        $results = glsr(Database::class)->searchUsers($search)->render();
341
        wp_send_json_success([
342
            'empty' => '<div>'._x('Nothing found.', 'admin-text', 'site-reviews').'</div>',
343
            'items' => $results,
344
        ]);
345
    }
346
347
    /**
348
     * @action site-reviews/route/ajax/toggle-filters
349
     */
350
    public function toggleFiltersAjax(Request $request): void
351
    {
352
        if ($userId = get_current_user_id()) {
353
            $filters = array_keys(glsr(ColumnFilterbyDefaults::class)->defaults());
354
            $enabled = glsr(Sanitizer::class)->sanitizeArrayString($request->enabled);
355
            $enabled = array_intersect($filters, $enabled);
356
            update_user_meta($userId, 'edit_'.glsr()->post_type.'_filters', $enabled);
357
        }
358
        wp_send_json_success();
359
    }
360
361
    /**
362
     * @action site-reviews/route/ajax/toggle-pinned
363
     */
364
    public function togglePinnedAjax(Request $request): void
365
    {
366
        $command = $this->execute(new TogglePinned($request));
367
        glsr()->action('cache/flush', $command->review); // @phpstan-ignore-line
368
        wp_send_json_success($command->response());
369
    }
370
371
    /**
372
     * @action site-reviews/route/ajax/toggle-status
373
     */
374
    public function toggleStatusAjax(Request $request): void
375
    {
376
        $command = $this->execute(new ToggleStatus($request));
377
        wp_send_json_success($command->response());
378
    }
379
}
380