Make WordPress Core

Ticket #32653: 34141.4.diff

File 34141.4.diff, 7.9 KB (added by dshanske, 9 years ago)

Based on the code written for #34141, this goes a bit farther.

  • class-wp-xmlrpc-server.php

     
    61156115                if ( !$pos1 )
    61166116                        return $this->pingback_error( 0, __( 'Is there no link to us?' ) );
    61176117
    6118                 // let's find which post is linked to
    6119                 // FIXME: does url_to_postid() cover all these cases already?
    6120                 //        if so, then let's use it and drop the old code.
    6121                 $urltest = parse_url($pagelinkedto);
    6122                 if ( $post_ID = url_to_postid($pagelinkedto) ) {
    6123                         // $way
    6124                 } elseif ( isset( $urltest['path'] ) && preg_match('#p/[0-9]{1,}#', $urltest['path'], $match) ) {
    6125                         // the path defines the post_ID (archives/p/XXXX)
    6126                         $blah = explode('/', $match[0]);
    6127                         $post_ID = (int) $blah[1];
    6128                 } elseif ( isset( $urltest['query'] ) && preg_match('#p=[0-9]{1,}#', $urltest['query'], $match) ) {
    6129                         // the querystring defines the post_ID (?p=XXXX)
    6130                         $blah = explode('=', $match[0]);
    6131                         $post_ID = (int) $blah[1];
    6132                 } elseif ( isset($urltest['fragment']) ) {
    6133                         // an #anchor is there, it's either...
    6134                         if ( intval($urltest['fragment']) ) {
    6135                                 // ...an integer #XXXX (simplest case)
    6136                                 $post_ID = (int) $urltest['fragment'];
    6137                         } elseif ( preg_match('/post-[0-9]+/',$urltest['fragment']) ) {
    6138                                 // ...a post id in the form 'post-###'
    6139                                 $post_ID = preg_replace('/[^0-9]+/', '', $urltest['fragment']);
    6140                         } elseif ( is_string($urltest['fragment']) ) {
    6141                                 // ...or a string #title, a little more complicated
    6142                                 $title = preg_replace('/[^a-z0-9]/i', '.', $urltest['fragment']);
    6143                                 $sql = $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_title RLIKE %s", $title );
    6144                                 if (! ($post_ID = $wpdb->get_var($sql)) ) {
    6145                                         // returning unknown error '0' is better than die()ing
    6146                                         return $this->pingback_error( 0, '' );
    6147                                 }
    6148                         }
    6149                 } else {
    6150                         // TODO: Attempt to extract a post ID from the given URL
    6151                         return $this->pingback_error( 33, __('The specified target URL cannot be used as a target. It either doesn’t exist, or it is not a pingback-enabled resource.' ) );
    6152                 }
    6153                 $post_ID = (int) $post_ID;
     6118                // let's find which post is linked to.
     6119                $post_ID = url_to_postid($pagelinkedto);
    61546120
     6121                $post_ID = intval( $post_ID );
    61556122                $post = get_post($post_ID);
    61566123
    61576124                if ( !$post ) // Post_ID not found
     
    62016168                 * @param string $pagelinkedto URL of the page linked to.
    62026169                 */
    62036170                $linea = apply_filters( 'pre_remote_source', $linea, $pagelinkedto );
     6171    /**
     6172     * Filter the pingback remote source through kses.
     6173     *
     6174     * @since
     6175     *
     6176     * @param array $allowed_tags Tags permitted through the filter, defaults to wp_kses_post.
     6177     * @param string $pagelinkedto URL of the page linked to.
     6178     */
    62046179
    6205                 // Work around bug in strip_tags():
    6206                 $linea = str_replace('<!DOC', '<DOC', $linea);
    6207                 $linea = preg_replace( '/[\r\n\t ]+/', ' ', $linea ); // normalize spaces
    6208                 $linea = preg_replace( "/<\/*(h1|h2|h3|h4|h5|h6|p|th|td|li|dt|dd|pre|caption|input|textarea|button|body)[^>]*>/", "\n\n", $linea );
     6180                $allowed_tags = apply_filters( 'filter_pingback_source', wp_kses_allowed_html( 'post' );
     6181                $linea = wp_kses( $linea, $allowed_tags );
    62096182
    6210                 preg_match('|<title>([^<]*?)</title>|is', $linea, $matchtitle);
    6211                 $title = $matchtitle[1];
    6212                 if ( empty( $title ) )
    6213                         return $this->pingback_error( 32, __('We cannot find a title on that page.' ) );
     6183                // check if source really links to target
     6184                if ( ! strpos( $linea, str_replace( array( 'http://www.', 'http://', 'https://www.', 'https://' ), '', untrailingslashit( preg_replace( '/#.*/', '', $pagelinkedto ) ) ) ) ) {
     6185                        return $this->pingback_error( 17, __( 'The source URL does not contain a link to the target URL, and so cannot be used as a source.' ) );
     6186                }
    62146187
    6215                 $linea = strip_tags( $linea, '<a>' ); // just keep the tag we need
     6188                $host = parse_url( $source, PHP_URL_HOST );
     6189                // strip leading www, if any
     6190                $host = preg_replace( '/^www\./', '', $host );
    62166191
    6217                 $p = explode( "\n\n", $linea );
    6218 
    6219                 $preg_target = preg_quote($pagelinkedto, '|');
    6220 
    6221                 foreach ( $p as $para ) {
    6222                         if ( strpos($para, $pagelinkedto) !== false ) { // it exists, but is it a link?
    6223                                 preg_match("|<a[^>]+?".$preg_target."[^>]*>([^>]+?)</a>|", $para, $context);
    6224 
    6225                                 // If the URL isn't in a link context, keep looking
    6226                                 if ( empty($context) )
    6227                                         continue;
    6228 
    6229                                 // We're going to use this fake tag to mark the context in a bit
    6230                                 // the marker is needed in case the link text appears more than once in the paragraph
    6231                                 $excerpt = preg_replace('|\</?wpcontext\>|', '', $para);
    6232 
    6233                                 // prevent really long link text
    6234                                 if ( strlen($context[1]) > 100 )
    6235                                         $context[1] = substr($context[1], 0, 100) . '&#8230;';
    6236 
    6237                                 $marker = '<wpcontext>'.$context[1].'</wpcontext>';    // set up our marker
    6238                                 $excerpt= str_replace($context[0], $marker, $excerpt); // swap out the link for our marker
    6239                                 $excerpt = strip_tags($excerpt, '<wpcontext>');        // strip all tags but our context marker
    6240                                 $excerpt = trim($excerpt);
    6241                                 $preg_marker = preg_quote($marker, '|');
    6242                                 $excerpt = preg_replace("|.*?\s(.{0,100}$preg_marker.{0,100})\s.*|s", '$1', $excerpt);
    6243                                 $excerpt = strip_tags($excerpt); // YES, again, to remove the marker wrapper
    6244                                 break;
    6245                         }
     6192                $meta_tags = @get_meta_tags( $source );
     6193                // use meta-author
     6194                if ( $meta_tags && is_array( $meta_tags ) && array_key_exists( 'author', $meta_tags ) ) {
     6195                        $title = $meta_tags['author'];
     6196                } elseif ( preg_match( '/<title>(.+)<\/title>/i', $contents, $match ) ) { // use title
     6197                        $title = trim( $match[1] );
     6198                } else { // or host
     6199                        // strip leading www, if any
     6200                        $title = $host;
    62466201                }
    62476202
    6248                 if ( empty($context) ) // Link to target not found
    6249                         return $this->pingback_error( 17, __( 'The source URL does not contain a link to the target URL, and so cannot be used as a source.' ) );
    6250 
    62516203                $pagelinkedfrom = str_replace('&', '&amp;', $pagelinkedfrom);
    6252 
    6253                 $context = '[&#8230;] ' . esc_html( $excerpt ) . ' [&#8230;]';
    62546204                $pagelinkedfrom = $this->escape( $pagelinkedfrom );
    62556205
     6206                // generate default text
     6207                $context = sprintf( __( 'This post was mentioned on <a href="%s">%s</a>' ), esc_url( $pagelinkedfrom ), $host );
     6208
    62566209                $comment_post_ID = (int) $post_ID;
    62576210                $comment_author = $title;
    62586211                $comment_author_email = '';
    62596212                $this->escape($comment_author);
    62606213                $comment_author_url = $pagelinkedfrom;
     6214       
    62616215                $comment_content = $context;
    62626216                $this->escape($comment_content);
    62636217                $comment_type = 'pingback';
    62646218
    6265                 $commentdata = compact('comment_post_ID', 'comment_author', 'comment_author_url', 'comment_author_email', 'comment_content', 'comment_type');
    6266 
     6219                $commentdata = compact('comment_post_ID', 'comment_author', 'comment_author_url', 'comment_author_email', 'comment_content', 'comment_type', 'linea' );
    62676220                $comment_ID = wp_new_comment($commentdata);
    62686221
    62696222                /**
  • comment-functions.php

     
    14291429         * @param WP_Comment $comment Comment object.
    14301430         */
    14311431        do_action( 'wp_insert_comment', $id, $comment );
     1432       
     1433        // If there is something extra in $commentdata save it as meta.
     1434        $commentmeta = array_diff( $commentdata, $compacted );
     1435        foreach ( $commentmeta as $key => $value ) {
     1436                update_comment_meta( $id, $key, $value, true );
     1437        }
    14321438
    14331439        wp_cache_set( 'last_changed', microtime(), 'comment' );
    14341440
     
    15741580         * @param array $commentdata Comment data.
    15751581         */
    15761582        $commentdata = apply_filters( 'preprocess_comment', $commentdata );
    1577 
     1583        // Unset linea from a pingback after it is made available to preprocessing the pingback.
     1584        if ( isset( $commentdata['linea' ) ) {
     1585                unset( $commentdata['linea'] );
     1586        }
    15781587        $commentdata['comment_post_ID'] = (int) $commentdata['comment_post_ID'];
    15791588        if ( isset( $commentdata['user_ID'] ) && $prefiltered_user_id !== (int) $commentdata['user_ID'] ) {
    15801589                $commentdata['user_id'] = $commentdata['user_ID'] = (int) $commentdata['user_ID'];