Make WordPress Core


Ignore:
Timestamp:
03/09/2015 09:48:38 PM (12 years ago)
Author:
azaozz
Message:

PressThis:

  • Filter and select the content on the PHP side. Then pass only the needed data to JS.
  • Add the suggested post title and contend directly to the HTML.
  • Standardise the data type names.
  • Some cleanup/reduction of the code in the bookmarklet.

See #31373.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/includes/class-wp-press-this.php

    r31655 r31693  
    1515class WP_Press_This {
    1616
     17        private $images = array();
     18
     19        private $embeds = array();
     20
    1721        /**
    1822         * Constructor.
    … …  
    3236         */
    3337        public function site_settings() {
    34                 $default_html = array(
    35                         'quote' => '<blockquote>%1$s</blockquote>',
    36                         'link' => '<p>' . _x( 'Source:', 'Used in Press This to indicate where the content comes from.' ) .
    37                                 ' <em><a href="%1$s">%2$s</a></em></p>',
    38                 );
    39 
    4038                return array(
    4139                        // Used to trigger the bookmarklet update notice.
    4240                        // Needs to be set here and in get_shortcut_link() in wp-includes/link-template.php.
    43                         'version' => '6',
     41                        'version' => '7',
    4442
    4543                        /**
    … …  
    5149                         */
    5250                        'redirInParent' => apply_filters( 'press_this_redirect_in_parent', false ),
    53 
    54                         /**
    55                          * Filter the default HTML for the Press This editor.
    56                          *
    57                          * @since 4.2.0
    58                          *
    59                          * @param array $default_html Associative array with two keys: 'quote' where %1$s is replaced with the site description
    60                          *                            or the selected content, and 'link' there %1$s is link href, %2$s is link text.
    61                          */
    62                         'html' => apply_filters( 'press_this_suggested_html', $default_html ),
    6351                );
    6452        }
    … …  
    436424
    437425        private function _process_meta_entry( $meta_name, $meta_value, $data ) {
    438                 if ( preg_match( '/:?(title|description|keywords)$/', $meta_name ) ) {
     426                if ( preg_match( '/:?(title|description|keywords|site_name)$/', $meta_name ) ) {
    439427                        $data['_meta'][ $meta_name ] = $meta_value;
    440428                } else {
    … …  
    445433                                        $meta_value = $this->_limit_embed( $meta_value );
    446434
    447                                         if ( ! isset( $data['_embed'] ) ) {
    448                                                 $data['_embed'] = array();
     435                                        if ( ! isset( $data['_embeds'] ) ) {
     436                                                $data['_embeds'] = array();
    449437                                        }
    450438
    451                                         if ( ! empty( $meta_value ) && ! in_array( $meta_value, $data['_embed'] ) ) {
    452                                                 $data['_embed'][] = $meta_value;
     439                                        if ( ! empty( $meta_value ) && ! in_array( $meta_value, $data['_embeds'] ) ) {
     440                                                $data['_embeds'][] = $meta_value;
    453441                                        }
    454442
    … …  
    462450                                        $meta_value = $this->_limit_img( $meta_value );
    463451
    464                                         if ( ! isset( $data['_img'] ) ) {
    465                                                 $data['_img'] = array();
     452                                        if ( ! isset( $data['_images'] ) ) {
     453                                                $data['_images'] = array();
    466454                                        }
    467455
    468                                         if ( ! empty( $meta_value ) && ! in_array( $meta_value, $data['_img'] ) ) {
    469                                                 $data['_img'][] = $meta_value;
     456                                        if ( ! empty( $meta_value ) && ! in_array( $meta_value, $data['_images'] ) ) {
     457                                                $data['_images'][] = $meta_value;
    470458                                        }
    471459
    … …  
    478466
    479467        /**
    480          * Fetches and parses _meta, _img, and _links data from the source.
     468         * Fetches and parses _meta, _images, and _links data from the source.
    481469         *
    482470         * @since 4.2.0
    … …  
    522510
    523511                // Fetch and gather <img> data.
    524                 if ( empty( $data['_img'] ) ) {
    525                         $data['_img'] = array();
     512                if ( empty( $data['_images'] ) ) {
     513                        $data['_images'] = array();
    526514                }
    527515
    … …  
    538526                                if ( preg_match( '/src=(\'|")([^\'"]+)\\1/i', $value, $new_matches ) ) {
    539527                                        $src = $this->_limit_img( $new_matches[2] );
    540                                         if ( ! empty( $src ) && ! in_array( $src, $data['_img'] ) ) {
    541                                                 $data['_img'][] = $src;
     528                                        if ( ! empty( $src ) && ! in_array( $src, $data['_images'] ) ) {
     529                                                $data['_images'][] = $src;
    542530                                        }
    543531                                }
    … …  
    546534
    547535                // Fetch and gather <iframe> data.
    548                 if ( empty( $data['_embed'] ) ) {
    549                         $data['_embed'] = array();
     536                if ( empty( $data['_embeds'] ) ) {
     537                        $data['_embeds'] = array();
    550538                }
    551539
    … …  
    557545                                        $src = $this->_limit_embed( $new_matches[2] );
    558546
    559                                         if ( ! empty( $src ) && ! in_array( $src, $data['_embed'] ) ) {
    560                                                 $data['_embed'][] = $src;
     547                                        if ( ! empty( $src ) && ! in_array( $src, $data['_embeds'] ) ) {
     548                                                $data['_embeds'][] = $src;
    561549                                        }
    562550                                }
    … …  
    573561
    574562                        foreach ( $items as $value ) {
    575                                 if ( preg_match( '/(rel|itemprop)="([^"]+)"[^>]+href="([^"]+)"/', $value, $new_matches ) ) {
    576                                         if ( 'alternate' === $new_matches[2] || 'thumbnailUrl' === $new_matches[2] || 'url' === $new_matches[2] ) {
    577                                                 $url = $this->_limit_url( $new_matches[3] );
    578 
    579                                                 if ( ! empty( $url ) && empty( $data['_links'][ $new_matches[2] ] ) ) {
    580                                                         $data['_links'][ $new_matches[2] ] = $url;
    581                                                 }
     563                                if ( preg_match( '/rel=["\'](canonical|shortlink|icon)["\']/i', $value, $matches_rel ) && preg_match( '/href=[\'"]([^\'" ]+)[\'"]/i', $value, $matches_url ) ) {
     564                                        $rel = $matches_rel[1];
     565                                        $url = $this->_limit_url( $matches_url[1] );
     566
     567                                        if ( ! empty( $url ) && empty( $data['_links'][ $rel ] ) ) {
     568                                                $data['_links'][ $rel ] = $url;
    582569                                        }
    583570                                }
    … …  
    601588
    602589                // Only instantiate the keys we want. Sanity check and sanitize each one.
    603                 foreach ( array( 'u', 's', 't', 'v', '_version' ) as $key ) {
     590                foreach ( array( 'u', 's', 't', 'v' ) as $key ) {
    604591                        if ( ! empty( $_POST[ $key ] ) ) {
    605592                                $value = wp_unslash( $_POST[ $key ] );
    … …  
    630617                if ( apply_filters( 'enable_press_this_media_discovery', true ) ) {
    631618                        /*
    632                          * If no title, _img, _embed, and _meta was passed via $_POST, fetch data from source as fallback,
     619                         * If no title, _images, _embed, and _meta was passed via $_POST, fetch data from source as fallback,
    633620                         * making PT fully backward compatible with the older bookmarklet.
    634621                         */
    … …  
    636623                                $data = $this->source_data_fetch_fallback( $data['u'], $data );
    637624                        } else {
    638                                 foreach ( array( '_img', '_embed', '_meta' ) as $type ) {
     625                                foreach ( array( '_images', '_embeds' ) as $type ) {
    639626                                        if ( empty( $_POST[ $type ] ) ) {
    640627                                                continue;
    … …  
    643630                                        $data[ $type ] = array();
    644631                                        $items = $this->_limit_array( $_POST[ $type ] );
    645                                         $items = wp_unslash( $items );
    646632
    647633                                        foreach ( $items as $key => $value ) {
    648                                                 if ( ! is_numeric( $key ) ) {
    649                                                         $key = $this->_limit_string( wp_unslash( $key ) );
    650 
    651                                                         // Sanity check. $key is usually things like 'title', 'description', 'keywords', etc.
    652                                                         if ( empty( $key ) || strlen( $key ) > 100 ) {
    653                                                                 continue;
    654                                                         }
     634                                                if ( $type === '_images' ) {
     635                                                        $value = $this->_limit_img( wp_unslash( $value ) );
     636                                                } else {
     637                                                        $value = $this->_limit_embed( wp_unslash( $value ) );
    655638                                                }
    656639
     640                                                if ( ! empty( $value ) ) {
     641                                                        $data[ $type ][] = $value;
     642                                                }
     643                                        }
     644                                }
     645
     646                                foreach ( array( '_meta', '_links' ) as $type ) {
     647                                        if ( empty( $_POST[ $type ] ) ) {
     648                                                continue;
     649                                        }
     650
     651                                        $data[ $type ] = array();
     652                                        $items = $this->_limit_array( $_POST[ $type ] );
     653
     654                                        foreach ( $items as $key => $value ) {
     655                                                // Sanity check. These are associative arrays, $key is usually things like 'title', 'description', 'keywords', etc.
     656                                                if ( empty( $key ) || strlen( $key ) > 100 ) {
     657                                                        continue;
     658                                                }
     659
    657660                                                if ( $type === '_meta' ) {
    658                                                         $value = $this->_limit_string( $value );
     661                                                        $value = $this->_limit_string( wp_unslash( $value ) );
    659662
    660663                                                        if ( ! empty( $value ) ) {
    661664                                                                $data = $this->_process_meta_entry( $key, $value, $data );
    662665                                                        }
    663                                                 } else if ( $type === '_img' ) {
    664                                                         $value = $this->_limit_img( $value );
    665 
    666                                                         if ( ! empty( $value ) ) {
    667                                                                 $data[ $type ][] = $value;
    668                                                         }
    669                                                 } else if ( $type === '_embed' ) {
    670                                                         $value = $this->_limit_embed( $value );
    671 
    672                                                         if ( ! empty( $value ) ) {
    673                                                                 $data[ $type ][] = $value;
     666                                                } else {
     667                                                        if ( in_array( $key, array( 'canonical', 'shortlink', 'icon' ), true ) ) {
     668                                                                $data[ $type ][ $key ] = $this->_limit_url( wp_unslash( $value ) );
    674669                                                        }
    675670                                                }
    … …  
    750745                                                <?php
    751746                                         }
     747
    752748                                         ?>
    753749                                </fieldset>
    … …  
    852848
    853849        /**
     850         * Get a list of embeds with no duplicates.
     851         *
     852         * @param array $data The site's data.
     853         * @returns array
     854         */
     855        public function get_embeds( $data ) {
     856                $selected_embeds = array();
     857
     858                if ( ! empty( $data['_embeds'] ) ) {
     859                        foreach( $data['_embeds'] as $src ) {
     860                                $prot_relative_src = preg_replace( '/^https?:/', '', $src );
     861
     862                                if ( in_array( $prot_relative_src, $this->embeds ) ) {
     863                                        continue;
     864                                }
     865
     866                                $selected_embeds[] = $src;
     867                                $this->embeds[] = $prot_relative_src;
     868                        }
     869                }
     870
     871                return $selected_embeds;
     872        }
     873
     874        /**
     875         * Get a list of images with no duplicates.
     876         *
     877         * @param array $data The site's data.
     878         * @returns array
     879         */
     880        public function get_images( $data ) {
     881                $selected_images = array();
     882
     883                if ( ! empty( $data['_images'] ) ) {
     884                        foreach( $data['_images'] as $src ) {
     885                                if ( false !== strpos( $src, 'gravatar.com' ) ) {
     886                                        $src = preg_replace( '%http://[\d]+\.gravatar\.com/%', 'https://secure.gravatar.com/', $src );
     887                                }
     888
     889                                $prot_relative_src = preg_replace( '/^https?:/', '', $src );
     890
     891                                if ( in_array( $prot_relative_src, $this->images ) ||
     892                                        ( false !== strpos( $src, 'avatar' ) && count( $this->images ) > 15 ) ) {
     893                                        // Skip: already selected or some type of avatar and we've already gathered more than 15 images.
     894                                        continue;
     895                                }
     896
     897                                $selected_images[] = $src;
     898                                $this->images[] = $prot_relative_src;
     899                        }
     900                }
     901
     902                return $selected_images;
     903        }
     904
     905        /**
     906         * Gets the source page's canonical link, based on passed location and meta data.
     907         *
     908         * @param array $data The site's data.
     909         * @returns string Discovered canonical URL, or empty
     910         */
     911        public function get_canonical_link( $data ) {
     912                $link = '';
     913
     914                if ( ! empty( $data['_links']['canonical'] ) ) {
     915                        $link = $data['_links']['canonical'];
     916                } elseif ( ! empty( $data['u'] ) ) {
     917                        $link = $data['u'];
     918                } elseif ( ! empty( $data['_meta'] ) ) {
     919                        if ( ! empty( $data['_meta']['twitter:url'] ) ) {
     920                                $link = $data['_meta']['twitter:url'];
     921                        } else if ( ! empty( $data['_meta']['og:url'] ) ) {
     922                                $link = $data['_meta']['og:url'];
     923                        }
     924                }
     925
     926                if ( empty( $link ) && ! empty( $data['_links']['shortlink'] ) ) {
     927                        $link = $data['_links']['shortlink'];
     928                }
     929
     930                return $link;
     931        }
     932
     933        /**
     934         * Gets the source page's site name, based on passed meta data.
     935         *
     936         * @param array $data The site's data.
     937         * @returns string Discovered site name, or empty
     938         */
     939        public function get_source_site_name( $data ) {
     940                $name = '';
     941
     942                if ( ! empty( $data['_meta'] ) ) {
     943                        if ( ! empty( $data['_meta']['og:site_name'] ) ) {
     944                                $name = $data['_meta']['og:site_name'];
     945                        } else if ( ! empty( $data['_meta']['application-name'] ) ) {
     946                                $name = $data['_meta']['application-name'];
     947                        }
     948                }
     949
     950                return $name;
     951        }
     952
     953        /**
     954         * Gets the source page's title, based on passed title and meta data.
     955         *
     956         * @param array $data The site's data.
     957         * @returns string Discovered page title, or empty
     958         */
     959        public function get_suggested_title( $data ) {
     960                $title = '';
     961
     962                if ( ! empty( $data['t'] ) ) {
     963                        $title = $data['t'];
     964                } elseif( ! empty( $data['_meta'] ) ) {
     965                        if ( ! empty( $data['_meta']['twitter:title'] ) ) {
     966                                $title = $data['_meta']['twitter:title'];
     967                        } else if ( ! empty( $data['_meta']['og:title'] ) ) {
     968                                $title = $data['_meta']['og:title'];
     969                        } else if ( ! empty( $data['_meta']['title'] ) ) {
     970                                $title = $data['_meta']['title'];
     971                        }
     972                }
     973
     974                return $title;
     975        }
     976
     977        /**
     978         * Gets the source page's suggested content, based on passed data (description, selection, etc).
     979         * Features a blockquoted excerpt, as well as content attribution, if any.
     980         *
     981         * @param array $data The site's data.
     982         * @returns string Discovered content, or empty
     983         */
     984        public function get_suggested_content( $data ) {
     985                $content = $text = '';
     986
     987                if ( ! empty( $data['s'] ) ) {
     988                        $text = $data['s'];
     989                } else if ( ! empty( $data['_meta'] ) ) {
     990                        if ( ! empty( $data['_meta']['twitter:description'] ) ) {
     991                                $text = $data['_meta']['twitter:description'];
     992                        } else if ( ! empty( $data['_meta']['og:description'] ) ) {
     993                                $text = $data['_meta']['og:description'];
     994                        } else if ( ! empty( $data['_meta']['description'] ) ) {
     995                                $text = $data['_meta']['description'];
     996                        }
     997                }
     998
     999                $default_html = array(
     1000                        'quote' => '<blockquote>%1$s</blockquote>',
     1001                        'link' => '<p>' . _x( 'Source:', 'Used in Press This to indicate where the content comes from.' ) .
     1002                                ' <em><a href="%1$s">%2$s</a></em></p>',
     1003                );
     1004
     1005                /**
     1006                 * Filter the default HTML for the Press This editor.
     1007                 *
     1008                 * @since 4.2.0
     1009                 *
     1010                 * @param array $default_html Associative array with two keys: 'quote' where %1$s is replaced with the site description
     1011                 *                            or the selected content, and 'link' there %1$s is link href, %2$s is link text.
     1012                 */
     1013                $default_html = apply_filters( 'press_this_suggested_html', $default_html, $data );
     1014
     1015                // Wrap suggested content in the specified HTML.
     1016                if ( ! empty( $default_html['quote'] ) ) {
     1017                        $content = sprintf( $default_html['quote'], $text );
     1018                }
     1019
     1020                // Add source attribution if there is one available.
     1021                if ( ! empty( $default_html['link'] ) ) {
     1022                        $title = $this->get_suggested_title( $data );
     1023                        $url = $this->get_canonical_link( $data );
     1024
     1025                        if ( ! $title ) {
     1026                                $title = $this->get_source_site_name( $data );
     1027                        }
     1028
     1029                        if ( $url && $title ) {
     1030                                $content .= sprintf( $default_html['link'], $url, $title );
     1031                        }
     1032                }
     1033
     1034                return $content;
     1035        }
     1036
     1037        /**
    8541038         * Serves the app's base HTML, which in turns calls the load script.
    8551039         *
    … …  
    8631047                $data = $this->merge_or_fetch_data();
    8641048
     1049                $post_title = $this->get_suggested_title( $data );
     1050
     1051                if ( empty( $title ) ) {
     1052                        $title = __( 'New Post' );
     1053                }
     1054
     1055                $post_content = $this->get_suggested_content( $data );
     1056
    8651057                // Get site settings array/data.
    8661058                $site_settings = $this->site_settings();
    8671059
    868                 // Set the passed data.
    869                 $data['_version'] = $site_settings['version'];
     1060                // Pass the images and embeds
     1061                $images = $this->get_images( $data );
     1062                $embeds = $this->get_embeds( $data );
     1063
     1064                $site_data = array(
     1065                        'v' => ! empty( $data['v'] ) ? $data['v'] : '',
     1066                        'hasData' => ! empty( $data ),
     1067                );
     1068
     1069                if ( ! empty( $images ) ) {
     1070                        $site_data['_images'] = $images;
     1071                }
     1072
     1073                if ( ! empty( $embeds ) ) {
     1074                        $site_data['_embeds'] = $embeds;
     1075                }
    8701076
    8711077                // Add press-this-editor.css and remove theme's editor-style.css, if any.
    … …  
    8911097
    8921098        <script>
    893                 window.wpPressThisData   = <?php echo wp_json_encode( $data ) ?>;
    894                 window.wpPressThisConfig = <?php echo wp_json_encode( $site_settings ) ?>;
     1099                window.wpPressThisData   = <?php echo wp_json_encode( $site_data ); ?>;
     1100                window.wpPressThisConfig = <?php echo wp_json_encode( $site_settings ); ?>;
    8951101        </script>
    8961102
    … …  
    9601166        $admin_body_class .= ' admin-color-' . sanitize_html_class( get_user_option( 'admin_color' ), 'fresh' );
    9611167        $admin_body_class .= ' locale-' . sanitize_html_class( strtolower( str_replace( '_', '-', get_locale() ) ) );
    962        
     1168
    9631169        /** This filter is documented in wp-admin/admin-header.php */
    9641170        $admin_body_classes = apply_filters( 'admin_body_class', '' );
    … …  
    10081214                        <div id='app-container' class="editor">
    10091215                                <span id="title-container-label" class="post-title-placeholder" aria-hidden="true"><?php _e( 'Post title' ); ?></span>
    1010                                 <h2 id="title-container" class="post-title" contenteditable="true" spellcheck="true" aria-label="<?php esc_attr_e( 'Post title' ); ?>" tabindex="0"></h2>
     1216                                <h2 id="title-container" class="post-title" contenteditable="true" spellcheck="true" aria-label="<?php esc_attr_e( 'Post title' ); ?>" tabindex="0"><?php echo esc_html( $post_title ); ?></h2>
    10111217                                <div id='featured-media-container' class="featured-container no-media">
    10121218                                        <div id='all-media-widget' class="all-media">
    … …  
    10161222
    10171223                                <?php
    1018                                 wp_editor( '', 'pressthis', array(
     1224                                wp_editor( $post_content, 'pressthis', array(
    10191225                                        'drag_drop_upload' => true,
    10201226                                        'editor_height'    => 600,
    … …  
    10401246                </div>
    10411247
    1042                 <div class="options-panel-back is-hidden" tabindex="-1"></div> 
     1248                <div class="options-panel-back is-hidden" tabindex="-1"></div>
    10431249                <div class="options-panel is-off-screen is-hidden" tabindex="-1">
    10441250                        <div class="post-options">
Note: See TracChangeset for help on using the changeset viewer.