Make WordPress Core

Ticket #26530: fix_do_enclose.diff

File fix_do_enclose.diff, 5.5 KB (added by joakimf, 11 years ago)

Suggested patch for problems described in ticket

  • src/wp-includes/functions.php

     
    450450function do_enclose( $content, $post_ID ) {
    451451        global $wpdb;
    452452
    453         //TODO: Tidy this ghetto code up and make the debug code optional
    454453        include_once( ABSPATH . WPINC . '/class-IXR.php' );
    455454
    456         $post_links = array();
     455        $post_enclosed_links = get_enclosed( $post_ID );
     456        $content_links_all = (array) wp_extract_urls( $content );
    457457
    458         $pung = get_enclosed( $post_ID );
    459 
    460         $post_links_temp = wp_extract_urls( $content );
    461 
    462         foreach ( $pung as $link_test ) {
    463                 if ( ! in_array( $link_test, $post_links_temp ) ) { // link no longer in post
    464                         $mids = $wpdb->get_col( $wpdb->prepare("SELECT meta_id FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = 'enclosure' AND meta_value LIKE (%s)", $post_ID, like_escape( $link_test ) . '%') );
     458        // Remove metadata references for links no longer in post
     459        foreach ( $post_enclosed_links as $link ) {
     460                if ( ! in_array( $link, $content_links_all ) ) { // link no longer in post
     461                        // This isn't really optimal but until there's a better helper function to do this..
     462                        $mids = $wpdb->get_col( $wpdb->prepare("SELECT meta_id FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = 'enclosure' AND meta_value LIKE (%s)", $post_ID, like_escape( $link ) . '%') );
    465463                        foreach ( $mids as $mid )
    466464                                delete_metadata_by_mid( 'post', $mid );
    467465                }
    468466        }
    469 
    470         foreach ( (array) $post_links_temp as $link_test ) {
    471                 if ( !in_array( $link_test, $pung ) ) { // If we haven't pung it already
    472                         $test = @parse_url( $link_test );
    473                         if ( false === $test )
    474                                 continue;
    475                         if ( isset( $test['query'] ) )
    476                                 $post_links[] = $link_test;
    477                         elseif ( isset($test['path']) && ( $test['path'] != '/' ) &&  ($test['path'] != '' ) )
    478                                 $post_links[] = $link_test;
     467       
     468        // Adds post metadata for new links to content of certain types
     469        foreach ($content_links_all as $link ) {
     470                // Link not already referenced for metadata and is valid
     471                if ( !in_array( $link, $post_enclosed_links ) &&
     472                        url_valid_for_enclosure_addition( $link ) ) {
     473                                add_enclosure_if_multimedia_link( $link, $post_ID );
    479474                }
    480475        }
     476}
    481477
    482         foreach ( (array) $post_links as $url ) {
    483                 if ( $url != '' && !$wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = 'enclosure' AND meta_value LIKE (%s)", $post_ID, like_escape( $url ) . '%' ) ) ) {
     478/**
     479 * Is this URL syntatically valid and not pointing to site root?
     480 *
     481 * @since ?
     482 *
     483 * @param string $url
     484 * @return bool Is url valid?
     485 */
     486function url_valid_for_enclosure_addition( $url ) {
     487        $test = WP_DEBUG ? parse_url( $url ) : @parse_url( $url );
     488        if ( false === $test ) {
     489                return false;
     490        }
     491        // Valid link not pointing to site root?
     492        return ( isset( $test['query'] ) || ( isset($test['path']) && $test['path'] != '/' && $test['path'] != '' ) );
     493}
    484494
    485                         if ( $headers = wp_get_http_headers( $url) ) {
    486                                 $len = isset( $headers['content-length'] ) ? (int) $headers['content-length'] : 0;
    487                                 $type = isset( $headers['content-type'] ) ? $headers['content-type'] : '';
    488                                 $allowed_types = array( 'video', 'audio' );
     495/**
     496 * Adds metadata for post link if headers of url is of any of the specified types
     497 * If no headers are accessible, try guessing the mime type from the file extension and possibly add an enclosure.
     498 * @since ?
     499 *
     500 * @param string $url
     501 * @param int $post_ID Post ID
     502 */
     503function add_enclosure_if_multimedia_link( $url, $post_ID ){
     504        $allowed_types = array( 'video', 'audio' );
    489505
    490                                 // Check to see if we can figure out the mime type from
    491                                 // the extension
    492                                 $url_parts = @parse_url( $url );
    493                                 if ( false !== $url_parts ) {
    494                                         $extension = pathinfo( $url_parts['path'], PATHINFO_EXTENSION );
    495                                         if ( !empty( $extension ) ) {
    496                                                 foreach ( wp_get_mime_types() as $exts => $mime ) {
    497                                                         if ( preg_match( '!^(' . $exts . ')$!i', $extension ) ) {
    498                                                                 $type = $mime;
    499                                                                 break;
    500                                                         }
    501                                                 }
    502                                         }
    503                                 }
     506        $headers = wp_get_http_headers( $url);
     507        $length = isset( $headers['content-length'] ) ? (int) $headers['content-length'] : 0;
     508        if (isset( $headers['content-type'] ) ) {
     509                // Filters out charset declarations etc
     510                preg_match("/^([a-z0-9]*\/[a-z0-9]*)/", $headers['content-type'], $matches);
     511                // Just a safeguard. The longtext type in mysql 5 supports 4GiB of information
     512                $mime = substr($matches[1], 0, 256);
     513        }
     514        else {
     515                $mime = find_mime_type_from_extension($url);
     516                // Mime type not possible to ascertain
     517                if (false === $mime) {
     518                        return false;
     519                }
     520        }
    504521
    505                                 if ( in_array( substr( $type, 0, strpos( $type, "/" ) ), $allowed_types ) ) {
    506                                         add_post_meta( $post_ID, 'enclosure', "$url\n$len\n$mime\n" );
    507                                 }
    508                         }
     522        if ( in_array( substr( $mime, 0, strpos( $mime, "/" ) ), $allowed_types ) ) {
     523                add_post_meta( $post_ID, 'enclosure', "$url\n$length\n$mime\n" );
     524        }
     525}
     526
     527/**
     528 * Attempts to find the mime type for a link
     529 *
     530 * @since ?
     531 *
     532 * @param string $url
     533 * @return bool|string False on failure and mime type string if found
     534 */
     535function find_mime_type_from_extension( $url ){
     536        $url_parts = WP_DEBUG ? parse_url( $url ) : @parse_url( $url );
     537        if ( false === $url_parts ){
     538                return false;
     539        }
     540        $extension = pathinfo( $url_parts['path'], PATHINFO_EXTENSION );
     541        if ( empty( $extension ) ) {
     542                return false;
     543        }
     544        $all_mime_types = wp_get_mime_types();
     545        foreach ( $all_mime_types as $exts => $mime ) {
     546                if ( preg_match( '!^(' . $exts . ')$!i', $extension ) ) {
     547                        return $mime;
    509548                }
    510549        }
     550        return false;
    511551}
    512552
    513553/**