Changeset 24399
- Timestamp:
- 06/02/2013 04:26:10 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/wp-includes/post-formats.php
r24387 r24399 71 71 72 72 return wp_set_post_terms( $post->ID, $format, 'post_format' ); 73 }74 75 /**76 * Retrieve post format metadata for a post77 *78 * @since 3.6.079 *80 * @param int $post_id (optional) The post ID.81 * @return array The array of post format metadata.82 */83 function get_post_format_meta( $post_id = 0 ) {84 $meta = get_post_meta( $post_id );85 $keys = array( 'quote', 'quote_source_name', 'quote_source_url', 'link_url', 'gallery', 'audio_embed', 'video_embed', 'url', 'image' );86 87 if ( empty( $meta ) )88 return array_fill_keys( $keys, '' );89 90 $upgrade = array(91 '_wp_format_quote_source' => 'quote_source_name',92 '_wp_format_audio' => 'audio_embed',93 '_wp_format_video' => 'video_embed'94 );95 96 $format = get_post_format( $post_id );97 if ( ! empty( $format ) ) {98 switch ( $format ) {99 case 'link':100 $upgrade['_wp_format_url'] = 'link_url';101 break;102 case 'quote':103 $upgrade['_wp_format_url'] = 'quote_source_url';104 break;105 }106 }107 108 $upgrade_keys = array_keys( $upgrade );109 foreach ( $meta as $key => $values ) {110 if ( ! in_array( $key, $upgrade_keys ) )111 continue;112 update_post_meta( $post_id, '_format_' . $upgrade[$key], reset( $values ) );113 delete_post_meta( $post_id, $key );114 }115 116 $values = array();117 118 foreach ( $keys as $key ) {119 $value = get_post_meta( $post_id, '_format_' . $key, true );120 $values[$key] = empty( $value ) ? '' : $value;121 }122 123 return apply_filters( 'post_format_meta', $values );124 73 } 125 74 … … 287 236 288 237 /** 289 * Add chat detection support to the `get_content_chat()` chat parser.290 *291 * @since 3.6.0292 *293 * @global array $_wp_chat_parsers294 *295 * @param string $name Unique identifier for chat format. Example: IRC296 * @param string $newline_regex RegEx to match the start of a new line, typically when a new "username:" appears297 * The parser will handle up to 3 matched expressions298 * $matches[0] = the string before the user's message starts299 * $matches[1] = the time of the message, if present300 * $matches[2] = the author/username301 * OR302 * $matches[0] = the string before the user's message starts303 * $matches[1] = the author/username304 * @param string $delimiter_regex RegEx to determine where to split the username syntax from the chat message305 */306 function add_chat_detection_format( $name, $newline_regex, $delimiter_regex ) {307 global $_wp_chat_parsers;308 309 if ( empty( $_wp_chat_parsers ) )310 $_wp_chat_parsers = array();311 312 $_wp_chat_parsers = array( $name => array( $newline_regex, $delimiter_regex ) ) + $_wp_chat_parsers;313 }314 add_chat_detection_format( 'IM', '#^([^:]+):#', '#[:]#' );315 add_chat_detection_format( 'Skype', '#(\[.+?\])\s([^:]+):#', '#[:]#' );316 317 /**318 * Deliberately interpret passed content as a chat transcript that is optionally319 * followed by commentary320 *321 * If the content does not contain username syntax, assume that it does not contain322 * chat logs and return323 *324 * Example:325 *326 * One stanza of chat:327 * Scott: Hey, let's chat!328 * Helen: No.329 *330 * $stanzas = array(331 * array(332 * array(333 * 'time' => '',334 * 'author' => 'Scott',335 * 'messsage' => "Hey, let's chat!"336 * ),337 * array(338 * 'time' => '',339 * 'author' => 'Helen',340 * 'message' => 'No.'341 * )342 * )343 * )344 *345 * @since 3.6.0346 *347 * @param string $content A string which might contain chat data, passed by reference.348 * @param boolean $remove Whether to remove the found data from the passed content.349 * @return array A chat log as structured data350 */351 function get_content_chat( &$content, $remove = false ) {352 global $_wp_chat_parsers;353 354 $trimmed = strip_tags( trim( $content ) );355 if ( empty( $trimmed ) )356 return array();357 358 $matched_parser = false;359 foreach ( $_wp_chat_parsers as $parser ) {360 @list( $newline_regex, $delimiter_regex ) = $parser;361 if ( preg_match( $newline_regex, $trimmed ) ) {362 $matched_parser = $parser;363 break;364 }365 }366 367 if ( false === $matched_parser )368 return array();369 370 $last_index = 0;371 $stanzas = $data = $stanza = array();372 $author = $time = '';373 $lines = explode( "\n", make_clickable( $trimmed ) );374 $found = false;375 $found_index = 0;376 377 foreach ( $lines as $index => $line ) {378 if ( ! $found )379 $found_index = $index;380 381 $line = trim( $line );382 383 if ( empty( $line ) && $found ) {384 if ( ! empty( $author ) ) {385 $stanza[] = array(386 'time' => $time,387 'author' => $author,388 'message' => join( ' ', $data )389 );390 }391 392 $stanzas[] = $stanza;393 394 $stanza = $data = array();395 $author = $time = '';396 if ( ! empty( $lines[$index + 1] ) && ! preg_match( $delimiter_regex, $lines[$index + 1] ) )397 break;398 else399 continue;400 }401 402 $matched = preg_match( $newline_regex, $line, $matches );403 if ( ! $matched )404 continue;405 406 $found = true;407 $last_index = $index;408 $author_match = empty( $matches[2] ) ? $matches[1] : $matches[2];409 // assume username syntax if no whitespace is present410 $no_ws = $matched && ! preg_match( '#[\r\n\t ]#', $author_match );411 // allow script-like stanzas412 $has_ws = $matched && preg_match( '#[\r\n\t ]#', $author_match ) && empty( $lines[$index + 1] ) && empty( $lines[$index - 1] );413 if ( $matched && ( ! empty( $matches[2] ) || ( $no_ws || $has_ws ) ) ) {414 if ( ! empty( $author ) ) {415 $stanza[] = array(416 'time' => $time,417 'author' => $author,418 'message' => join( ' ', $data )419 );420 $data = array();421 }422 423 $time = empty( $matches[2] ) ? '' : $matches[1];424 $author = $author_match;425 $data[] = trim( str_replace( $matches[0], '', $line ) );426 } elseif ( preg_match( '#\S#', $line ) ) {427 $data[] = $line;428 }429 }430 431 if ( ! empty( $author ) ) {432 $stanza[] = array(433 'time' => $time,434 'author' => $author,435 'message' => trim( join( ' ', $data ) )436 );437 }438 439 if ( ! empty( $stanza ) )440 $stanzas[] = $stanza;441 442 if ( $remove ) {443 if ( 0 === $found_index ) {444 $removed = array_slice( $lines, $last_index );445 } else {446 $before = array_slice( $lines, 0, $found_index );447 $after = array_slice( $lines, $last_index + 1 );448 $removed = array_filter( array_merge( $before, $after ) );449 }450 $content = trim( join( "\n", $removed ) );451 }452 453 return $stanzas;454 }455 456 /**457 * Retrieve structured chat data from the current or passed post458 *459 * @since 3.6.0460 *461 * @param int $post_id (optional) The post ID.462 * @return array The chat content.463 */464 function get_the_post_format_chat( $post_id = 0 ) {465 if ( ! $post = get_post( $post_id ) )466 return array();467 468 $data = get_content_chat( get_paged_content( $post->post_content ) );469 if ( empty( $data ) )470 return array();471 472 return $data;473 }474 475 /**476 * Output HTML for a given chat's structured data. Themes can use this as a477 * template tag in place of the_content() for Chat post format templates.478 *479 * @since 3.6.0480 *481 * @uses get_the_post_format_chat()482 *483 * @print HTML484 */485 function the_post_format_chat() {486 $output = '<dl class="chat">';487 $stanzas = get_the_post_format_chat();488 489 foreach ( $stanzas as $stanza ) {490 foreach ( $stanza as $row ) {491 $time = '';492 if ( ! empty( $row['time'] ) )493 $time = sprintf( '<time class="chat-timestamp">%s</time>', esc_html( $row['time'] ) );494 495 $output .= sprintf(496 '<dt class="chat-author chat-author-%1$s vcard">%2$s <cite class="fn">%3$s</cite>: </dt>497 <dd class="chat-text">%4$s</dd>498 ',499 esc_attr( sanitize_title_with_dashes( $row['author'] ) ), // Slug.500 $time,501 esc_html( $row['author'] ),502 $row['message']503 );504 }505 }506 507 $output .= '</dl><!-- .chat -->';508 509 echo $output;510 }511 512 /**513 * Get the first <blockquote> from the $content string passed by reference.514 *515 * If $content does not have a blockquote, assume the whole string516 * is the quote.517 *518 * @since 3.6.0519 *520 * @param string $content A string which might contain chat data, passed by reference.521 * @param bool $remove (optional) Whether to remove the quote from the content.522 * @param string $replace (optional) Content to replace the quote content with.523 * @return string The quote content.524 */525 function get_content_quote( &$content, $remove = false, $replace = '' ) {526 if ( empty( $content ) )527 return '';528 529 if ( ! preg_match( '/<blockquote[^>]*>(.+?)<\/blockquote>/is', $content, $matches ) ) {530 $quote = $content;531 if ( $remove || ! empty( $replace ) )532 $content = $replace;533 return $quote;534 }535 536 if ( $remove || ! empty( $replace ) )537 $content = preg_replace( '/<blockquote[^>]*>(.+?)<\/blockquote>/is', addcslashes( $replace, '\\$' ), $content, 1 );538 539 return $matches[1];540 }541 542 /**543 * Get a quote from the post content and set split_content for future use.544 *545 * @since 3.6.0546 *547 * @uses get_content_quote()548 * @uses apply_filters() Calls 'quote_source_format' filter to allow changing the typographical mark added to the quote source (em-dash prefix, by default)549 *550 * @param object $post (optional) A reference to the post object, falls back to get_post().551 * @return string The quote html.552 */553 function get_the_post_format_quote( &$post = null ) {554 if ( empty( $post ) )555 $post = get_post();556 557 if ( empty( $post ) )558 return '';559 560 $content = $post->post_content;561 $quote = get_content_quote( $content, true );562 $post->split_content = $content;563 564 if ( ! empty( $quote ) )565 $quote = sprintf( '<blockquote>%s</blockquote>', wpautop( $quote ) );566 567 $meta = get_post_format_meta( $post->ID );568 569 if ( ! empty( $meta['quote_source_name'] ) ) {570 $source = ( empty( $meta['quote_source_url'] ) ) ? $meta['quote_source_name'] : sprintf( '<a href="%s">%s</a>', esc_url( $meta['quote_source_url'] ), $meta['quote_source_name'] );571 $source = sprintf( apply_filters( 'quote_source_format', __( '— %s' ) ), $source );572 $quote .= sprintf( '<figcaption class="quote-caption">%s</figcaption>', $source );573 }574 575 if ( ! empty( $quote ) )576 $quote = sprintf( '<figure class="quote">%s</figure>', $quote );577 578 return $quote;579 }580 581 /**582 * Outputs the post format quote.583 *584 * @since 3.6.0585 */586 function the_post_format_quote() {587 echo get_the_post_format_quote();588 }589 590 /**591 238 * Extract a URL from passed content, if possible 592 239 * Checks for a URL on the first line of the content or the first encountered href attribute. … … 629 276 630 277 /** 631 * Attempt to retrieve a URL from a post's content632 *633 * @since 3.6.0634 *635 * @param int $post_id (optional) The post ID.636 * @return string A URL, if found.637 */638 function get_the_post_format_url( $post_id = 0 ) {639 if ( ! $post = get_post( $post_id ) )640 return '';641 642 $format = get_post_format( $post->ID );643 if ( in_array( $format, array( 'image', 'link', 'quote' ) ) ) {644 $meta = get_post_format_meta( $post->ID );645 $meta_link = '';646 647 switch ( $format ) {648 case 'link':649 if ( ! empty( $meta['link_url'] ) )650 $meta_link = $meta['link_url'];651 break;652 case 'image':653 if ( ! empty( $meta['url'] ) )654 $meta_link = $meta['url'];655 break;656 case 'quote':657 if ( ! empty( $meta['quote_source_url'] ) )658 $meta_link = $meta['quote_source_url'];659 break;660 }661 662 if ( ! empty( $meta_link ) )663 return apply_filters( 'get_the_post_format_url', esc_url_raw( $meta_link ), $post );664 }665 666 if ( ! empty( $post->post_content ) )667 return apply_filters( 'get_the_post_format_url', get_content_url( $post->post_content ), $post );668 }669 670 /**671 * Attempt to output a URL from a post's content672 *673 * @since 3.6.0674 *.675 */676 function the_post_format_url() {677 echo esc_url( get_the_post_format_url() );678 }679 680 /**681 * Retrieve the post content, minus the extracted post format content682 *683 * @since 3.6.0684 *685 * @internal there is a lot of code that could be abstracted from get_the_content()686 *687 * @param string $more_link_text Optional. Content for when there is more text.688 * @param bool $strip_teaser Optional. Strip teaser content before the more text. Default is false.689 * @param int $id Optional. A post id. Defaults to the current post when in The Loop, undefined otherwise.690 * @return string The content minus the extracted post format content.691 */692 function get_the_remaining_content( $more_link_text = null, $strip_teaser = false, $id = 0 ) {693 global $more, $page, $preview;694 695 $post = get_post( $id );696 697 extract( wp_parse_post_content( $post, true ) );698 699 if ( null === $more_link_text )700 $more_link_text = __( '(more…)' );701 702 $output = '';703 $has_teaser = false;704 705 // If post password required and it doesn't match the cookie.706 if ( post_password_required( $post ) )707 return get_the_password_form( $post );708 709 if ( $page > count( $pages ) ) // if the requested page doesn't exist710 $page = count( $pages ); // give them the highest numbered page that DOES exist711 712 $content = $pages[$page-1];713 if ( preg_match( '/<!--more(.*?)?-->/', $content, $matches ) ) {714 $content = explode( $matches[0], $content, 2 );715 if ( ! empty( $matches[1] ) && ! empty( $more_link_text ) )716 $more_link_text = strip_tags( wp_kses_no_null( trim( $matches[1] ) ) );717 718 $has_teaser = true;719 } else {720 $content = array( $content );721 }722 723 if ( false !== strpos( $post->post_content, '<!--noteaser-->' ) && ( ! $multipage || $page == 1 ) )724 $strip_teaser = true;725 726 $teaser = $content[0];727 728 if ( $more && $strip_teaser && $has_teaser )729 $teaser = '';730 731 $output .= $teaser;732 733 if ( count( $content ) > 1 ) {734 if ( $more ) {735 $output .= '<span id="more-' . $post->ID . '"></span>' . $content[1];736 } else {737 if ( ! empty( $more_link_text ) )738 $output .= apply_filters( 'the_content_more_link', ' <a href="' . get_permalink() . "#more-{$post->ID}\" class=\"more-link\">$more_link_text</a>", $more_link_text );739 740 $output = force_balance_tags( $output );741 }742 }743 744 if ( $preview ) // preview fix for javascript bug with foreign languages745 $output = preg_replace_callback( '/\%u([0-9A-F]{4})/', '_convert_urlencoded_to_entities', $output );746 747 return $output;748 }749 750 /**751 * Display the post content minus the parsed post format data.752 *753 * @since 3.6.0754 *755 * @param string $more_link_text Optional. Content for when there is more text.756 * @param bool $strip_teaser Optional. Strip teaser content before the more text. Default is false.757 * @param int $id Optional. A post id. Defaults to the current post when in The Loop, undefined otherwise.758 */759 function the_remaining_content( $more_link_text = null, $strip_teaser = false, $id = 0 ) {760 $post = get_post( $id );761 762 $extra = get_the_remaining_content( $more_link_text, $strip_teaser, $post->ID );763 764 remove_filter( 'the_content', 'post_formats_compat', 7 );765 $content = apply_filters( 'the_content', $extra, $post->ID );766 add_filter( 'the_content', 'post_formats_compat', 7, 2 );767 768 echo str_replace( ']]>', ']]>', $content );769 }770 771 /**772 278 * Don't display post titles for asides and status posts on the front end. 773 279 *
Note: See TracChangeset
for help on using the changeset viewer.