Test Failed
Push — develop ( 39822a...f2441f )
by Paul
10:43
created

Controller   A

Complexity

Total Complexity 27

Size/Duplication

Total Lines 288
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
wmc 27
eloc 140
c 1
b 0
f 1
dl 0
loc 288
rs 10

11 Methods

Rating   Name   Duplication   Size   Complexity  
A prepareResponse() 0 11 2
A verifyRequest() 0 17 5
A registerRoutes() 0 27 2
A registerElements() 0 27 1
A searchAssignedUsers() 0 28 3
A fetchAssignedTerms() 0 4 1
A searchAssignedPosts() 0 28 3
A searchAssignedTerms() 0 18 3
A fetchAssignedUsers() 0 9 2
A searchPostId() 0 22 3
A fetchAssignedPosts() 0 8 2
1
<?php
2
3
namespace GeminiLabs\SiteReviews\Integrations\Breakdance;
4
5
use GeminiLabs\SiteReviews\Controllers\AbstractController;
6
use GeminiLabs\SiteReviews\Database;
7
use GeminiLabs\SiteReviews\Database\ShortcodeOptionManager;
8
use GeminiLabs\SiteReviews\Helpers\Arr;
9
10
class Controller extends AbstractController
11
{
12
    /**
13
     * Breakdance loads an element by filtering the result of get_declared_classes
14
     * and checking if the class is_subclass_of \Breakdance\Elements\Element.
15
     *
16
     * Controls are added dynamically from the Shortcode class to enforce consistancy
17
     * across builder integrations. As a result, we need to bypass the Element Studio
18
     * and we do this by setting the save location to $onlyForAdvancedUsers and
19
     * $excludeFromElementStudio.
20
     *
21
     * @action breakdance_loaded:5
22
     */
23
    public function registerElements(): void
24
    {
25
        $pluginDir = dirname(plugin_basename(glsr()->file));
26
        \Breakdance\Elements\registerCategory(glsr()->id, glsr()->name);
0 ignored issues
show
Bug introduced by
The function registerCategory was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

26
        /** @scrutinizer ignore-call */ 
27
        \Breakdance\Elements\registerCategory(glsr()->id, glsr()->name);
Loading history...
27
        \Breakdance\ElementStudio\registerSaveLocation(
0 ignored issues
show
Bug introduced by
The function registerSaveLocation was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

27
        /** @scrutinizer ignore-call */ 
28
        \Breakdance\ElementStudio\registerSaveLocation(
Loading history...
28
            "{$pluginDir}/assets/breakdance/elements",
29
            'GLSR_Breakdance',
30
            'element',
31
            'Site Reviews Elements',
32
            true, // onlyForAdvancedUsers
33
            true // excludeFromElementStudio
34
        );
35
        \Breakdance\ElementStudio\registerSaveLocation(
36
            "{$pluginDir}/assets/breakdance/macros",
37
            'GLSR_Breakdance',
38
            'macro',
39
            'Site Reviews Macros',
40
            true, // onlyForAdvancedUsers
41
            true // excludeFromElementStudio
42
        );
43
        \Breakdance\ElementStudio\registerSaveLocation(
44
            "{$pluginDir}/assets/breakdance/presets",
45
            'GLSR_Breakdance',
46
            'preset',
47
            'Site Reviews Presets',
48
            true, // onlyForAdvancedUsers
49
            true // excludeFromElementStudio
50
        );
51
    }
52
53
    /**
54
     * Unfortunately we can't use this yet because Breakdance does not support
55
     * AJAX searching in multiselect controls.
56
     *
57
     * @action breakdance_loaded
58
     */
59
    public function registerRoutes(): void
60
    {
61
        $input = filter_input_array(INPUT_POST, [
62
            'requestData' => [
63
                'context' => [
64
                    'filter' => fn ($value) => is_numeric($value)
65
                        ? intval($value)
66
                        : filter_var($value, FILTER_SANITIZE_STRING),
67
                    'flags' => FILTER_REQUIRE_ARRAY,
68
                ],
69
            ],
70
        ]);
71
        $include = Arr::consolidate($input['requestData']['context'] ?? []);
72
        \Breakdance\AJAX\register_handler(
0 ignored issues
show
Bug introduced by
The function register_handler was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

72
        /** @scrutinizer ignore-call */ 
73
        \Breakdance\AJAX\register_handler(
Loading history...
73
            glsr()->prefix.'breakdance_assigned_posts',
74
            fn () => $this->fetchAssignedPosts($include),
75
            'edit'
76
        );
77
        \Breakdance\AJAX\register_handler(
78
            glsr()->prefix.'breakdance_assigned_terms',
79
            fn () => $this->fetchAssignedTerms($include),
80
            'edit'
81
        );
82
        \Breakdance\AJAX\register_handler(
83
            glsr()->prefix.'breakdance_assigned_users',
84
            fn () => $this->fetchAssignedUsers($include),
85
            'edit'
86
        );
87
    }
88
89
    /**
90
     * Breakdance does not provide a way to create a multi-select dropdown
91
     * populated by an AJAX callback on init AND search. To get around this,
92
     * we use the post_chooser control and override the callback with our own.
93
     *
94
     * @action breakdance_ajax_breakdance_get_posts:1
95
     * @action wp_ajax_breakdance_get_posts:1
96
     * @action wp_ajax_nopriv_breakdance_get_posts:1
97
     */
98
    public function searchAssignedPosts(): void
99
    {
100
        if (!$this->verifyRequest('assigned_posts')) {
101
            return;
102
        }
103
        $search = filter_input(INPUT_POST, 'search');
104
        if (!empty($search)) {
105
            $results = glsr(ShortcodeOptionManager::class)->assignedPosts([
106
                'search' => $search,
107
            ]);
108
        } else {
109
            $results = [
110
                'post_id' => esc_html_x('The Current Page', 'admin-text', 'site-reviews'),
111
                'parent_id' => esc_html_x('The Parent Page', 'admin-text', 'site-reviews'),
112
            ] + glsr(Database::class)->posts([
113
                // @see MainController::parseAssignedPostTypesInQuery
114
                'post_type' => glsr()->prefix.'assigned_posts',
115
                'posts_per_page' => 50,
116
            ]);
117
        }
118
        $thumbnailFn = fn ($id) => get_the_post_thumbnail_url($id, 'thumbnail');
119
        $replacements = [ // the post_chooser control requires integer keys
120
            'post_id' => -10,
121
            'parent_id' => -20,
122
        ];
123
        $data = $this->prepareResponse($results, $thumbnailFn, $replacements);
124
        wp_send_json_success($data, 200);
125
        exit; // @phpstan-ignore-line
1 ignored issue
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
126
    }
127
128
    /**
129
     * Breakdance does not provide a way to create a multi-select dropdown
130
     * populated by an AJAX callback on init AND search. To get around this,
131
     * we use the post_chooser control and override the callback with our own.
132
     *
133
     * @action breakdance_ajax_breakdance_get_posts:1
134
     * @action wp_ajax_breakdance_get_posts:1
135
     * @action wp_ajax_nopriv_breakdance_get_posts:1
136
     */
137
    public function searchAssignedTerms(): void
138
    {
139
        if (!$this->verifyRequest('assigned_terms')) {
140
            return;
141
        }
142
        $search = filter_input(INPUT_POST, 'search');
143
        if (!empty($search)) {
144
            $results = glsr(ShortcodeOptionManager::class)->assignedTerms([
145
                'search' => $search,
146
            ]);
147
        } else {
148
            $results = glsr(Database::class)->terms([
149
                'number' => 50,
150
            ]);
151
        }
152
        $data = $this->prepareResponse($results);
153
        wp_send_json_success($data, 200);
154
        exit; // @phpstan-ignore-line
1 ignored issue
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
155
    }
156
157
    /**
158
     * Breakdance does not provide a way to create a multi-select dropdown
159
     * populated by an AJAX callback on init AND search. To get around this,
160
     * we use the post_chooser control and override the callback with our own.
161
     *
162
     * @action breakdance_ajax_breakdance_get_posts:1
163
     * @action wp_ajax_breakdance_get_posts:1
164
     * @action wp_ajax_nopriv_breakdance_get_posts:1
165
     */
166
    public function searchAssignedUsers(): void
167
    {
168
        if (!$this->verifyRequest('assigned_users')) {
169
            return;
170
        }
171
        $search = filter_input(INPUT_POST, 'search');
172
        if (!empty($search)) {
173
            $results = glsr(ShortcodeOptionManager::class)->assignedUsers([
174
                'search' => $search,
175
            ]);
176
        } else {
177
            $results = [
178
                'user_id' => esc_html_x('The Logged In User', 'admin-text', 'site-reviews'),
179
                'author_id' => esc_html_x('The Page Author', 'admin-text', 'site-reviews'),
180
                'profile_id' => esc_html_x('The Profile User', 'admin-text', 'site-reviews'),
181
            ] + glsr(Database::class)->users([
182
                'number' => 50,
183
            ]);
184
        }
185
        $thumbnailFn = fn ($id) => get_avatar_url($id);
186
        $replacements = [ // the post_chooser control requires integer keys
187
            'user_id' => -10,
188
            'author_id' => -20,
189
            'profile_id' => -30,
190
        ];
191
        $data = $this->prepareResponse($results, $thumbnailFn, $replacements);
192
        wp_send_json_success($data, 200);
193
        exit; // @phpstan-ignore-line
1 ignored issue
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
194
    }
195
196
    /**
197
     * Breakdance does not provide a way to create a dropdown with AJAX search.
198
     * To get around this, we use the post_chooser control and override the
199
     * callback with our own.
200
     *
201
     * @action breakdance_ajax_breakdance_get_posts:1
202
     * @action wp_ajax_breakdance_get_posts:1
203
     * @action wp_ajax_nopriv_breakdance_get_posts:1
204
     */
205
    public function searchPostId(): void
206
    {
207
        if (!$this->verifyRequest('post_id')) {
208
            return;
209
        }
210
        $search = filter_input(INPUT_POST, 'search');
211
        if (!empty($search)) {
212
            $results = glsr(ShortcodeOptionManager::class)->postId([
213
                'search' => $search,
214
            ]);
215
        } else {
216
            $results = glsr(Database::class)->posts([
217
                'post_type' => glsr()->post_type,
218
                'posts_per_page' => 50,
219
            ]);
220
        }
221
        $data = $this->prepareResponse($results);
222
        array_walk($data, function (&$item) {
223
            $item['title'] = "{$item['id']}: {$item['title']}";
224
        });
225
        wp_send_json_success($data, 200);
226
        exit; // @phpstan-ignore-line
1 ignored issue
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
227
    }
228
229
    /**
230
     * Unfortunately we can't use this yet because Breakdance does not support
231
     * AJAX searching in multiselect controls.
232
     */
233
    protected function fetchAssignedPosts(array $include): array
234
    {
235
        $include = array_filter($include, fn ($id) => is_numeric($id) || in_array($id, [
0 ignored issues
show
Unused Code introduced by
The assignment to $include is dead and can be removed.
Loading history...
236
            'parent_id',
237
            'post_id',
238
        ]));
239
        // ...
240
        return [];
241
    }
242
243
    /**
244
     * Unfortunately we can't use this yet because Breakdance does not support
245
     * AJAX searching in multiselect controls.
246
     */
247
    protected function fetchAssignedTerms(array $include): array
1 ignored issue
show
Unused Code introduced by
The parameter $include is not used and could be removed. ( Ignorable by Annotation )

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

247
    protected function fetchAssignedTerms(/** @scrutinizer ignore-unused */ array $include): array

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
248
    {
249
        // ...
250
        return [];
251
    }
252
253
    /**
254
     * Unfortunately we can't use this yet because Breakdance does not support
255
     * AJAX searching in multiselect controls.
256
     */
257
    protected function fetchAssignedUsers(array $include): array
258
    {
259
        $include = array_filter($include, fn ($id) => is_numeric($id) || in_array($id, [
0 ignored issues
show
Unused Code introduced by
The assignment to $include is dead and can be removed.
Loading history...
260
            'author_id',
261
            'profile_id',
262
            'user_id',
263
        ]));
264
        // ...
265
        return [];
266
    }
267
268
    protected function prepareResponse(array $results, ?callable $thumbnailFn = null, array $replacements = []): array
269
    {
270
        if (!$thumbnailFn) {
271
            $thumbnailFn = fn () => false;
272
        }
273
        $callback = fn ($id, $title) => [
274
            'id' => $replacements[$id] ?? $id,
275
            'title' => $title,
276
            'thumbnail' => $thumbnailFn($id),
277
        ];
278
        return array_map($callback, array_keys($results), $results);
279
    }
280
281
    protected function verifyRequest(string $type): bool
282
    {
283
        if (glsr()->prefix.$type !== filter_input(INPUT_POST, 'postType')) {
284
            return false;
285
        }
286
        if (!\Breakdance\Permissions\hasMinimumPermission('edit')) {
0 ignored issues
show
Bug introduced by
The function hasMinimumPermission was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

286
        if (!/** @scrutinizer ignore-call */ \Breakdance\Permissions\hasMinimumPermission('edit')) {
Loading history...
287
            return false;
288
        }
289
        $nonceTick = check_ajax_referer(\Breakdance\AJAX\get_nonce_key_for_ajax_requests(), false, false);
0 ignored issues
show
Bug introduced by
The function get_nonce_key_for_ajax_requests was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

289
        $nonceTick = check_ajax_referer(/** @scrutinizer ignore-call */ \Breakdance\AJAX\get_nonce_key_for_ajax_requests(), false, false);
Loading history...
290
        if (!$nonceTick) {
291
            return false;
292
        }
293
        if (2 === $nonceTick) {
294
            $refreshNonce = \Breakdance\AJAX\get_nonce_for_ajax_requests();
0 ignored issues
show
Bug introduced by
The function get_nonce_for_ajax_requests was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

294
            $refreshNonce = /** @scrutinizer ignore-call */ \Breakdance\AJAX\get_nonce_for_ajax_requests();
Loading history...
295
            header('Breakdance-Refresh-Nonce:'.$refreshNonce);
296
        }
297
        return true;
298
    }
299
}
300