This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
1 | <?php |
||||||
2 | |||||||
3 | namespace GeminiLabs\SiteReviews\Integrations\Breakdance; |
||||||
4 | |||||||
5 | use GeminiLabs\SiteReviews\Controllers\AbstractController; |
||||||
6 | use GeminiLabs\SiteReviews\Database\ShortcodeOptionManager; |
||||||
7 | use GeminiLabs\SiteReviews\Helpers\Arr; |
||||||
8 | use GeminiLabs\SiteReviews\Helpers\Str; |
||||||
9 | use GeminiLabs\SiteReviews\Helpers\Svg; |
||||||
10 | |||||||
11 | class Controller extends AbstractController |
||||||
12 | { |
||||||
13 | /** |
||||||
14 | * Breakdance does not provide a way to create a multi-select dropdown |
||||||
15 | * populated by an AJAX callback on init AND search. To get around this, |
||||||
16 | * we use the post_chooser control and override the callback with our own. |
||||||
17 | * |
||||||
18 | * @action breakdance_ajax_breakdance_get_posts:1 |
||||||
19 | * @action wp_ajax_breakdance_get_posts:1 |
||||||
20 | * @action wp_ajax_nopriv_breakdance_get_posts:1 |
||||||
21 | */ |
||||||
22 | public function interceptGetPostsQuery(): void |
||||||
23 | { |
||||||
24 | if (!$this->verifyRequest()) { |
||||||
25 | return; |
||||||
26 | } |
||||||
27 | $option = Str::removePrefix(filter_input(INPUT_POST, 'postType'), glsr()->prefix); |
||||||
28 | $search = filter_input(INPUT_POST, 'search'); |
||||||
29 | $params = compact('option', 'search'); |
||||||
30 | $results = call_user_func([glsr(ShortcodeOptionManager::class), $option], $params); |
||||||
31 | $replacements = [ // the post_chooser control requires integer keys |
||||||
32 | 'post_id' => -10, |
||||||
33 | 'parent_id' => -20, |
||||||
34 | 'user_id' => -30, |
||||||
35 | 'author_id' => -40, |
||||||
36 | 'profile_id' => -50, |
||||||
37 | ]; |
||||||
38 | if (in_array($option, ['assigned_posts'])) { |
||||||
39 | $thumbnailFn = fn ($id) => get_the_post_thumbnail_url($id, 'thumbnail'); |
||||||
40 | } elseif (in_array($option, ['assigned_users', 'author'])) { |
||||||
41 | $thumbnailFn = fn ($id) => get_avatar_url($id); |
||||||
42 | } |
||||||
43 | $data = $this->prepareResponse($results, $thumbnailFn ?? null, $replacements); |
||||||
44 | if (in_array($option, ['post_id'])) { |
||||||
45 | array_walk($data, function (&$item) { |
||||||
46 | $item['title'] = "{$item['id']}: {$item['title']}"; |
||||||
47 | }); |
||||||
48 | } |
||||||
49 | wp_send_json_success($data, 200); |
||||||
50 | exit; // @phpstan-ignore-line |
||||||
0 ignored issues
–
show
|
|||||||
51 | } |
||||||
52 | |||||||
53 | /** |
||||||
54 | * @action unofficial_i_am_kevin_geary_master_of_all_things_css_and_html |
||||||
55 | */ |
||||||
56 | public function printInlineStyles(): void |
||||||
57 | { |
||||||
58 | $icon = Svg::encoded('assets/images/icon-static.svg'); |
||||||
59 | echo '<style>'. |
||||||
60 | '.breakdance-control-wrapper:has(+ .breakdance-control-wrapper [data-test-id$="_description_alert"] .breakdance-alert-box) {'. |
||||||
61 | 'margin-bottom: 7px;'. |
||||||
62 | '}'. |
||||||
63 | '[data-test-id$="_description_alert"] .breakdance-alert-box {'. |
||||||
64 | 'padding-inline: 13px;', |
||||||
65 | '.v-alert__border--left {'. |
||||||
66 | 'display: none;'. |
||||||
67 | '}', |
||||||
68 | '}', |
||||||
69 | '.breakdance-add-panel__element:has(.glsr-icon) .breakdance-element-badge {'. |
||||||
70 | 'padding: 0;'. |
||||||
71 | '&::after {'. |
||||||
72 | 'background-image: url("'.$icon.'");'. |
||||||
73 | 'content: "";'. |
||||||
74 | 'height: var(--text-lg);'. |
||||||
75 | 'width: var(--text-lg);'. |
||||||
76 | '}'. |
||||||
77 | '}'. |
||||||
78 | '</style>'; |
||||||
79 | } |
||||||
80 | |||||||
81 | /** |
||||||
82 | * @action init |
||||||
83 | */ |
||||||
84 | public function registerDesignControls(): void |
||||||
85 | { |
||||||
86 | $controls = \EssentialElements\Formdesignoptions::designControls(); |
||||||
0 ignored issues
–
show
The type
EssentialElements\Formdesignoptions was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths ![]() |
|||||||
87 | $atomV1FormDesign = reset($controls); |
||||||
88 | if ('other' === Arr::get($atomV1FormDesign, 'children.5.slug')) { |
||||||
89 | unset($atomV1FormDesign['children'][5]); |
||||||
90 | } |
||||||
91 | \Breakdance\Elements\PresetSections\PresetSectionsController::getInstance()->register( |
||||||
0 ignored issues
–
show
The type
Breakdance\Elements\Pres...resetSectionsController was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths ![]() |
|||||||
92 | "GLSR\\FormDesign", |
||||||
93 | $atomV1FormDesign, |
||||||
94 | true |
||||||
95 | ); |
||||||
96 | } |
||||||
97 | |||||||
98 | /** |
||||||
99 | * Breakdance loads an element by filtering the result of get_declared_classes |
||||||
100 | * and checking if the class is_subclass_of \Breakdance\Elements\Element. |
||||||
101 | * |
||||||
102 | * Controls are added dynamically from the Shortcode class to enforce consistancy |
||||||
103 | * across builder integrations. As a result, we need to bypass the Element Studio |
||||||
104 | * and we do this by setting the save location to $onlyForAdvancedUsers and |
||||||
105 | * $excludeFromElementStudio. |
||||||
106 | * |
||||||
107 | * @action breakdance_loaded:5 |
||||||
108 | */ |
||||||
109 | public function registerElements(): void |
||||||
110 | { |
||||||
111 | $pluginDir = dirname(plugin_basename(glsr()->file)); |
||||||
112 | \Breakdance\Elements\registerCategory(glsr()->id, glsr()->name); |
||||||
0 ignored issues
–
show
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
![]() |
|||||||
113 | \Breakdance\ElementStudio\registerSaveLocation( |
||||||
0 ignored issues
–
show
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
![]() |
|||||||
114 | "{$pluginDir}/assets/breakdance/elements", |
||||||
115 | 'GLSR_Breakdance', |
||||||
116 | 'element', |
||||||
117 | 'Site Reviews Elements', |
||||||
118 | true, // onlyForAdvancedUsers |
||||||
119 | true // excludeFromElementStudio |
||||||
120 | ); |
||||||
121 | \Breakdance\ElementStudio\registerSaveLocation( |
||||||
122 | "{$pluginDir}/assets/breakdance/macros", |
||||||
123 | 'GLSR_Breakdance', |
||||||
124 | 'macro', |
||||||
125 | 'Site Reviews Macros', |
||||||
126 | true, // onlyForAdvancedUsers |
||||||
127 | true // excludeFromElementStudio |
||||||
128 | ); |
||||||
129 | \Breakdance\ElementStudio\registerSaveLocation( |
||||||
130 | "{$pluginDir}/assets/breakdance/presets", |
||||||
131 | 'GLSR_Breakdance', |
||||||
132 | 'preset', |
||||||
133 | 'Site Reviews Presets', |
||||||
134 | true, // onlyForAdvancedUsers |
||||||
135 | true // excludeFromElementStudio |
||||||
136 | ); |
||||||
137 | } |
||||||
138 | |||||||
139 | /** |
||||||
140 | * Unfortunately we can't use this yet because Breakdance does not support |
||||||
141 | * AJAX searching in multiselect controls. |
||||||
142 | * |
||||||
143 | * @action breakdance_loaded |
||||||
144 | */ |
||||||
145 | public function registerRoutes(): void |
||||||
146 | { |
||||||
147 | return; // We can't use this yet... |
||||||
148 | $input = filter_input_array(INPUT_POST, [ // @phpstan-ignore-line |
||||||
0 ignored issues
–
show
$input = filter_input_ar...ILTER_REQUIRE_ARRAY)))) is not reachable.
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed. Unreachable code is most often the result of function fx() {
try {
doSomething();
return true;
}
catch (\Exception $e) {
return false;
}
return false;
}
In the above example, the last ![]() |
|||||||
149 | 'requestData' => [ |
||||||
150 | 'context' => [ |
||||||
151 | 'filter' => fn ($value) => is_numeric($value) |
||||||
152 | ? intval($value) |
||||||
153 | : strip_tags($value), |
||||||
154 | 'flags' => FILTER_REQUIRE_ARRAY, |
||||||
155 | ], |
||||||
156 | ], |
||||||
157 | ]); |
||||||
158 | $include = Arr::consolidate($input['requestData']['context'] ?? []); |
||||||
159 | \Breakdance\AJAX\register_handler( |
||||||
0 ignored issues
–
show
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
![]() |
|||||||
160 | glsr()->prefix.'breakdance_assigned_posts', |
||||||
161 | fn () => $this->fetchAssignedPosts($include), |
||||||
162 | 'edit' |
||||||
163 | ); |
||||||
164 | \Breakdance\AJAX\register_handler( |
||||||
165 | glsr()->prefix.'breakdance_assigned_terms', |
||||||
166 | fn () => $this->fetchAssignedTerms($include), |
||||||
167 | 'edit' |
||||||
168 | ); |
||||||
169 | \Breakdance\AJAX\register_handler( |
||||||
170 | glsr()->prefix.'breakdance_assigned_users', |
||||||
171 | fn () => $this->fetchAssignedUsers($include), |
||||||
172 | 'edit' |
||||||
173 | ); |
||||||
174 | \Breakdance\AJAX\register_handler( |
||||||
175 | glsr()->prefix.'breakdance_author', |
||||||
176 | fn () => $this->fetchAuthor($include), |
||||||
177 | 'edit' |
||||||
178 | ); |
||||||
179 | \Breakdance\AJAX\register_handler( |
||||||
180 | glsr()->prefix.'breakdance_post_id', |
||||||
181 | fn () => $this->fetchPostId($include), |
||||||
182 | 'edit' |
||||||
183 | ); |
||||||
184 | } |
||||||
185 | |||||||
186 | /** |
||||||
187 | * Unfortunately we can't use this yet because Breakdance does not support |
||||||
188 | * AJAX searching in multiselect controls. |
||||||
189 | */ |
||||||
190 | protected function fetchAssignedPosts(array $include): array |
||||||
191 | { |
||||||
192 | // $include = array_filter($include, fn ($id) => is_numeric($id) || in_array($id, [ |
||||||
193 | // 'parent_id', |
||||||
194 | // 'post_id', |
||||||
195 | // ])); |
||||||
196 | return []; |
||||||
197 | } |
||||||
198 | |||||||
199 | /** |
||||||
200 | * Unfortunately we can't use this yet because Breakdance does not support |
||||||
201 | * AJAX searching in multiselect controls. |
||||||
202 | */ |
||||||
203 | protected function fetchAssignedTerms(array $include): array |
||||||
204 | { |
||||||
205 | return []; |
||||||
206 | } |
||||||
207 | |||||||
208 | /** |
||||||
209 | * Unfortunately we can't use this yet because Breakdance does not support |
||||||
210 | * AJAX searching in multiselect controls. |
||||||
211 | */ |
||||||
212 | protected function fetchAssignedUsers(array $include): array |
||||||
213 | { |
||||||
214 | // $include = array_filter($include, fn ($id) => is_numeric($id) || in_array($id, [ |
||||||
215 | // 'author_id', |
||||||
216 | // 'profile_id', |
||||||
217 | // 'user_id', |
||||||
218 | // ])); |
||||||
219 | return []; |
||||||
220 | } |
||||||
221 | |||||||
222 | /** |
||||||
223 | * Unfortunately we can't use this yet because Breakdance does not support |
||||||
224 | * AJAX searching in multiselect controls. |
||||||
225 | */ |
||||||
226 | protected function fetchAuthor(array $include): array |
||||||
227 | { |
||||||
228 | // $include = array_filter($include, fn ($id) => is_numeric($id) || in_array($id, [ |
||||||
229 | // 'user_id', |
||||||
230 | // ])); |
||||||
231 | return []; |
||||||
232 | } |
||||||
233 | |||||||
234 | /** |
||||||
235 | * Unfortunately we can't use this yet because Breakdance does not support |
||||||
236 | * AJAX searching in multiselect controls. |
||||||
237 | */ |
||||||
238 | protected function fetchPostId(array $include): array |
||||||
239 | { |
||||||
240 | return []; |
||||||
241 | } |
||||||
242 | |||||||
243 | protected function prepareResponse(array $results, ?callable $thumbnailFn = null, array $replacements = []): array |
||||||
244 | { |
||||||
245 | if (!$thumbnailFn) { |
||||||
246 | $thumbnailFn = fn () => false; |
||||||
247 | } |
||||||
248 | $callback = fn ($id, $title) => [ |
||||||
249 | 'id' => $replacements[$id] ?? $id, |
||||||
250 | 'title' => $title, |
||||||
251 | 'thumbnail' => $thumbnailFn($id), |
||||||
252 | ]; |
||||||
253 | return array_map($callback, array_keys($results), $results); |
||||||
254 | } |
||||||
255 | |||||||
256 | protected function verifyRequest(): bool |
||||||
257 | { |
||||||
258 | if (!str_starts_with((string) filter_input(INPUT_POST, 'postType'), glsr()->prefix)) { |
||||||
259 | return false; |
||||||
260 | } |
||||||
261 | if (!\Breakdance\Permissions\hasMinimumPermission('edit')) { |
||||||
0 ignored issues
–
show
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
![]() |
|||||||
262 | return false; |
||||||
263 | } |
||||||
264 | $nonceTick = check_ajax_referer(\Breakdance\AJAX\get_nonce_key_for_ajax_requests(), false, false); |
||||||
0 ignored issues
–
show
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
![]() |
|||||||
265 | if (!$nonceTick) { |
||||||
266 | return false; |
||||||
267 | } |
||||||
268 | if (2 === $nonceTick) { |
||||||
269 | $refreshNonce = \Breakdance\AJAX\get_nonce_for_ajax_requests(); |
||||||
0 ignored issues
–
show
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
![]() |
|||||||
270 | header('Breakdance-Refresh-Nonce:'.$refreshNonce); |
||||||
271 | } |
||||||
272 | return true; |
||||||
273 | } |
||||||
274 | } |
||||||
275 |
In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.