Total Complexity | 84 |
Total Lines | 519 |
Duplicated Lines | 0 % |
Coverage | 0% |
Changes | 0 |
Complex classes like EditorController 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 EditorController, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
14 | class EditorController extends Controller |
||
15 | { |
||
16 | const META_AVERAGE = '_glsr_average'; |
||
17 | const META_RANKING = '_glsr_ranking'; |
||
18 | const META_REVIEW_ID = '_glsr_review_id'; |
||
19 | |||
20 | /** |
||
21 | * @return void |
||
22 | * @action admin_enqueue_scripts |
||
23 | */ |
||
24 | public function customizePostStatusLabels() |
||
25 | { |
||
26 | global $wp_scripts; |
||
1 ignored issue
–
show
|
|||
27 | $strings = [ |
||
28 | 'savePending' => __( 'Save as Unapproved', 'site-reviews' ), |
||
29 | 'published' => __( 'Approved', 'site-reviews' ), |
||
30 | ]; |
||
31 | if( $this->canModifyTranslation() && isset( $wp_scripts->registered['post']->extra['data'] )) { |
||
32 | $l10n = &$wp_scripts->registered['post']->extra['data']; |
||
33 | foreach( $strings as $search => $replace ) { |
||
34 | $l10n = preg_replace( '/("'.$search.'":")([^"]+)/', "$1".$replace, $l10n ); |
||
35 | } |
||
36 | } |
||
37 | } |
||
38 | |||
39 | /** |
||
40 | * @return array |
||
41 | * @filter wp_editor_settings |
||
42 | */ |
||
43 | public function filterEditorSettings( array $settings ) |
||
44 | { |
||
45 | if( $this->isReviewEditable() ) { |
||
46 | $settings = [ |
||
47 | 'media_buttons' => false, |
||
48 | 'quicktags' => false, |
||
49 | 'textarea_rows' => 12, |
||
50 | 'tinymce' => false, |
||
51 | ]; |
||
52 | } |
||
53 | return $settings; |
||
54 | } |
||
55 | |||
56 | /** |
||
57 | * Modify the WP_Editor html to allow autosizing without breaking the `editor-expand` script |
||
58 | * @param string $html |
||
59 | * @return string |
||
60 | * @filter the_editor |
||
61 | */ |
||
62 | public function filterEditorTextarea( $html ) |
||
63 | { |
||
64 | if( $this->isReviewEditable() ) { |
||
65 | $html = str_replace( '<textarea', '<div id="ed_toolbar"></div><textarea', $html ); |
||
66 | } |
||
67 | return $html; |
||
68 | } |
||
69 | |||
70 | /** |
||
71 | * @param string $translation |
||
72 | * @param string $test |
||
73 | * @param string $domain |
||
74 | * @return string |
||
75 | * @filter gettext |
||
76 | */ |
||
77 | public function filterPostStatusLabels( $translation, $text, $domain ) |
||
1 ignored issue
–
show
|
|||
78 | { |
||
79 | if( $this->canModifyTranslation( $domain )) { |
||
80 | $replacements = [ |
||
81 | 'Pending Review' => __( 'Unapproved', 'site-reviews' ), |
||
82 | 'Pending' => __( 'Unapproved', 'site-reviews' ), |
||
83 | 'Privately Published' => __( 'Privately Approved', 'site-reviews' ), |
||
84 | 'Published' => __( 'Approved', 'site-reviews' ), |
||
85 | 'Save as Pending' => __( 'Save as Unapproved', 'site-reviews' ), |
||
86 | ]; |
||
87 | foreach( $replacements as $search => $replacement ) { |
||
88 | if( $translation != $search )continue; |
||
89 | $translation = $replacement; |
||
90 | } |
||
91 | } |
||
92 | return $translation; |
||
93 | } |
||
94 | |||
95 | /** |
||
96 | * @param string $translation |
||
97 | * @param string $test |
||
98 | * @param string $domain |
||
99 | * @return string |
||
100 | * @filter gettext_with_context |
||
101 | */ |
||
102 | public function filterPostStatusLabelsWithContext( $translation, $text, $context, $domain ) |
||
1 ignored issue
–
show
|
|||
103 | { |
||
104 | return $this->filterPostStatusLabels( $translation, $text, $domain ); |
||
105 | } |
||
106 | |||
107 | /** |
||
108 | * @return array |
||
109 | * @filter post_updated_messages |
||
110 | */ |
||
111 | public function filterUpdateMessages( array $messages ) |
||
112 | { |
||
113 | $post = get_post(); |
||
114 | if( !( $post instanceof WP_Post ))return; |
||
115 | $strings = glsr( Strings::class )->post_updated_messages(); |
||
116 | $restored = filter_input( INPUT_GET, 'revision' ); |
||
117 | if( $revisionTitle = wp_post_revision_title( intval( $restored ), false )) { |
||
118 | $restored = sprintf( $strings['restored'], $revisionTitle ); |
||
119 | } |
||
120 | $scheduled_date = date_i18n( 'M j, Y @ H:i', strtotime( $post->post_date )); |
||
121 | $messages[ Application::POST_TYPE ] = [ |
||
122 | 1 => $strings['updated'], |
||
123 | 4 => $strings['updated'], |
||
124 | 5 => $restored, |
||
125 | 6 => $strings['published'], |
||
126 | 7 => $strings['saved'], |
||
127 | 8 => $strings['submitted'], |
||
128 | 9 => sprintf( $strings['scheduled'], '<strong>'.$scheduled_date.'</strong>' ), |
||
129 | 10 => $strings['draft_updated'], |
||
130 | 50 => $strings['approved'], |
||
131 | 51 => $strings['unapproved'], |
||
132 | 52 => $strings['reverted'], |
||
133 | ]; |
||
134 | return $messages; |
||
135 | } |
||
136 | |||
137 | /** |
||
138 | * @param array $postData |
||
139 | * @param array $meta |
||
140 | * @param int $postId |
||
141 | * @return void |
||
142 | */ |
||
143 | public function onCreateReview( $postData, $meta, $postId ) |
||
144 | { |
||
145 | if( !$this->isReviewPostType( $review = get_post( $postId )))return; |
||
146 | $this->updateAssignedToPost( $review ); |
||
147 | } |
||
148 | |||
149 | /** |
||
150 | * @param int $postId |
||
151 | * @return void |
||
152 | * @action before_delete_post |
||
153 | */ |
||
154 | public function onDeleteReview( $postId ) |
||
155 | { |
||
156 | if( !$this->isReviewPostType( $review = get_post( $postId )))return; |
||
157 | $review->post_status = 'deleted'; // important to change the post_status here first! |
||
158 | $this->updateAssignedToPost( $review ); |
||
159 | } |
||
160 | |||
161 | /** |
||
162 | * @param int $postId |
||
163 | * @return void |
||
164 | * @action save_post_.static::POST_TYPE |
||
165 | */ |
||
166 | public function onSaveReview( $postId, WP_Post $review ) |
||
167 | { |
||
168 | $this->updateAssignedToPost( $review ); |
||
169 | } |
||
170 | |||
171 | /** |
||
172 | * @param string $postType |
||
173 | * @return void |
||
174 | * @action add_meta_boxes |
||
175 | */ |
||
176 | public function registerMetaBoxes( $postType ) |
||
177 | { |
||
178 | if( $postType != Application::POST_TYPE )return; |
||
179 | add_meta_box( Application::ID.'_assigned_to', __( 'Assigned To', 'site-reviews' ), [$this, 'renderAssignedToMetabox'], null, 'side' ); |
||
180 | add_meta_box( Application::ID.'_review', __( 'Details', 'site-reviews' ), [$this, 'renderDetailsMetaBox'], null, 'side' ); |
||
181 | add_meta_box( Application::ID.'_response', __( 'Respond Publicly', 'site-reviews' ), [$this, 'renderResponseMetaBox'], null, 'normal' ); |
||
182 | } |
||
183 | |||
184 | /** |
||
185 | * @return void |
||
186 | * @action admin_print_scripts |
||
187 | */ |
||
188 | public function removeAutosave() |
||
189 | { |
||
190 | if( $this->isReviewEditor() && !$this->isReviewEditable() ) { |
||
191 | wp_deregister_script( 'autosave' ); |
||
192 | } |
||
193 | } |
||
194 | |||
195 | /** |
||
196 | * @return void |
||
197 | * @action admin_menu |
||
198 | */ |
||
199 | public function removeMetaBoxes() |
||
200 | { |
||
201 | remove_meta_box( 'slugdiv', Application::POST_TYPE, 'advanced' ); |
||
202 | } |
||
203 | |||
204 | /** |
||
205 | * @return void |
||
206 | * @callback add_meta_box |
||
207 | */ |
||
208 | public function renderAssignedToMetabox( WP_Post $post ) |
||
209 | { |
||
210 | if( !$this->isReviewPostType( $post ))return; |
||
211 | $assignedTo = get_post_meta( $post->ID, 'assigned_to', true ); |
||
212 | $template = ''; |
||
213 | if( $assignedPost = get_post( $assignedTo )) { |
||
214 | ob_start(); |
||
215 | glsr( Html::class )->renderTemplate( 'edit/assigned-post', [ |
||
216 | 'context' => [ |
||
217 | 'url' => (string)get_permalink( $assignedPost ), |
||
218 | 'title' => get_the_title( $assignedPost ), |
||
219 | ], |
||
220 | ]); |
||
221 | $template = ob_get_clean(); |
||
222 | } |
||
223 | wp_nonce_field( 'assigned_to', '_nonce-assigned-to', false ); |
||
224 | glsr()->render( 'edit/metabox-assigned-to', [ |
||
225 | 'id' => $assignedTo, |
||
226 | 'template' => $template, |
||
227 | ]); |
||
228 | } |
||
229 | |||
230 | /** |
||
231 | * @return void |
||
232 | * @callback add_meta_box |
||
233 | */ |
||
234 | public function renderDetailsMetaBox( WP_Post $post ) |
||
235 | { |
||
236 | if( !$this->isReviewPostType( $post ))return; |
||
237 | $review = glsr_db()->getReview( $post ); |
||
238 | glsr()->render( 'edit/metabox-details', [ |
||
239 | 'button' => $this->getMetaboxButton( $review, $post ), |
||
240 | 'metabox' => $this->getMetaboxDetails( $review ), |
||
241 | ]); |
||
242 | } |
||
243 | |||
244 | /** |
||
245 | * @return void |
||
246 | * @action post_submitbox_misc_actions |
||
247 | */ |
||
248 | public function renderMetaBoxPinned() |
||
249 | { |
||
250 | if( !$this->isReviewPostType( get_post() ))return; |
||
251 | $pinned = get_post_meta( get_the_ID(), 'pinned', true ); |
||
252 | glsr()->render( 'edit/pinned', [ |
||
253 | 'pinned' => $pinned, |
||
254 | ]); |
||
255 | } |
||
256 | |||
257 | /** |
||
258 | * @return void |
||
259 | * @callback add_meta_box |
||
260 | */ |
||
261 | public function renderResponseMetaBox( WP_Post $post ) |
||
262 | { |
||
263 | if( !$this->isReviewPostType( $post ))return; |
||
264 | $review = glsr_db()->getReview( $post ); |
||
265 | wp_nonce_field( 'response', '_nonce-response', false ); |
||
266 | glsr()->render( 'edit/metabox-response', [ |
||
267 | 'response' => $review->response, |
||
268 | ]); |
||
269 | } |
||
270 | |||
271 | /** |
||
272 | * @return void |
||
273 | * @see glsr_categories_meta_box() |
||
274 | * @callback register_taxonomy |
||
275 | */ |
||
276 | public function renderTaxonomyMetabox( WP_Post $post ) |
||
277 | { |
||
278 | if( !$this->isReviewPostType( $post ))return; |
||
279 | glsr()->render( 'edit/metabox-categories', [ |
||
280 | 'post' => $post, |
||
281 | 'tax_name' => esc_attr( Application::TAXONOMY ), |
||
282 | 'taxonomy' => get_taxonomy( Application::TAXONOMY ), |
||
283 | ]); |
||
284 | } |
||
285 | |||
286 | /** |
||
287 | * @return void |
||
288 | * @see $this->filterUpdateMessages() |
||
289 | * @action admin_action_revert |
||
290 | */ |
||
291 | public function revert() |
||
292 | { |
||
293 | check_admin_referer( 'revert-review_'.( $postId = $this->getPostId() )); |
||
294 | glsr_db()->revertReview( $postId ); |
||
295 | $this->redirect( $postId, 52 ); |
||
296 | } |
||
297 | |||
298 | /** |
||
299 | * @param int $postId |
||
300 | * @return void |
||
301 | * @action save_post_.Application::POST_TYPE |
||
302 | */ |
||
303 | public function saveMetaboxes( $postId ) |
||
304 | { |
||
305 | $this->saveAssignedToMetabox( $postId ); |
||
306 | $this->saveResponseMetabox( $postId ); |
||
307 | } |
||
308 | |||
309 | /** |
||
310 | * @param string $domain |
||
311 | * @return bool |
||
312 | */ |
||
313 | protected function canModifyTranslation( $domain = 'default' ) |
||
314 | { |
||
315 | return glsr_current_screen()->post_type == Application::POST_TYPE |
||
316 | && in_array( glsr_current_screen()->base, ['edit', 'post'] ) |
||
317 | && $domain == 'default'; |
||
318 | } |
||
319 | |||
320 | /** |
||
321 | * @param int $postId |
||
322 | * @return int|false |
||
323 | */ |
||
324 | protected function getAssignedToPostId( $postId ) |
||
325 | { |
||
326 | $assignedTo = get_post_meta( $postId, 'assigned_to', true ); |
||
327 | if(( $post = get_post( $assignedTo )) instanceof WP_Post ) { |
||
328 | return $post->ID; |
||
329 | } |
||
330 | return false; |
||
331 | } |
||
332 | |||
333 | /** |
||
334 | * @param object $review |
||
335 | * @return string |
||
336 | */ |
||
337 | protected function getMetaboxButton( $review, WP_Post $post ) |
||
338 | { |
||
339 | $modified = false; |
||
340 | if( $post->post_title !== $review->title |
||
341 | || $post->post_content !== $review->content |
||
342 | || $post->post_date !== $review->date ) { |
||
343 | $modified = true; |
||
344 | } |
||
345 | $revertUrl = wp_nonce_url( |
||
346 | admin_url( 'post.php?post='.$post->ID.'&action=revert' ), |
||
347 | 'revert-review_'.$post->ID |
||
348 | ); |
||
349 | return !$modified |
||
350 | ? sprintf( '<button id="revert" class="button button-large" disabled>%s</button>', __( 'Nothing to Revert', 'site-reviews' )) |
||
351 | : sprintf( '<a href="%s" id="revert" class="button button-large">%s</a>', $revertUrl, __( 'Revert Changes', 'site-reviews' )); |
||
352 | } |
||
353 | |||
354 | /** |
||
355 | * @param object $review |
||
356 | * @return array |
||
357 | */ |
||
358 | protected function getMetaboxDetails( $review ) |
||
359 | { |
||
360 | $reviewer = empty( $review->user_id ) |
||
361 | ? __( 'Unregistered user', 'site-reviews' ) |
||
362 | : $this->generateLink( get_the_author_meta( 'display_name', $review->user_id ), [ |
||
363 | 'href' => get_author_posts_url( $review->user_id ), |
||
364 | ]); |
||
365 | $email = empty( $review->email ) |
||
366 | ? '—' |
||
367 | : $this->generateLink( $review->email, [ |
||
368 | 'href' => 'mailto:'.$review->email.'?subject='.esc_attr( __( 'RE:', 'site-reviews' ).' '.$review->title ), |
||
369 | ]); |
||
370 | $metabox = [ |
||
371 | __( 'Rating', 'site-reviews' ) => glsr( Html::class )->renderPartial( 'star-rating', ['rating' => $review->rating] ), |
||
372 | __( 'Type', 'site-reviews' ) => $this->getReviewType( $review ), |
||
373 | __( 'Date', 'site-reviews' ) => get_date_from_gmt( $review->date, 'F j, Y' ), |
||
374 | __( 'Reviewer', 'site-reviews' ) => $reviewer, |
||
375 | __( 'Name', 'site-reviews' ) => $review->author, |
||
376 | __( 'Email', 'site-reviews' ) => $email, |
||
377 | __( 'IP Address', 'site-reviews' ) => $review->ip_address, |
||
378 | __( 'Avatar', 'site-reviews' ) => sprintf( '<img src="%s" width="96">', $review->avatar ), |
||
379 | ]; |
||
380 | return apply_filters( 'site-reviews/metabox/details', $metabox, $review ); |
||
381 | } |
||
382 | |||
383 | /** |
||
384 | * @param object $review |
||
385 | * @return string |
||
386 | */ |
||
387 | protected function getReviewType( $review ) |
||
388 | { |
||
389 | $reviewType = $review->review_type; |
||
390 | $reviewTypeFallback = !empty( $review->review_type ) |
||
391 | ? ucfirst( $review->review_type ) |
||
392 | : __( 'Unknown', 'site-reviews' ); |
||
393 | if( !empty( $review->url )) { |
||
394 | $reviewType = $this->generateLink( $reviewType, [ |
||
395 | 'href' => $review->url, |
||
396 | 'target' => '_blank', |
||
397 | ]); |
||
398 | } |
||
399 | return sprintf( __( '%s review', 'site-reviews' ), |
||
400 | glsr( Strings::class )->review_types( $reviewType, $reviewTypeFallback ) |
||
401 | ); |
||
402 | } |
||
403 | |||
404 | /** |
||
405 | * @return bool |
||
406 | */ |
||
407 | protected function isReviewEditable() |
||
408 | { |
||
409 | $postId = intval( filter_input( INPUT_GET, 'post' )); |
||
410 | return $postId > 0 |
||
411 | && get_post_meta( $postId, 'review_type', true ) == 'local' |
||
412 | && $this->isReviewEditor(); |
||
413 | } |
||
414 | |||
415 | /** |
||
416 | * @return bool |
||
417 | */ |
||
418 | protected function isReviewEditor() |
||
419 | { |
||
420 | return glsr_current_screen()->base == 'post' |
||
421 | && glsr_current_screen()->id == Application::POST_TYPE |
||
422 | && glsr_current_screen()->post_type == Application::POST_TYPE; |
||
423 | } |
||
424 | |||
425 | /** |
||
426 | * @param mixed $post |
||
427 | * @return bool |
||
428 | */ |
||
429 | protected function isReviewPostType( $post ) |
||
432 | } |
||
433 | |||
434 | /** |
||
435 | * @return int |
||
436 | */ |
||
437 | protected function recalculatePostAverage( array $reviews ) |
||
438 | { |
||
439 | return glsr( Rating::class )->getAverage( $reviews ); |
||
440 | } |
||
441 | |||
442 | /** |
||
443 | * @return int |
||
444 | */ |
||
445 | protected function recalculatePostRanking( array $reviews ) |
||
446 | { |
||
447 | return glsr( Rating::class )->getRanking( $reviews ); |
||
448 | } |
||
449 | |||
450 | /** |
||
451 | * @param int $postId |
||
452 | * @param int $messageIndex |
||
453 | * @return void |
||
454 | */ |
||
455 | protected function redirect( $postId, $messageIndex ) |
||
456 | { |
||
457 | $referer = wp_get_referer(); |
||
458 | $hasReferer = !$referer |
||
459 | || strpos( $referer, 'post.php' ) !== false |
||
460 | || strpos( $referer, 'post-new.php' ) !== false; |
||
461 | $redirectUri = $hasReferer |
||
462 | ? remove_query_arg( ['deleted', 'ids', 'trashed', 'untrashed'], $referer ) |
||
463 | : get_edit_post_link( $postId, false ); |
||
464 | wp_safe_redirect( add_query_arg( ['message' => $messageIndex], $redirectUri )); |
||
465 | exit; |
||
1 ignored issue
–
show
|
|||
466 | } |
||
467 | |||
468 | /** |
||
469 | * @param int $postId |
||
470 | * @return void |
||
471 | */ |
||
472 | protected function saveAssignedToMetabox( $postId ) |
||
473 | { |
||
474 | if( !wp_verify_nonce( filter_input( INPUT_POST, '_nonce-assigned-to' ), 'assigned_to' ))return; |
||
475 | $assignedTo = filter_input( INPUT_POST, 'assigned_to' ); |
||
476 | $assignedTo || $assignedTo = ''; |
||
477 | if( get_post_meta( $postId, 'assigned_to', true ) != $assignedTo ) { |
||
478 | $this->onDeleteReview( $postId ); |
||
479 | } |
||
480 | update_post_meta( $postId, 'assigned_to', $assignedTo ); |
||
481 | } |
||
482 | |||
483 | /** |
||
484 | * @param int $postId |
||
485 | * @return mixed |
||
486 | */ |
||
487 | protected function saveResponseMetabox( $postId ) |
||
496 | ]))); |
||
497 | } |
||
498 | |||
499 | /** |
||
500 | * @return void |
||
501 | */ |
||
502 | protected function updateAssignedToPost( WP_Post $review ) |
||
503 | { |
||
504 | if( !( $postId = $this->getAssignedToPostId( $review->ID )))return; |
||
505 | $reviewIds = get_post_meta( $postId, static::META_REVIEW_ID ); |
||
506 | $updatedReviewIds = array_filter( (array)get_post_meta( $postId, static::META_REVIEW_ID )); |
||
519 | } |
||
520 | } |
||
521 | |||
522 | /** |
||
523 | * @param int $postId |
||
524 | * @return void |
||
525 | */ |
||
526 | protected function updateReviewIdOfPost( $postId, WP_Post $review, array $reviewIds ) |
||
527 | { |
||
528 | if( $review->post_status != 'publish' ) { |
||
529 | delete_post_meta( $postId, static::META_REVIEW_ID, $review->ID ); |
||
530 | } |
||
531 | else if( !in_array( $review->ID, $reviewIds )) { |
||
532 | add_post_meta( $postId, static::META_REVIEW_ID, $review->ID ); |
||
533 | } |
||
534 | } |
||
535 | } |
||
536 |
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.
excluded_paths: ["lib/*"]
, you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths