Make WordPress Core


Ignore:
Timestamp:
02/21/2008 09:20:09 PM (18 years ago)
Author:
ryan
Message:

Dashboard widgets caching improvements from mdawaffe. see #5750

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-admin/includes/dashboard.php

    r6810 r6958  
    3333    );
    3434
    35 
    3635    // Incoming Links Widget
    3736    if ( !isset( $widget_options['dashboard_incoming_links'] ) ) {
     
    4544    }
    4645    wp_register_sidebar_widget( 'dashboard_incoming_links', __( 'Incoming Links' ), 'wp_dashboard_empty',
    47         array( 'all_link' => $widget_options['dashboard_incoming_links']['link'], 'feed_link' => $widget_options['dashboard_incoming_links']['url'], 'width' => 'half' )
     46        array( 'all_link' => $widget_options['dashboard_incoming_links']['link'], 'feed_link' => $widget_options['dashboard_incoming_links']['url'], 'width' => 'half' ),
     47        'wp_dashboard_cached_rss_widget', 'wp_dashboard_incoming_links_output'
    4848    );
    4949    wp_register_widget_control( 'dashboard_incoming_links', __( 'Incoming Links' ), 'wp_dashboard_rss_control', array(),
     
    5454    // WP Plugins Widget
    5555    wp_register_sidebar_widget( 'dashboard_plugins', __( 'Plugins' ), 'wp_dashboard_empty',
    56         array( 'all_link' => 'http://wordpress.org/extend/plugins/', 'feed_link' => 'http://wordpress.org/extend/plugins/rss/', 'width' => 'half' )
    57     );
    58     wp_register_widget_control( 'dashboard_plugins', __( 'Plugins' ), 'wp_dashboard_empty', array(),
    59         array( 'widget_id' => 'dashboard_plugins' )
    60     );
    61 
     56        array( 'all_link' => 'http://wordpress.org/extend/plugins/', 'feed_link' => 'http://wordpress.org/extend/plugins/rss/', 'width' => 'half' ),
     57        'wp_dashboard_cached_rss_widget', 'wp_dashboard_plugins_output',
     58        array( 'http://wordpress.org/extend/plugins/rss/browse/popular/', 'http://wordpress.org/extend/plugins/rss/browse/new/', 'http://wordpress.org/extend/plugins/rss/browse/updated/' )
     59    );
    6260
    6361    // Primary feed (Dev Blog) Widget
     
    7573    }
    7674    wp_register_sidebar_widget( 'dashboard_primary', $widget_options['dashboard_primary']['title'], 'wp_dashboard_empty',
    77         array( 'all_link' => $widget_options['dashboard_primary']['link'], 'feed_link' => $widget_options['dashboard_primary']['url'], 'width' => 'half', 'class' => 'widget_rss' )
     75        array( 'all_link' => $widget_options['dashboard_primary']['link'], 'feed_link' => $widget_options['dashboard_primary']['url'], 'width' => 'half', 'class' => 'widget_rss' ),
     76        'wp_dashboard_cached_rss_widget', 'wp_dashboard_rss_output'
    7877    );
    7978    wp_register_widget_control( 'dashboard_primary', __( 'Primary Feed' ), 'wp_dashboard_rss_control', array(),
     
    9392    }
    9493    wp_register_sidebar_widget( 'dashboard_secondary', $widget_options['dashboard_secondary']['title'], 'wp_dashboard_empty',
    95         array( 'all_link' => $widget_options['dashboard_secondary']['link'], 'feed_link' => $widget_options['dashboard_secondary']['url'], 'width' => 'full' )
     94        array( 'all_link' => $widget_options['dashboard_secondary']['link'], 'feed_link' => $widget_options['dashboard_secondary']['url'], 'width' => 'full' ),
     95        'wp_dashboard_cached_rss_widget', 'wp_dashboard_secondary_output'
    9696    );
    9797    wp_register_widget_control( 'dashboard_secondary', __( 'Secondary Feed' ), 'wp_dashboard_rss_control', array(),
     
    9999    );
    100100
     101
     102        /* Dashboard Widget Template
     103        wp_register_sidebar_widget( $widget_id (unique slug) , $widget_title, $output_callback,
     104            array(
     105                'all_link'  => full url for "See All" link,
     106                'feed_link' => full url for "RSS" link,
     107                'width'     => 'fourth', 'third', 'half', 'full' (defaults to 'half'),
     108                'height'    => 'single', 'double' (defaults to 'single'),
     109            ),
     110            $wp_dashboard_empty_callback (only needed if using 'wp_dashboard_empty' as your $output_callback),
     111            $arg, $arg, $arg... (further args passed to callbacks)
     112        );
     113   
     114        // optional: if you want users to be able to edit the settings of your widget, you need to register a widget_control
     115        wp_register_widget_control( $widget_id, $widget_control_title, $control_output_callback,
     116            array(), // leave an empty array here: oddity in widget code
     117            array(
     118                'widget_id' => $widget_id, // Yes - again.  This is required: oddity in widget code
     119                'arg'       => an arg to pass to the $control_output_callback,
     120                'another'   => another arg to pass to the $control_output_callback,
     121                ...
     122            )
     123        );
     124        */
    101125
    102126    // Hook to register new widgets
     
    175199            $wp_registered_widgets[$widget_id]['callback'] = 'wp_dashboard_empty';
    176200            $sidebar_widget_name = $wp_registered_widget_controls[$widget_id]['name'];
    177             $params[1] = $widget_id;
     201            $params[1] = 'wp_dashbaord_trigger_widget_control';
    178202            $sidebar_before_widget .= '<form action="' . remove_query_arg( 'edit' )  . '" method="post">';
    179203            $sidebar_after_widget   = "<div class='dashboard-widget-submit'><input type='hidden' name='sidebar' value='wp_dashboard' /><input type='hidden' name='widget_id' value='$widget_id' /><input type='submit' value='" . __( 'Save' ) . "' /></div></form>$sidebar_after_widget";
     
    219243function wp_dashboard_recent_comments( $sidebar_args ) {
    220244    global $comment;
    221 
    222245    extract( $sidebar_args, EXTR_SKIP );
    223246
     
    269292}
    270293
    271 // Empty widget used for JS/AJAX created output.  Also used when widget is in edit mode.
    272 function wp_dashboard_empty( $sidebar_args, $widget_control_id = false ) {
     294// $sidebar_args are handled by wp_dashboard_empty()
     295function wp_dashboard_incoming_links_output() {
     296    $widgets = get_option( 'dashboard_widget_options' );
     297    @extract( @$widgets['dashboard_incoming_links'], EXTR_SKIP );
     298    $rss = @fetch_rss( $url );
     299    if ( isset($rss->items) && 1 < count($rss->items) )  {// Technorati returns a 1-item feed when it has no results
     300
     301        echo "<ul>\n";
     302
     303        $rss->items = array_slice($rss->items, 0, $items);
     304        foreach ( $rss->items as $item ) {
     305            $publisher = '';
     306            $site_link = '';
     307            $link = '';
     308            $content = '';
     309            $date = '';
     310            $link = clean_url( strip_tags( $item['link'] ) );
     311       
     312            if ( isset( $item['author_uri'] ) )
     313                $site_link = clean_url( strip_tags( $item['author_uri'] ) );
     314       
     315            if ( !$publisher = wp_specialchars( strip_tags( isset($item['dc']['publisher']) ? $item['dc']['publisher'] : $item['author_name'] ) ) )
     316                $publisher = __( 'Somebody' );
     317            if ( $site_link )
     318                $publisher = "<a href='$site_link'>$publisher</a>";
     319            else
     320                $publisher = "<strong>$publisher</strong>";
     321       
     322            if ( isset($item['description']) )
     323                $content = $item['description'];
     324            elseif ( isset($item['summary']) )
     325                $content = $item['summary'];
     326            elseif ( isset($item['atom_content']) )
     327                $content = $item['atom_content'];
     328            else
     329                $content = __( 'something' );
     330            $content = strip_tags( $content );
     331            if ( 50 < strlen($content) )
     332                $content = substr($content, 0, 50) . ' ...';
     333            $content = wp_specialchars( $content );
     334            if ( $link )
     335                $text = _c( '%1$s linked here <a href="%2$s">saying</a>, "%3$s"|feed_display' );
     336            else
     337                $text = _c( '%1$s linked here saying, "%3$s"|feed_display' );
     338       
     339            if ( $show_date ) {
     340                if ( $show_author || $show_summary )
     341                    $text .= _c( ' on %4$s|feed_display' );
     342                $date = wp_specialchars( strip_tags( isset($item['pubdate']) ? $item['pubdate'] : $item['published'] ) );
     343                $date = strtotime( $date );
     344                $date = gmdate( get_option( 'date_format' ), $date );
     345            }
     346       
     347            echo "\t<li>" . sprintf( _c( "$text|feed_display" ), $publisher, $link, $content, $date ) . "</li>\n";
     348        }
     349
     350        echo "</ul>\n";
     351
     352    } else {
     353        echo '<p>' . __('No incoming links found... yet.') . "</p>\n";
     354    }
     355}
     356
     357// $sidebar_args are handled by wp_dashboard_empty()
     358function wp_dashboard_rss_output( $widget_id ) {
     359    $widgets = get_option( 'dashboard_widget_options' );
     360    wp_widget_rss_output( $widgets[$widget_id] );
     361}
     362
     363// $sidebar_args are handled by wp_dashboard_empty()
     364function wp_dashboard_secondary_output() {
     365    $widgets = get_option( 'dashboard_widget_options' );
     366    @extract( @$widgets['dashboard_secondary'], EXTR_SKIP );
     367    $rss = @fetch_rss( $url );
     368    if ( !isset($rss->items) || 0 == count($rss->items) )
     369        return false;
     370
     371    echo "<ul>\n";
     372
     373    $rss->items = array_slice($rss->items, 0, $items);
     374    foreach ($rss->items as $item ) {
     375        $title = wp_specialchars($item['title']);
     376        $author = preg_replace( '|(.+?):.+|s', '$1', $item['title'] );
     377        $post = preg_replace( '|.+?:(.+)|s', '$1', $item['title'] );
     378        $link = clean_url($item['link']);
     379
     380        echo "\t<li><a href='$link'><span class='post'>$post</span><span class='hidden'> - </span><cite>$author</cite></a></li>\n";
     381    }
     382
     383    echo "</ul>\n<br class='clear' />\n";
     384}
     385
     386// $sidebar_args are handled by wp_dashboard_empty()
     387function wp_dashboard_plugins_output() {
     388    $popular = @fetch_rss( 'http://wordpress.org/extend/plugins/rss/browse/popular/' );
     389    $new     = @fetch_rss( 'http://wordpress.org/extend/plugins/rss/browse/new/' );
     390    $updated = @fetch_rss( 'http://wordpress.org/extend/plugins/rss/browse/updated/' );
     391
     392    foreach ( array( 'popular' => __('Most Popular'), 'new' => __('Newest Plugins'), 'updated' => __('Recently Updated') ) as $feed => $label ) {
     393        if ( !isset($$feed->items) || 0 == count($$feed->items) )
     394            continue;
     395
     396        $$feed->items = array_slice($$feed->items, 0, 5);
     397        $item_key = array_rand($$feed->items);
     398
     399        // Eliminate some common badly formed plugin descriptions
     400        while ( ( null !== $item_key = array_rand($$feed->items) ) && false !== strpos( $$feed->items[$item_key]['description'], 'Plugin Name:' ) )
     401            unset($$feed->items[$item_key]);
     402
     403        if ( !isset($$feed->items[$item_key]) )
     404            continue;
     405
     406        $item = $$feed->items[$item_key];
     407
     408        // current bbPress feed item titles are: user on "topic title"
     409        if ( preg_match( '/"(.*)"/s', $item['title'], $matches ) )
     410            $title = $matches[1];
     411        else // but let's make it forward compatible if things change
     412            $title = $item['title'];
     413        $title = wp_specialchars( $title );
     414
     415        $description = wp_specialchars( strip_tags(html_entity_decode($item['description'], ENT_QUOTES)) );
     416
     417        list($link, $frag) = explode( '#', $item['link'] );
     418
     419        $link = clean_url($link);
     420        $dlink = rtrim($link, '/') . '/download/';
     421
     422        echo "<h4>$label</h4>\n";
     423        echo "<h5><a href='$link'>$title</a></h5> <span>(<a href='$dlink'>" . __( 'Download' ) . "</a>)</span>\n";
     424        echo "<p>$description</p>\n";
     425    }
     426}
     427
     428// Checks to see if all of the feed url in $check_urls are cached.
     429// If $check_urls is empty, look for the rss feed url found in the dashboard widget optios of $widget_id.
     430// If cached, call $callback, a function that echoes out output for this widget.
     431// If not cache, echo a "Loading..." stub which is later replaced by AJAX call (see top of /wp-admin/index.php)
     432function wp_dashboard_cached_rss_widget( $widget_id, $callback, $check_urls = array() ) {
     433    $loading = '<p class="widget-loading">' . __( 'Loading&#8230;' ) . '</p>';
     434
     435    if ( empty($check_urls) ) {
     436        $widgets = get_option( 'dashboard_widget_options' );
     437        if ( empty($widgets[$widget_id]['url']) ) {
     438            echo $loading;
     439            return false;
     440        }
     441        $check_urls = array( $widgets[$widget_id]['url'] );
     442    }
     443
     444
     445    require_once( ABSPATH . WPINC . '/rss.php' );
     446    init(); // initialize rss constants
     447
     448    $cache = new RSSCache( MAGPIE_CACHE_DIR, MAGPIE_CACHE_AGE );
     449
     450    foreach ( $check_urls as $check_url ) {
     451        $status = $cache->check_cache( $check_url );
     452        if ( 'HIT' !== $status ) {
     453            echo $loading;
     454            return false;
     455        }
     456    }
     457
     458    if ( $callback && is_callable( $callback ) ) {
     459        $args = array_slice( func_get_args(), 2 );
     460        array_unshift( $args, $widget_id );
     461        call_user_func_array( $callback, $args );
     462    }
     463
     464    return true;
     465}
     466
     467// Empty widget used for JS/AJAX created output.
     468// Callback inserts content between before_widget and after_widget.  Used when widget is in edit mode.  Can also be used for custom widgets.
     469function wp_dashboard_empty( $sidebar_args, $callback = false ) {
    273470    extract( $sidebar_args, EXTR_SKIP );
    274471
     
    279476    echo $after_title;
    280477
    281     if ( $widget_control_id ) // If in edit mode
    282         wp_dashbaord_trigger_widget_control( $widget_control_id );
     478    // When in edit mode, the callback passed to this function is the widget_control callback
     479    if ( $callback && is_callable( $callback ) ) {
     480        $args = array_slice( func_get_args(), 2 );
     481        array_unshift( $args, $widget_id );
     482        call_user_func_array( $callback, $args );
     483    }
    283484
    284485    echo $after_widget;
Note: See TracChangeset for help on using the changeset viewer.