Test Failed
Push — develop ( bf902a...baed09 )
by Paul
09:29
created

AdminController   B

Complexity

Total Complexity 44

Size/Duplication

Total Lines 341
Duplicated Lines 0 %

Test Coverage

Coverage 5.65%

Importance

Changes 2
Bugs 0 Features 1
Metric Value
wmc 44
eloc 154
c 2
b 0
f 1
dl 0
loc 341
ccs 10
cts 177
cp 0.0565
rs 8.8798

22 Methods

Rating   Name   Duplication   Size   Complexity  
A onImportEnd() 0 3 1
A onDeactivation() 0 3 1
A scheduleMigration() 0 15 6
A filterActionLinks() 0 15 3
A filterTinymcePlugins() 0 6 2
A enqueueAssets() 0 3 1
A toggleStatusAjax() 0 4 1
A searchPostsAjax() 0 7 1
A searchAuthorsAjax() 0 9 1
A searchUsersAjax() 0 7 1
A searchAssignedPostsAjax() 0 6 1
A searchAssignedUsersAjax() 0 9 1
A togglePinnedAjax() 0 5 1
A toggleFiltersAjax() 0 9 2
A filterScreenOptionsButton() 0 18 2
B renderPageHeader() 0 38 8
A filterExportArgs() 0 6 2
A onActivation() 0 7 2
A approveReview() 0 12 3
A displayUpdateWarning() 0 7 2
A printInlineStyle() 0 21 1
A searchStringsAjax() 0 12 1

How to fix   Complexity   

Complex Class

Complex classes like AdminController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use AdminController, and based on these observations, apply Extract Interface, too.

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