Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like WP_Press_This 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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
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 WP_Press_This, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
15 | class WP_Press_This { |
||
16 | |||
17 | // Used to trigger the bookmarklet update notice. |
||
18 | public $version = 8; |
||
19 | |||
20 | private $images = array(); |
||
21 | |||
22 | private $embeds = array(); |
||
23 | |||
24 | private $domain = ''; |
||
25 | |||
26 | /** |
||
27 | * Constructor. |
||
28 | * |
||
29 | * @since 4.2.0 |
||
30 | * @access public |
||
31 | */ |
||
32 | public function __construct() {} |
||
33 | |||
34 | /** |
||
35 | * App and site settings data, including i18n strings for the client-side. |
||
36 | * |
||
37 | * @since 4.2.0 |
||
38 | * @access public |
||
39 | * |
||
40 | * @return array Site settings. |
||
41 | */ |
||
42 | public function site_settings() { |
||
43 | return array( |
||
44 | /** |
||
45 | * Filters whether or not Press This should redirect the user in the parent window upon save. |
||
46 | * |
||
47 | * @since 4.2.0 |
||
48 | * |
||
49 | * @param bool $redirect Whether to redirect in parent window or not. Default false. |
||
50 | */ |
||
51 | 'redirInParent' => apply_filters( 'press_this_redirect_in_parent', false ), |
||
52 | ); |
||
53 | } |
||
54 | |||
55 | /** |
||
56 | * Get the source's images and save them locally, for posterity, unless we can't. |
||
57 | * |
||
58 | * @since 4.2.0 |
||
59 | * @access public |
||
60 | * |
||
61 | * @param int $post_id Post ID. |
||
62 | * @param string $content Optional. Current expected markup for Press This. Expects slashed. Default empty. |
||
63 | * @return string New markup with old image URLs replaced with the local attachment ones if swapped. |
||
64 | */ |
||
65 | public function side_load_images( $post_id, $content = '' ) { |
||
97 | |||
98 | /** |
||
99 | * Ajax handler for saving the post as draft or published. |
||
100 | * |
||
101 | * @since 4.2.0 |
||
102 | * @access public |
||
103 | */ |
||
104 | public function save_post() { |
||
105 | if ( empty( $_POST['post_ID'] ) || ! $post_id = (int) $_POST['post_ID'] ) { |
||
106 | wp_send_json_error( array( 'errorMessage' => __( 'Missing post ID.' ) ) ); |
||
107 | } |
||
108 | |||
109 | if ( empty( $_POST['_wpnonce'] ) || ! wp_verify_nonce( $_POST['_wpnonce'], 'update-post_' . $post_id ) || |
||
|
|||
110 | ! current_user_can( 'edit_post', $post_id ) ) { |
||
111 | |||
112 | wp_send_json_error( array( 'errorMessage' => __( 'Invalid post.' ) ) ); |
||
113 | } |
||
114 | |||
115 | $post_data = array( |
||
116 | 'ID' => $post_id, |
||
117 | 'post_title' => ( ! empty( $_POST['post_title'] ) ) ? sanitize_text_field( trim( $_POST['post_title'] ) ) : '', |
||
118 | 'post_content' => ( ! empty( $_POST['post_content'] ) ) ? trim( $_POST['post_content'] ) : '', |
||
119 | 'post_type' => 'post', |
||
120 | 'post_status' => 'draft', |
||
121 | 'post_format' => ( ! empty( $_POST['post_format'] ) ) ? sanitize_text_field( $_POST['post_format'] ) : '', |
||
122 | 'tax_input' => ( ! empty( $_POST['tax_input'] ) ) ? $_POST['tax_input'] : array(), |
||
123 | 'post_category' => ( ! empty( $_POST['post_category'] ) ) ? $_POST['post_category'] : array(), |
||
124 | ); |
||
125 | |||
126 | if ( ! empty( $_POST['post_status'] ) && 'publish' === $_POST['post_status'] ) { |
||
127 | if ( current_user_can( 'publish_posts' ) ) { |
||
128 | $post_data['post_status'] = 'publish'; |
||
129 | } else { |
||
130 | $post_data['post_status'] = 'pending'; |
||
131 | } |
||
132 | } |
||
133 | |||
134 | $post_data['post_content'] = $this->side_load_images( $post_id, $post_data['post_content'] ); |
||
135 | |||
136 | /** |
||
137 | * Filters the post data of a Press This post before saving/updating. |
||
138 | * |
||
139 | * The {@see 'side_load_images'} action has already run at this point. |
||
140 | * |
||
141 | * @since 4.5.0 |
||
142 | * |
||
143 | * @param array $post_data The post data. |
||
144 | */ |
||
145 | $post_data = apply_filters( 'press_this_save_post', $post_data ); |
||
146 | |||
147 | $updated = wp_update_post( $post_data, true ); |
||
148 | |||
149 | if ( is_wp_error( $updated ) ) { |
||
150 | wp_send_json_error( array( 'errorMessage' => $updated->get_error_message() ) ); |
||
151 | } else { |
||
152 | if ( isset( $post_data['post_format'] ) ) { |
||
153 | if ( current_theme_supports( 'post-formats', $post_data['post_format'] ) ) { |
||
154 | set_post_format( $post_id, $post_data['post_format'] ); |
||
155 | } elseif ( $post_data['post_format'] ) { |
||
156 | set_post_format( $post_id, false ); |
||
157 | } |
||
158 | } |
||
159 | |||
160 | $forceRedirect = false; |
||
161 | |||
162 | if ( 'publish' === get_post_status( $post_id ) ) { |
||
163 | $redirect = get_post_permalink( $post_id ); |
||
164 | } elseif ( isset( $_POST['pt-force-redirect'] ) && $_POST['pt-force-redirect'] === 'true' ) { |
||
165 | $forceRedirect = true; |
||
166 | $redirect = get_edit_post_link( $post_id, 'js' ); |
||
167 | } else { |
||
168 | $redirect = false; |
||
169 | } |
||
170 | |||
171 | /** |
||
172 | * Filters the URL to redirect to when Press This saves. |
||
173 | * |
||
174 | * @since 4.2.0 |
||
175 | * |
||
176 | * @param string $url Redirect URL. If `$status` is 'publish', this will be the post permalink. |
||
177 | * Otherwise, the default is false resulting in no redirect. |
||
178 | * @param int $post_id Post ID. |
||
179 | * @param string $status Post status. |
||
180 | */ |
||
181 | $redirect = apply_filters( 'press_this_save_redirect', $redirect, $post_id, $post_data['post_status'] ); |
||
182 | |||
183 | if ( $redirect ) { |
||
184 | wp_send_json_success( array( 'redirect' => $redirect, 'force' => $forceRedirect ) ); |
||
185 | } else { |
||
186 | wp_send_json_success( array( 'postSaved' => true ) ); |
||
187 | } |
||
188 | } |
||
189 | } |
||
190 | |||
191 | /** |
||
192 | * Ajax handler for adding a new category. |
||
193 | * |
||
194 | * @since 4.2.0 |
||
195 | * @access public |
||
196 | */ |
||
197 | public function add_category() { |
||
259 | |||
260 | /** |
||
261 | * Downloads the source's HTML via server-side call for the given URL. |
||
262 | * |
||
263 | * @since 4.2.0 |
||
264 | * @access public |
||
265 | * |
||
266 | * @param string $url URL to scan. |
||
267 | * @return string Source's HTML sanitized markup |
||
268 | */ |
||
269 | public function fetch_source_html( $url ) { |
||
270 | global $wp_version; |
||
271 | |||
272 | if ( empty( $url ) ) { |
||
273 | return new WP_Error( 'invalid-url', __( 'A valid URL was not provided.' ) ); |
||
274 | } |
||
275 | |||
276 | $remote_url = wp_safe_remote_get( $url, array( |
||
277 | 'timeout' => 30, |
||
278 | // Use an explicit user-agent for Press This |
||
279 | 'user-agent' => 'Press This (WordPress/' . $wp_version . '); ' . get_bloginfo( 'url' ) |
||
280 | ) ); |
||
281 | |||
282 | if ( is_wp_error( $remote_url ) ) { |
||
283 | return $remote_url; |
||
284 | } |
||
285 | |||
286 | $allowed_elements = array( |
||
287 | 'img' => array( |
||
288 | 'src' => true, |
||
289 | 'width' => true, |
||
290 | 'height' => true, |
||
291 | ), |
||
292 | 'iframe' => array( |
||
293 | 'src' => true, |
||
294 | ), |
||
295 | 'link' => array( |
||
296 | 'rel' => true, |
||
297 | 'itemprop' => true, |
||
298 | 'href' => true, |
||
299 | ), |
||
300 | 'meta' => array( |
||
301 | 'property' => true, |
||
302 | 'name' => true, |
||
303 | 'content' => true, |
||
304 | ) |
||
305 | ); |
||
306 | |||
307 | $source_content = wp_remote_retrieve_body( $remote_url ); |
||
308 | $source_content = wp_kses( $source_content, $allowed_elements ); |
||
309 | |||
310 | return $source_content; |
||
311 | } |
||
312 | |||
313 | /** |
||
314 | * Utility method to limit an array to 50 values. |
||
315 | * |
||
316 | * @ignore |
||
317 | * @since 4.2.0 |
||
318 | * |
||
319 | * @param array $value Array to limit. |
||
320 | * @return array Original array if fewer than 50 values, limited array, empty array otherwise. |
||
321 | */ |
||
322 | private function _limit_array( $value ) { |
||
333 | |||
334 | /** |
||
335 | * Utility method to limit the length of a given string to 5,000 characters. |
||
336 | * |
||
337 | * @ignore |
||
338 | * @since 4.2.0 |
||
339 | * |
||
340 | * @param string $value String to limit. |
||
341 | * @return bool|int|string If boolean or integer, that value. If a string, the original value |
||
342 | * if fewer than 5,000 characters, a truncated version, otherwise an |
||
343 | * empty string. |
||
344 | */ |
||
345 | private function _limit_string( $value ) { |
||
363 | |||
364 | /** |
||
365 | * Utility method to limit a given URL to 2,048 characters. |
||
366 | * |
||
367 | * @ignore |
||
368 | * @since 4.2.0 |
||
369 | * |
||
370 | * @param string $url URL to check for length and validity. |
||
371 | * @return string Escaped URL if of valid length (< 2048) and makeup. Empty string otherwise. |
||
372 | */ |
||
373 | private function _limit_url( $url ) { |
||
374 | if ( ! is_string( $url ) ) { |
||
375 | return ''; |
||
376 | } |
||
377 | |||
378 | // HTTP 1.1 allows 8000 chars but the "de-facto" standard supported in all current browsers is 2048. |
||
379 | if ( strlen( $url ) > 2048 ) { |
||
380 | return ''; // Return empty rather than a truncated/invalid URL |
||
381 | } |
||
382 | |||
383 | // Does not look like a URL. |
||
384 | if ( ! preg_match( '/^([!#$&-;=?-\[\]_a-z~]|%[0-9a-fA-F]{2})+$/', $url ) ) { |
||
385 | return ''; |
||
386 | } |
||
387 | |||
388 | // If the URL is root-relative, prepend the protocol and domain name |
||
389 | if ( $url && $this->domain && preg_match( '%^/[^/]+%', $url ) ) { |
||
390 | $url = $this->domain . $url; |
||
391 | } |
||
392 | |||
393 | // Not absolute or protocol-relative URL. |
||
394 | if ( ! preg_match( '%^(?:https?:)?//[^/]+%', $url ) ) { |
||
395 | return ''; |
||
396 | } |
||
397 | |||
398 | return esc_url_raw( $url, array( 'http', 'https' ) ); |
||
399 | } |
||
400 | |||
401 | /** |
||
402 | * Utility method to limit image source URLs. |
||
403 | * |
||
404 | * Excluded URLs include share-this type buttons, loaders, spinners, spacers, WordPress interface images, |
||
405 | * tiny buttons or thumbs, mathtag.com or quantserve.com images, or the WordPress.com stats gif. |
||
406 | * |
||
407 | * @ignore |
||
408 | * @since 4.2.0 |
||
409 | * |
||
410 | * @param string $src Image source URL. |
||
411 | * @return string If not matched an excluded URL type, the original URL, empty string otherwise. |
||
412 | */ |
||
413 | private function _limit_img( $src ) { |
||
447 | |||
448 | /** |
||
449 | * Limit embed source URLs to specific providers. |
||
450 | * |
||
451 | * Not all core oEmbed providers are supported. Supported providers include YouTube, Vimeo, |
||
452 | * Vine, Daily Motion, SoundCloud, and Twitter. |
||
453 | * |
||
454 | * @ignore |
||
455 | * @since 4.2.0 |
||
456 | * |
||
457 | * @param string $src Embed source URL. |
||
458 | * @return string If not from a supported provider, an empty string. Otherwise, a reformattd embed URL. |
||
459 | */ |
||
460 | private function _limit_embed( $src ) { |
||
492 | |||
493 | /** |
||
494 | * Process a meta data entry from the source. |
||
495 | * |
||
496 | * @ignore |
||
497 | * @since 4.2.0 |
||
498 | * |
||
499 | * @param string $meta_name Meta key name. |
||
500 | * @param mixed $meta_value Meta value. |
||
501 | * @param array $data Associative array of source data. |
||
502 | * @return array Processed data array. |
||
503 | */ |
||
504 | private function _process_meta_entry( $meta_name, $meta_value, $data ) { |
||
545 | |||
546 | /** |
||
547 | * Fetches and parses _meta, _images, and _links data from the source. |
||
548 | * |
||
549 | * @since 4.2.0 |
||
550 | * @access public |
||
551 | * |
||
552 | * @param string $url URL to scan. |
||
553 | * @param array $data Optional. Existing data array if you have one. Default empty array. |
||
554 | * @return array New data array. |
||
555 | */ |
||
556 | public function source_data_fetch_fallback( $url, $data = array() ) { |
||
655 | |||
656 | /** |
||
657 | * Handles backward-compat with the legacy version of Press This by supporting its query string params. |
||
658 | * |
||
659 | * @since 4.2.0 |
||
660 | * @access public |
||
661 | * |
||
662 | * @return array |
||
663 | */ |
||
664 | public function merge_or_fetch_data() { |
||
665 | // Get data from $_POST and $_GET, as appropriate ($_POST > $_GET), to remain backward compatible. |
||
666 | $data = array(); |
||
667 | |||
668 | // Only instantiate the keys we want. Sanity check and sanitize each one. |
||
669 | foreach ( array( 'u', 's', 't', 'v' ) as $key ) { |
||
670 | if ( ! empty( $_POST[ $key ] ) ) { |
||
671 | $value = wp_unslash( $_POST[ $key ] ); |
||
672 | } else if ( ! empty( $_GET[ $key ] ) ) { |
||
673 | $value = wp_unslash( $_GET[ $key ] ); |
||
674 | } else { |
||
675 | continue; |
||
676 | } |
||
677 | |||
678 | if ( 'u' === $key ) { |
||
679 | $value = $this->_limit_url( $value ); |
||
680 | |||
681 | if ( preg_match( '%^(?:https?:)?//[^/]+%i', $value, $domain_match ) ) { |
||
682 | $this->domain = $domain_match[0]; |
||
683 | } |
||
684 | } else { |
||
685 | $value = $this->_limit_string( $value ); |
||
686 | } |
||
687 | |||
688 | if ( ! empty( $value ) ) { |
||
689 | $data[ $key ] = $value; |
||
690 | } |
||
691 | } |
||
692 | |||
693 | /** |
||
694 | * Filters whether to enable in-source media discovery in Press This. |
||
695 | * |
||
696 | * @since 4.2.0 |
||
697 | * |
||
698 | * @param bool $enable Whether to enable media discovery. |
||
699 | */ |
||
700 | if ( apply_filters( 'enable_press_this_media_discovery', true ) ) { |
||
701 | /* |
||
702 | * If no title, _images, _embed, and _meta was passed via $_POST, fetch data from source as fallback, |
||
703 | * making PT fully backward compatible with the older bookmarklet. |
||
704 | */ |
||
705 | if ( empty( $_POST ) && ! empty( $data['u'] ) ) { |
||
706 | $data = $this->source_data_fetch_fallback( $data['u'], $data ); |
||
707 | } else { |
||
708 | foreach ( array( '_images', '_embeds' ) as $type ) { |
||
709 | if ( empty( $_POST[ $type ] ) ) { |
||
710 | continue; |
||
711 | } |
||
712 | |||
713 | $data[ $type ] = array(); |
||
714 | $items = $this->_limit_array( $_POST[ $type ] ); |
||
715 | |||
716 | foreach ( $items as $key => $value ) { |
||
717 | if ( $type === '_images' ) { |
||
718 | $value = $this->_limit_img( wp_unslash( $value ) ); |
||
719 | } else { |
||
720 | $value = $this->_limit_embed( wp_unslash( $value ) ); |
||
721 | } |
||
722 | |||
723 | if ( ! empty( $value ) ) { |
||
724 | $data[ $type ][] = $value; |
||
725 | } |
||
726 | } |
||
727 | } |
||
728 | |||
729 | foreach ( array( '_meta', '_links' ) as $type ) { |
||
730 | if ( empty( $_POST[ $type ] ) ) { |
||
731 | continue; |
||
732 | } |
||
733 | |||
734 | $data[ $type ] = array(); |
||
735 | $items = $this->_limit_array( $_POST[ $type ] ); |
||
736 | |||
737 | foreach ( $items as $key => $value ) { |
||
738 | // Sanity check. These are associative arrays, $key is usually things like 'title', 'description', 'keywords', etc. |
||
739 | if ( empty( $key ) || strlen( $key ) > 100 ) { |
||
740 | continue; |
||
741 | } |
||
742 | |||
743 | if ( $type === '_meta' ) { |
||
744 | $value = $this->_limit_string( wp_unslash( $value ) ); |
||
745 | |||
746 | if ( ! empty( $value ) ) { |
||
747 | $data = $this->_process_meta_entry( $key, $value, $data ); |
||
748 | } |
||
749 | } else { |
||
750 | if ( in_array( $key, array( 'canonical', 'shortlink', 'icon' ), true ) ) { |
||
751 | $data[ $type ][ $key ] = $this->_limit_url( wp_unslash( $value ) ); |
||
752 | } |
||
753 | } |
||
754 | } |
||
755 | } |
||
756 | } |
||
757 | |||
758 | // Support passing a single image src as `i` |
||
759 | if ( ! empty( $_REQUEST['i'] ) && ( $img_src = $this->_limit_img( wp_unslash( $_REQUEST['i'] ) ) ) ) { |
||
760 | if ( empty( $data['_images'] ) ) { |
||
761 | $data['_images'] = array( $img_src ); |
||
762 | } elseif ( ! in_array( $img_src, $data['_images'], true ) ) { |
||
763 | array_unshift( $data['_images'], $img_src ); |
||
764 | } |
||
765 | } |
||
766 | } |
||
767 | |||
768 | /** |
||
769 | * Filters the Press This data array. |
||
770 | * |
||
771 | * @since 4.2.0 |
||
772 | * |
||
773 | * @param array $data Press This Data array. |
||
774 | */ |
||
775 | return apply_filters( 'press_this_data', $data ); |
||
776 | } |
||
777 | |||
778 | /** |
||
779 | * Adds another stylesheet inside TinyMCE. |
||
780 | * |
||
781 | * @since 4.2.0 |
||
782 | * @access public |
||
783 | * |
||
784 | * @param string $styles URL to editor stylesheet. |
||
785 | * @return string Possibly modified stylesheets list. |
||
786 | */ |
||
787 | public function add_editor_style( $styles ) { |
||
788 | if ( ! empty( $styles ) ) { |
||
789 | $styles .= ','; |
||
790 | } |
||
791 | |||
792 | $press_this = admin_url( 'css/press-this-editor.css' ); |
||
793 | if ( is_rtl() ) { |
||
794 | $press_this = str_replace( '.css', '-rtl.css', $press_this ); |
||
795 | } |
||
796 | |||
797 | return $styles . $press_this; |
||
798 | } |
||
799 | |||
800 | /** |
||
801 | * Outputs the post format selection HTML. |
||
802 | * |
||
803 | * @since 4.2.0 |
||
804 | * @access public |
||
805 | * |
||
806 | * @param WP_Post $post Post object. |
||
807 | */ |
||
808 | public function post_formats_html( $post ) { |
||
809 | if ( current_theme_supports( 'post-formats' ) && post_type_supports( $post->post_type, 'post-formats' ) ) { |
||
810 | $post_formats = get_theme_support( 'post-formats' ); |
||
811 | |||
812 | if ( is_array( $post_formats[0] ) ) { |
||
813 | $post_format = get_post_format( $post->ID ); |
||
814 | |||
815 | if ( ! $post_format ) { |
||
816 | $post_format = '0'; |
||
817 | } |
||
818 | |||
819 | // Add in the current one if it isn't there yet, in case the current theme doesn't support it. |
||
820 | View Code Duplication | if ( $post_format && ! in_array( $post_format, $post_formats[0] ) ) { |
|
821 | $post_formats[0][] = $post_format; |
||
822 | } |
||
823 | |||
824 | ?> |
||
825 | <div id="post-formats-select"> |
||
826 | <fieldset><legend class="screen-reader-text"><?php _e( 'Post Formats' ); ?></legend> |
||
827 | <input type="radio" name="post_format" class="post-format" id="post-format-0" value="0" <?php checked( $post_format, '0' ); ?> /> |
||
828 | <label for="post-format-0" class="post-format-icon post-format-standard"><?php echo get_post_format_string( 'standard' ); ?></label> |
||
829 | <?php |
||
830 | |||
831 | foreach ( $post_formats[0] as $format ) { |
||
832 | $attr_format = esc_attr( $format ); |
||
833 | ?> |
||
834 | <br /> |
||
835 | <input type="radio" name="post_format" class="post-format" id="post-format-<?php echo $attr_format; ?>" value="<?php echo $attr_format; ?>" <?php checked( $post_format, $format ); ?> /> |
||
836 | <label for="post-format-<?php echo $attr_format ?>" class="post-format-icon post-format-<?php echo $attr_format; ?>"><?php echo esc_html( get_post_format_string( $format ) ); ?></label> |
||
837 | <?php |
||
838 | } |
||
839 | |||
840 | ?> |
||
841 | </fieldset> |
||
842 | </div> |
||
843 | <?php |
||
844 | } |
||
845 | } |
||
846 | } |
||
847 | |||
848 | /** |
||
849 | * Outputs the categories HTML. |
||
850 | * |
||
851 | * @since 4.2.0 |
||
852 | * @access public |
||
853 | * |
||
854 | * @param WP_Post $post Post object. |
||
855 | */ |
||
856 | public function categories_html( $post ) { |
||
899 | |||
900 | /** |
||
901 | * Outputs the tags HTML. |
||
902 | * |
||
903 | * @since 4.2.0 |
||
904 | * @access public |
||
905 | * |
||
906 | * @param WP_Post $post Post object. |
||
907 | */ |
||
908 | public function tags_html( $post ) { |
||
909 | $taxonomy = get_taxonomy( 'post_tag' ); |
||
910 | $user_can_assign_terms = current_user_can( $taxonomy->cap->assign_terms ); |
||
911 | $esc_tags = get_terms_to_edit( $post->ID, 'post_tag' ); |
||
912 | |||
913 | if ( ! $esc_tags || is_wp_error( $esc_tags ) ) { |
||
914 | $esc_tags = ''; |
||
915 | } |
||
916 | |||
917 | ?> |
||
918 | <div class="tagsdiv" id="post_tag"> |
||
919 | <div class="jaxtag"> |
||
920 | <input type="hidden" name="tax_input[post_tag]" class="the-tags" value="<?php echo $esc_tags; // escaped in get_terms_to_edit() ?>"> |
||
921 | <?php |
||
922 | |||
923 | if ( $user_can_assign_terms ) { |
||
924 | ?> |
||
925 | <div class="ajaxtag hide-if-no-js"> |
||
926 | <label class="screen-reader-text" for="new-tag-post_tag"><?php _e( 'Tags' ); ?></label> |
||
927 | <p> |
||
928 | <input type="text" id="new-tag-post_tag" name="newtag[post_tag]" class="newtag form-input-tip" size="16" autocomplete="off" value="" aria-describedby="new-tag-desc" /> |
||
929 | <button type="button" class="tagadd"><?php _e( 'Add' ); ?></button> |
||
930 | </p> |
||
931 | </div> |
||
932 | <p class="howto" id="new-tag-desc"> |
||
933 | <?php echo $taxonomy->labels->separate_items_with_commas; ?> |
||
934 | </p> |
||
935 | <?php |
||
936 | } |
||
937 | |||
938 | ?> |
||
939 | </div> |
||
940 | <div class="tagchecklist"></div> |
||
941 | </div> |
||
942 | <?php |
||
943 | |||
944 | if ( $user_can_assign_terms ) { |
||
945 | ?> |
||
946 | <button type="button" class="button-link tagcloud-link" id="link-post_tag"><?php echo $taxonomy->labels->choose_from_most_used; ?></button> |
||
947 | <?php |
||
948 | } |
||
949 | } |
||
950 | |||
951 | /** |
||
952 | * Get a list of embeds with no duplicates. |
||
953 | * |
||
954 | * @since 4.2.0 |
||
955 | * @access public |
||
956 | * |
||
957 | * @param array $data The site's data. |
||
958 | * @return array Embeds selected to be available. |
||
959 | */ |
||
960 | public function get_embeds( $data ) { |
||
961 | $selected_embeds = array(); |
||
962 | |||
963 | // Make sure to add the Pressed page if it's a valid oembed itself |
||
964 | if ( ! empty ( $data['u'] ) && $this->_limit_embed( $data['u'] ) ) { |
||
965 | $data['_embeds'][] = $data['u']; |
||
966 | } |
||
967 | |||
968 | if ( ! empty( $data['_embeds'] ) ) { |
||
969 | foreach ( $data['_embeds'] as $src ) { |
||
970 | $prot_relative_src = preg_replace( '/^https?:/', '', $src ); |
||
971 | |||
972 | if ( in_array( $prot_relative_src, $this->embeds ) ) { |
||
973 | continue; |
||
974 | } |
||
975 | |||
976 | $selected_embeds[] = $src; |
||
977 | $this->embeds[] = $prot_relative_src; |
||
978 | } |
||
979 | } |
||
980 | |||
981 | return $selected_embeds; |
||
982 | } |
||
983 | |||
984 | /** |
||
985 | * Get a list of images with no duplicates. |
||
986 | * |
||
987 | * @since 4.2.0 |
||
988 | * @access public |
||
989 | * |
||
990 | * @param array $data The site's data. |
||
991 | * @return array |
||
992 | */ |
||
993 | public function get_images( $data ) { |
||
1017 | |||
1018 | /** |
||
1019 | * Gets the source page's canonical link, based on passed location and meta data. |
||
1020 | * |
||
1021 | * @since 4.2.0 |
||
1022 | * @access public |
||
1023 | * |
||
1024 | * @param array $data The site's data. |
||
1025 | * @return string Discovered canonical URL, or empty |
||
1026 | */ |
||
1027 | public function get_canonical_link( $data ) { |
||
1048 | |||
1049 | /** |
||
1050 | * Gets the source page's site name, based on passed meta data. |
||
1051 | * |
||
1052 | * @since 4.2.0 |
||
1053 | * @access public |
||
1054 | * |
||
1055 | * @param array $data The site's data. |
||
1056 | * @return string Discovered site name, or empty |
||
1057 | */ |
||
1058 | public function get_source_site_name( $data ) { |
||
1071 | |||
1072 | /** |
||
1073 | * Gets the source page's title, based on passed title and meta data. |
||
1074 | * |
||
1075 | * @since 4.2.0 |
||
1076 | * @access public |
||
1077 | * |
||
1078 | * @param array $data The site's data. |
||
1079 | * @return string Discovered page title, or empty |
||
1080 | */ |
||
1081 | public function get_suggested_title( $data ) { |
||
1098 | |||
1099 | /** |
||
1100 | * Gets the source page's suggested content, based on passed data (description, selection, etc). |
||
1101 | * |
||
1102 | * Features a blockquoted excerpt, as well as content attribution, if any. |
||
1103 | * |
||
1104 | * @since 4.2.0 |
||
1105 | * @access public |
||
1106 | * |
||
1107 | * @param array $data The site's data. |
||
1108 | * @return string Discovered content, or empty |
||
1109 | */ |
||
1110 | public function get_suggested_content( $data ) { |
||
1185 | |||
1186 | /** |
||
1187 | * Serves the app's base HTML, which in turns calls the load script. |
||
1188 | * |
||
1189 | * @since 4.2.0 |
||
1190 | * @access public |
||
1191 | * |
||
1192 | * @global WP_Locale $wp_locale |
||
1193 | * @global string $wp_version |
||
1194 | * @global bool $is_IE |
||
1195 | */ |
||
1196 | public function html() { |
||
1519 | } |
||
1520 | |||
1526 |
If you define a variable conditionally, it can happen that it is not defined for all execution paths.
Let’s take a look at an example:
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.
Available Fixes
Check for existence of the variable explicitly:
Define a default value for the variable:
Add a value for the missing path: