Make WordPress Core

Ticket #23625: 23625.9.diff

File 23625.9.diff, 6.1 KB (added by lancewillett, 12 years ago)
  • wp-includes/post-formats.php

     
    392392}
    393393
    394394/**
     395 * Add chat detection support to the `get_content_chat()` chat parser
     396 *
     397 * @since 3.6.0
     398 *
     399 * @global array $_wp_chat_parsers
     400 * @param string $name Unique identifier for chat format. Example: IRC
     401 * @param string $newline_regex RegEx to match the start of a new line, typically when a new "username:" appears
     402 *      The parser will handle up to 3 matched expressions
     403 *      $matches[0] = the string before the user's message starts
     404 *      $matches[1] = the time of the message, if present
     405 *      $matches[2] = the author/username
     406 *      OR
     407 *      $matches[0] = the string before the user's message starts
     408 *      $matches[1] = the author/username
     409 * @param string $delimiter_regex RegEx to determine where to split the username syntax from the chat message
     410 */
     411function add_chat_detection_format( $name, $newline_regex, $delimiter_regex ) {
     412        global $_wp_chat_parsers;
     413
     414        if ( empty( $_wp_chat_parsers ) )
     415                $_wp_chat_parsers = array();
     416
     417        $_wp_chat_parsers = array( $name => array( $newline_regex, $delimiter_regex ) ) + $_wp_chat_parsers;
     418}
     419add_chat_detection_format( 'IM', '#^([^:]+):#', '#[:]#' );
     420add_chat_detection_format( 'Skype', '#^(\[.+?\])\s([^:]+):#', '#[:]#' );
     421
     422/**
     423 * Deliberately interpret passed content as a chat transcript that is optionally
     424 * followed by commentary
     425 *
     426 * If the content does not contain username syntax, assume that it does not contain
     427 * chat logs and return
     428 *
     429 * @since 3.6.0
     430 *
     431 * Example:
     432 *
     433 * One stanza of chat:
     434 * Scott: Hey, let's chat!
     435 * Helen: No.
     436 *
     437 * $stanzas = array(
     438 *     array(
     439 *         array(
     440 *             'time' => '',
     441 *             'author' => 'Scott',
     442 *             'messsage' => "Hey, let's chat!"
     443 *         ),
     444 *         array(
     445 *             'time' => '',
     446 *             'author' => 'Helen',
     447 *             'message' => 'No.'
     448 *         )
     449 *     )
     450 * )
     451 * @param string $content A string which might contain chat data.
     452 * @param boolean $remove Whether to remove the found data from the passed content.
     453 * @return array A chat log as structured data
     454 */
     455function get_content_chat( &$content, $remove = false ) {
     456        global $_wp_chat_parsers;
     457
     458        $trimmed = trim( $content );
     459        if ( empty( $trimmed ) )
     460                return array();
     461
     462        $has_match = false;
     463        $matched_parser = false;
     464        foreach ( $_wp_chat_parsers as $parser ) {
     465                @list( $newline_regex ) = $parser;
     466                if ( preg_match( $newline_regex, $trimmed ) ) {
     467                        $has_match = true;
     468                        $matched_parser = $parser;
     469                        break;
     470                }
     471        }
     472
     473        if ( false === $matched_parser )
     474                return array();
     475
     476        @list( $newline_regex, $delimiter_regex ) = $parser;
     477
     478        $last_index = 0;
     479        $stanzas = array();
     480        $lines = explode( "\n", make_clickable( $trimmed ) );
     481
     482        $author = $time = '';
     483        $data = array();
     484        $stanza = array();
     485
     486        foreach ( $lines as $index => $line ) {
     487                $line = trim( $line );
     488
     489                if ( empty( $line ) ) {
     490                        if ( ! empty( $author ) ) {
     491                                $stanza[] = array(
     492                                        'time' => $time,
     493                                        'author' => $author,
     494                                        'message' => join( ' ', $data )
     495                                );
     496                        }
     497
     498                        $stanzas[] = $stanza;
     499                        $last_index = $index;
     500                        $stanza = array();
     501                        $author = $time = '';
     502                        $data = array();
     503                        if ( ! empty( $lines[$index + 1] ) && ! preg_match( $delimiter_regex, $lines[$index + 1] ) )
     504                                break;
     505                }
     506
     507                $matches = array();
     508                $matched = preg_match( $newline_regex, $line, $matches );
     509                $author_match = empty( $matches[2] ) ? $matches[1] : $matches[2];
     510                // assume username syntax if no whitespace is present
     511                $no_ws = $matched && ! preg_match( '#\s#', $author_match );
     512                // allow script-like stanzas
     513                $has_ws = $matched && preg_match( '#\s#', $author_match ) && empty( $lines[$index + 1] ) && empty( $lines[$index - 1] );
     514                if ( $matched && ( ! empty( $matches[2] ) || ( $no_ws || $has_ws ) ) ) {
     515                        if ( ! empty( $author ) ) {
     516                                $stanza[] = array(
     517                                        'time' => $time,
     518                                        'author' => $author,
     519                                        'message' => join( ' ', $data )
     520                                );
     521                                $data = array();
     522                        }
     523
     524                        $time = empty( $matches[2] ) ? '' : $matches[1];
     525                        $author = $author_match;
     526                        $data[] = trim( str_replace( $matches[0], '', $line ) );
     527                } elseif ( preg_match( '#\S#', $line ) ) {
     528                        $data[] = $line;
     529                }
     530        }
     531
     532        if ( ! empty( $author ) ) {
     533                $stanza[] = array(
     534                        'time' => $time,
     535                        'author' => $author,
     536                        'message' => trim( join( ' ', $data ) )
     537                );
     538        }
     539
     540        if ( ! empty( $stanza ) )
     541                $stanzas[] = $stanza;
     542
     543        if ( $remove )
     544                $content = trim( join( "\n", array_slice( $lines, $last_index ) ) );
     545
     546        return $stanzas;
     547}
     548
     549/**
     550 * Retrieve structured chat data from the current or passed post
     551 *
     552 * @since 3.6.0
     553 *
     554 * @param int $id Optional. Post ID
     555 * @return array
     556 */
     557function get_the_chat( $id = 0 ) {
     558        $post = empty( $id ) ? clone get_post() : get_post( $id );
     559        if ( empty( $post ) )
     560                return array();
     561
     562        $data = get_content_chat( $post->post_content );
     563        if ( empty( $data ) )
     564                return array();
     565
     566        return $data;
     567}
     568
     569/**
     570 * Output HTML for a given chat's structured data. Themes can use this as a
     571 * template tag in place of the_content() for Chat post format templates.
     572 *
     573 * @since 3.6.0
     574 *
     575 * @uses get_the_chat()
     576 *
     577 * @print HTML
     578 */
     579function the_chat() {
     580        $output = '<dl class="chat-transcript">';
     581
     582        $stanzas = get_the_chat();
     583
     584        foreach ( $stanzas as $stanza ) {
     585                foreach ( $stanza as $row ) {
     586                        $time = '';
     587                        if ( ! empty( $row['time'] ) )
     588                                $time = sprintf( '<time>%s</time>', esc_html( $row['time'] ) );
     589
     590                        $output .= sprintf(
     591                                '<dt class="chat-author chat-author-%1$s vcard">%2$s <cite class="fn">%3$s</cite>: </dt>
     592                                        <dd class="chat-text">%4$s</dd>
     593                                ',
     594                                esc_attr( strtolower( $row['author'] ) ), // Slug.
     595                                $time,
     596                                esc_html( $row['author'] ),
     597                                esc_html( $row['message'] )
     598                        );
     599                }
     600        }
     601
     602        $output .= '</dl><!-- .chat-transcript -->';
     603
     604        echo $output;
     605}
     606
     607/**
    395608 * Extract a URL from passed content, if possible
    396609 * Checks for a URL on the first line of the content or the first encountered href attribute.
    397610 *