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: