Make WordPress Core

Ticket #7921: dashboard.php

File dashboard.php, 25.6 KB (added by jamierumbelow, 18 years ago)

The wp-admin/includes/dashboard.php file.

Line 
1<?php
2/**
3 * WordPress Dashboard Widget Administration Panel API
4 *
5 * @package WordPress
6 * @subpackage Administration
7 */
8
9/**
10 * Registers dashboard widgets.
11 *
12 * handles POST data, sets up filters.
13 *
14 * @since unknown
15 */
16function wp_dashboard_setup() {
17        global $wp_registered_widgets, $wp_registered_widget_controls, $wp_dashboard_control_callbacks;
18        $wp_dashboard_control_callbacks = array();
19
20        $update = false;
21        $widget_options = get_option( 'dashboard_widget_options' );
22        if ( !$widget_options || !is_array($widget_options) )
23                $widget_options = array();
24
25        /* Register Widgets and Controls */
26
27        // Recent Comments Widget
28        wp_add_dashboard_widget( 'dashboard_recent_comments', __( 'Recent Comments' ), 'wp_dashboard_recent_comments' );
29
30        // QuickPress Widget
31        wp_add_dashboard_widget( 'dashboard_quick_press', __( 'QuickPress' ), 'wp_dashboard_quick_press' );
32
33        // Recent Drafts
34        wp_add_dashboard_widget( 'dashboard_recent_drafts', __( 'Recent Drafts' ), 'wp_dashboard_recent_drafts' );
35
36        // Incoming Links Widget
37        if ( !isset( $widget_options['dashboard_incoming_links'] ) || !isset( $widget_options['dashboard_incoming_links']['home'] ) || $widget_options['dashboard_incoming_links']['home'] != get_option('home') ) {
38                $update = true;
39                $widget_options['dashboard_incoming_links'] = array(
40                        'home' => get_option('home'),
41                        'link' => apply_filters( 'dashboard_incoming_links_link', 'http://blogsearch.google.com/blogsearch?hl=en&scoring=d&partner=wordpress&q=link:' . trailingslashit( get_option('home') ) ),
42                        'url' => apply_filters( 'dashboard_incoming_links_feed', 'http://blogsearch.google.com/blogsearch_feeds?hl=en&scoring=d&ie=utf-8&num=10&output=rss&partner=wordpress&q=link:' . trailingslashit( get_option('home') ) ),
43                        'items' => 5,
44                        'show_date' => 0
45                );
46        }
47        wp_add_dashboard_widget( 'dashboard_incoming_links', __( 'Incoming Links' ), 'wp_dashboard_incoming_links', 'wp_dashboard_incoming_links_control' );
48
49        // WP Plugins Widget
50        if ( current_user_can( 'activate_plugins' ) )
51                wp_add_dashboard_widget( 'dashboard_plugins', __( 'Plugins' ), 'wp_dashboard_plugins' );
52
53        // Primary feed (Dev Blog) Widget
54        if ( !isset( $widget_options['dashboard_primary'] ) ) {
55                $update = true;
56                $widget_options['dashboard_primary'] = array(
57                        'link' => apply_filters( 'dashboard_primary_link',  __( 'http://wordpress.org/development/' ) ),
58                        'url' => apply_filters( 'dashboard_primary_feed',  __( 'http://wordpress.org/development/feed/' ) ),
59                        'title' => apply_filters( 'dashboard_primary_title', __( 'WordPress Development Blog' ) ),
60                        'items' => 2,
61                        'show_summary' => 1,
62                        'show_author' => 0,
63                        'show_date' => 1
64                );
65        }
66        wp_add_dashboard_widget( 'dashboard_primary', $widget_options['dashboard_primary']['title'], 'wp_dashboard_primary', 'wp_dashboard_primary_control' );
67
68        // Secondary Feed (Planet) Widget
69        if ( !isset( $widget_options['dashboard_secondary'] ) ) {
70                $update = true;
71                $widget_options['dashboard_secondary'] = array(
72                        'link' => apply_filters( 'dashboard_secondary_link',  __( 'http://planet.wordpress.org/' ) ),
73                        'url' => apply_filters( 'dashboard_secondary_feed',  __( 'http://planet.wordpress.org/feed/' ) ),
74                        'title' => apply_filters( 'dashboard_secondary_title', __( 'Other WordPress News' ) ),
75                        'items' => 15
76                );
77        }
78        wp_add_dashboard_widget( 'dashboard_secondary', $widget_options['dashboard_secondary']['title'], 'wp_dashboard_secondary', 'wp_dashboard_secondary_control' );
79
80        // Hook to register new widgets
81        do_action( 'wp_dashboard_setup' );
82
83        // Filter widget order
84        $dashboard_widgets = apply_filters( 'wp_dashboard_widgets', array() );
85
86        if ( 'POST' == $_SERVER['REQUEST_METHOD'] && isset($_POST['widget_id']) ) {
87                ob_start(); // hack - but the same hack wp-admin/widgets.php uses
88                wp_dashboard_trigger_widget_control( $_POST['widget_id'] );
89                ob_end_clean();
90                wp_redirect( remove_query_arg( 'edit' ) );
91                exit;
92        }
93
94        if ( $update )
95                update_option( 'dashboard_widget_options', $widget_options );
96
97        foreach ( $dashboard_widgets as $widget_id )
98                wp_add_dashboard_widget( $widget_id, $wp_registered_widgets[$widget_id]['name'], $wp_registered_widgets[$widget_id]['callback'], $wp_registered_widget_controls[$widget_id]['callback'] );
99}
100
101function wp_add_dashboard_widget( $widget_id, $widget_name, $callback, $control_callback = null ) {
102        global $wp_dashboard_control_callbacks;
103        if ( $control_callback && current_user_can( 'edit_dashboard' ) && is_callable( $control_callback ) ) {
104                $wp_dashboard_control_callbacks[$widget_id] = $control_callback;
105                if ( isset( $_GET['edit'] ) && $widget_id == $_GET['edit'] ) {
106                        list($url) = explode( '#', add_query_arg( 'edit', false ), 2 );
107                        $widget_name .= ' <a href="' . clean_url( $url ) . '">' . __( 'Cancel' ) . '</a>';
108                        add_meta_box( $widget_id, $widget_name, '_wp_dashboard_control_callback', 'dashboard', 'normal', 'core' );
109                        return;
110                }
111                list($url) = explode( '#', add_query_arg( 'edit', $widget_id ), 2 );
112                $widget_name .= ' <a href="' . clean_url( "$url#$widget_id" ) . '" class="edit-box open-box">' . __( 'Edit' ) . '</a>';
113        }
114        add_meta_box( $widget_id, $widget_name , $callback, 'dashboard', 'normal', 'core' );
115}
116
117function _wp_dashboard_control_callback( $dashboard, $meta_box ) {
118        echo '<form action="" method="post">';
119        wp_dashboard_trigger_widget_control( $meta_box['id'] );
120        echo "<p class='submit'><input type='hidden' name='widget_id' value='$meta_box[id]' /><input type='submit' value='" . __( 'Submit' ) . "' /></p>";
121
122        echo '</form>'; 
123}
124
125/**
126 * Displays the dashboard.
127 *
128 * @since unknown
129 */
130function wp_dashboard() {
131        echo "<div id='dashboard-widgets' class='metabox-holder'>\n\n";
132
133        echo "<div id='side-info-column' class='inner-sidebar'>\n\n";
134        $class = do_meta_boxes( 'dashboard', 'side', '' ) ? ' class="has-sidebar"' : '';
135        echo "</div>\n\n";
136
137        echo "<div id='post-body'$class>\n\n";
138        echo "<div id='dashboard-widgets-main-content' class='has-sidebar-content'>\n\n";
139        do_meta_boxes( 'dashboard', 'normal', '' );
140        echo "</div>\n\n";
141        echo "</div>\n\n";
142
143        echo "<form style='display: none' method='get' action=''>\n<p>\n";
144        wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false );
145        wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false );
146        echo "</p>\n</form>\n";
147
148        echo "</div>";
149}
150
151/* Dashboard Widgets */
152
153function wp_dashboard_quick_press( $dashboard, $meta_box ) {
154        $drafts = false;
155        if ( 'post' === strtolower( $_SERVER['REQUEST_METHOD'] ) && isset( $_POST['action'] ) && 0 === strpos( $_POST['action'], 'post-quickpress' ) ) {
156                $view = get_permalink( $_POST['post_ID'] );
157                $edit = clean_url( get_edit_post_link( $_POST['post_ID'] ) );
158                if ( 'post-quickpress-publish' == $_POST['action'] ) {
159                        printf( __( 'Post Published. <a href="%s">View post</a> | <a href="%s">Edit post</a>' ), clean_url( $view ), $edit );
160                } else {
161                        printf( __( 'Draft Saved. <a href="%s">Preview post</a> | <a href="%s">Edit post</a>' ), clean_url( add_query_arg( 'preview', 1, $view ) ), $edit );
162                        $drafts_query = new WP_Query( array(
163                                'post_type' => 'post',
164                                'what_to_show' => 'posts',
165                                'post_status' => 'draft',
166                                'author' => $GLOBALS['current_user']->ID,
167                                'posts_per_page' => 1,
168                                'orderby' => 'modified',
169                                'order' => 'DESC'
170                        ) );
171               
172                        if ( $drafts_query->posts )
173                                $drafts =& $drafts_query->posts;
174                }
175                $_REQUEST = array(); // hack for get_default_post_to_edit()
176        }
177
178        $post = get_default_post_to_edit();
179?>
180
181        <form name="post" action="<?php echo clean_url( admin_url( 'post.php' ) ); ?>" method="post" id="quick-press">
182                <h4 id="quick-post-title"><label for="title"><?php _e('Title') ?></label></h4>
183                <div class="input-text-wrap">
184                        <input type="text" name="post_title" id="title" autocomplete="off" value="<?php echo attribute_escape( $post->post_title ); ?>" />
185                </div>
186
187                <div id="add-media-button" class="alignright">
188                        <a class="thickbox button" href="http://hacek.local/wordpress/wp-admin/media-upload.php?TB_iframe=true" id="add-media-link"><?php _e( 'Insert Media' ); ?></a>
189                </div>
190
191                <h4 id="content-label"><label for="content"><?php _e('Post') ?></label></h4>
192                <div class="textarea-wrap">
193                        <textarea name="content" id="content" class="mceEditor" rows="3" cols="15"><?php echo $post->post_content; ?></textarea>
194                </div>
195
196                <h4><label for="tags-input"><?php _e('Tags') ?></label></h4>
197                <div class="input-text-wrap">
198                        <input type="text" name="tags_input" id="tags-input" value="<?php echo get_tags_to_edit( $post->ID ); ?>" />
199                </div>
200                <p class='field-tip'><?php _e('Separate tags with commas'); ?></p>
201
202                <p class="submit">
203                        <input type="hidden" name="action" id="quickpost-action" value="post-quickpress-save" />
204                        <input type="hidden" name="quickpress_post_ID" value="<?php echo (int) $post->ID; ?>" />
205                        <?php wp_nonce_field('add-post'); ?>
206                        <input type="submit" name="save" id="save-post" class="button alignleft" value="<?php _e('Save Draft'); ?>" />
207                        <input type="submit" name="publish" id="publish" accesskey="p" class="button button-highlighted alignright" value="<?php _e('Publish'); ?>" />
208                        <br class="clear" />
209                </p>
210
211        </form>
212
213<?php
214        if ( $drafts )
215                wp_dashboard_recent_drafts( $drafts );
216}
217
218function wp_dashboard_recent_drafts( $drafts = false ) {
219        global $post;
220        if ( !$drafts ) {
221                $drafts_query = new WP_Query( array(
222                        'post_type' => 'post',
223                        'what_to_show' => 'posts',
224                        'post_status' => 'draft',
225                        'author' => $GLOBALS['current_user']->ID,
226                        'posts_per_page' => 5,
227                        'orderby' => 'modified',
228                        'order' => 'DESC'
229                ) );
230                $drafts =& $drafts_query->posts;
231        }
232
233        if ( $drafts && is_array( $drafts ) ) {
234                $list = array();
235                foreach ( $drafts as $post ) {
236                        $url = get_edit_post_link( $draft->ID );
237                        $title = _draft_or_post_title( $draft->ID );
238                        $list[] = '<abbr title="' . get_the_time(__('Y/m/d g:i:s A')) . '">' . get_the_time( get_option( 'date_format' ) ) . "</abbr> <a href='$url' title='" . sprintf( __( 'Edit "%s"' ), attribute_escape( $title ) ) . "'>$title</a>";
239}               
240?>
241        <ul>
242                <li><?php echo join( "</li>\n<li>", $list ); ?></li>
243        </ul>
244
245<?php
246}
247        else
248        {
249                ?>
250                        There are no drafts saved at the moment!
251                <?php
252        }
253
254}
255
256/**
257 * Display recent comments dashboard widget content.
258 *
259 * @since unknown
260 */
261function wp_dashboard_recent_comments() {
262        list($comments, $total) = _wp_get_comment_list( '', false, 0, 5 );
263
264        if ( $comments ) :
265?>
266
267                <p class="view-all"><a href="edit-comments.php"><?php _e( 'View All Comments' ); ?></a></p>
268                <div id="the-comment-list" class="list:comment">
269
270<?php
271                foreach ( $comments as $comment )
272                        _wp_dashboard_recent_comments_row( $comment );
273?>
274
275                </div>
276
277<?php
278                wp_comment_reply( -1, false, 'dashboard', false );
279
280        else :
281?>
282
283        <p><?php _e( 'No comments yet.' ); ?></p>
284
285<?php
286        endif; // $comments;
287}
288
289function _wp_dashboard_recent_comments_row( &$comment, $show_date = true ) {
290        static $date = false;
291        static $today = false;
292        static $yesterday = false;
293
294        $GLOBALS['comment'] =& $comment;
295
296        if ( $show_date ) {
297                if ( !$today )
298                        $today = gmdate( get_option( 'date_format' ), time() + get_option( 'gmt_offset' ) );
299                if ( !$yesterday )
300                        $yesterday = gmdate( get_option( 'date_format' ), strtotime( 'yesterday' ) + get_option( 'gmt_offset' ) );
301                $wordy_dates = array( $today => __( 'Today' ), $yesterday => __( 'Yesterday' ) );
302       
303                $comment_date = gmdate( get_option( 'date_format' ), strtotime( $comment->comment_date ) + get_option( 'gmt_offset' ) );
304                if ( $comment_date != $date ) {
305                        $date = $comment_date;
306                        echo '<h4>' . ( isset( $wordy_dates[$date] ) ? $wordy_dates[$date] : $date ) . ":</h4>\n";
307                }
308        }
309
310        $comment_post_url = get_edit_post_link( $comment->comment_post_ID );
311        $comment_post_title = get_the_title( $comment->comment_post_ID );
312        $comment_post_link = "<a href='$comment_post_url'>$comment_post_title</a>";
313        $comment_link = '<a class="comment-link" href="' . get_comment_link() . '">#</a>';
314
315        $delete_url = clean_url( wp_nonce_url( "comment.php?action=deletecomment&p=$comment->comment_post_ID&c=$comment->comment_ID", "delete-comment_$comment->comment_ID" ) );
316        $approve_url = clean_url( wp_nonce_url( "comment.php?action=approvecomment&p=$comment->comment_post_ID&c=$comment->comment_ID", "approve-comment_$comment->comment_ID" ) );
317        $unapprove_url = clean_url( wp_nonce_url( "comment.php?action=unapprovecomment&p=$comment->comment_post_ID&c=$comment->comment_ID", "unapprove-comment_$comment->comment_ID" ) );
318        $spam_url = clean_url( wp_nonce_url( "comment.php?action=deletecomment&dt=spam&p=$comment->comment_post_ID&c=$comment->comment_ID", "delete-comment_$comment->comment_ID" ) );
319
320        $actions = array();
321
322        if ( current_user_can('edit_post', $comment->comment_post_ID) ) {
323                $actions['approve'] = "<a href='$approve_url' class='dim:the-comment-list:comment-$comment->comment_ID:unapproved:e7e7d3:e7e7d3:new=approved vim-a' title='" . __( 'Approve this comment' ) . "'>" . __( 'Approve' ) . '</a>';
324                $actions['unapprove'] = "<a href='$unapprove_url' class='dim:the-comment-list:comment-$comment->comment_ID:unapproved:e7e7d3:e7e7d3:new=unapproved vim-u' title='" . __( 'Unapprove this comment' ) . "'>" . __( 'Unapprove' ) . '</a>';
325                $actions['edit'] = "<a href='comment.php?action=editcomment&amp;c={$comment->comment_ID}' title='" . __('Edit comment') . "'>". __('Edit') . '</a>';
326                $actions['spam'] = "<a href='$spam_url' class='delete:the-comment-list:comment-$comment->comment_ID::spam=1 vim-s vim-destructive' title='" . __( 'Mark this comment as spam' ) . "'>" . __( 'Spam' ) . '</a>';
327                $actions['delete'] = "<a href='$delete_url' class='delete:the-comment-list:comment-$comment->comment_ID delete vim-d vim-destructive'>" . __('Delete') . '</a>';
328                $actions['quickedit'] = '<a onclick="commentReply.open(\''.$comment->comment_ID.'\',\''.$comment->comment_post_ID.'\',\'edit\');return false;" class="vim-q" title="'.__('Quick Edit').'" href="#">' . __('Quick Edit') . '</a>';
329                $actions['reply'] = '<a onclick="commentReply.open(\''.$comment->comment_ID.'\',\''.$comment->comment_post_ID.'\');return false;" class="vim-r hide-if-no-js" title="'.__('Reply to this comment').'" href="#">' . __('Reply') . '</a>';
330
331                $actions = apply_filters( 'comment_row_actions', $actions, $comment );
332
333                $i = 0;
334                $actions_string = '';
335                foreach ( $actions as $action => $link ) {
336                        ++$i;
337                        ( ( ('approve' == $action || 'unapprove' == $action) && 2 === $i ) || 1 === $i ) ? $sep = '' : $sep = ' | ';
338
339                        // Reply and quickedit need a hide-if-no-js span
340                        if ( 'reply' == $action )
341                                $action .= ' hide-if-no-js';
342                        elseif ( 'quickedit' == $action )
343                                $action .= ' hide-if-no-js hide-if-js'; // hah
344
345                        $actions_string .= "<span class='$action'>$sep$link</span>";
346                }
347        }
348
349?>
350
351                <div id="comment-<?php echo $comment->comment_ID; ?>" <?php comment_class( array( 'comment-item', wp_get_comment_status($comment->comment_ID) ) ); ?>>
352                        <?php if ( !$comment->comment_type || 'comment' == $comment->comment_type ) : ?>
353
354                        <?php echo get_avatar( $comment, 32 ); ?>
355                        <span class="comment-meta"><?php printf( __( '%1$s in response to %2$s:' ), '<cite>' . get_comment_author() . '</cite>', $comment_post_link ); ?></span>
356
357                        <?php
358                        else :
359                                switch ( $comment->comment_type ) :
360                                case 'pingback' :
361                                        $type = __( 'Pingback' );
362                                        break;
363                                case 'trackback' :
364                                        $type = __( 'Trackback' );
365                                        break;
366                                default :
367                                        $type = ucwords( $comment->comment_type );
368                                endswitch;
369                                $type = wp_specialchars( $type );
370                        ?>
371
372                        <span class="comment-meta"><?php printf( __( '%3$s on %2$s: %1$s' ), '<cite>' . get_comment_author() . '</cite>', $comment_post_link, "<strong>$type</strong>" ); ?></span>
373
374                        <?php endif; // comment_type ?>
375                        <blockquote><p><?php comment_excerpt(); ?></p></blockquote>
376                        <p class="comment-actions"><?php echo $actions_string; ?></p>
377
378                        <div id="inline-<?php echo $comment->comment_ID; ?>" class="hidden">
379                                <textarea class="comment" rows="3" cols="10"><?php echo $comment->comment_content; ?></textarea>
380                                <div class="author-email"><?php echo attribute_escape( $comment->comment_author_email ); ?></div>
381                                <div class="author"><?php echo attribute_escape( $comment->comment_author ); ?></div>
382                                <div class="author-url"><?php echo attribute_escape( $comment->comment_author_url ); ?></div>
383                                <div class="comment_status"><?php echo $comment->comment_approved; ?></div>
384                        </div>
385
386                </div>
387<?php
388}
389
390function wp_dashboard_incoming_links() {
391        wp_dashboard_cached_rss_widget( 'dashboard_incoming_links', 'wp_dashboard_incoming_links_output' );
392}
393
394/**
395 * Display incoming links dashboard widget content.
396 *
397 * @since unknown
398 */
399function wp_dashboard_incoming_links_output() {
400        $widgets = get_option( 'dashboard_widget_options' );
401        @extract( @$widgets['dashboard_incoming_links'], EXTR_SKIP );
402        $rss = @fetch_rss( $url );
403        if ( isset($rss->items) && 0 < count($rss->items) )  {
404
405                echo "<ul>\n";
406
407                $rss->items = array_slice($rss->items, 0, $items);
408                foreach ( $rss->items as $item ) {
409                        $publisher = '';
410                        $site_link = '';
411                        $link = '';
412                        $content = '';
413                        $date = '';
414                        $link = clean_url( strip_tags( $item['link'] ) );
415
416                        if ( isset( $item['author_uri'] ) )
417                                $site_link = clean_url( strip_tags( $item['author_uri'] ) );
418
419                        if ( !$publisher = wp_specialchars( strip_tags( isset($item['dc']['publisher']) ? $item['dc']['publisher'] : $item['author_name'] ) ) )
420                                $publisher = __( 'Somebody' );
421                        if ( $site_link )
422                                $publisher = "<a href='$site_link'>$publisher</a>";
423                        else
424                                $publisher = "<strong>$publisher</strong>";
425
426                        if ( isset($item['description']) )
427                                $content = $item['description'];
428                        elseif ( isset($item['summary']) )
429                                $content = $item['summary'];
430                        elseif ( isset($item['atom_content']) )
431                                $content = $item['atom_content'];
432                        else
433                                $content = __( 'something' );
434                        $content = wp_html_excerpt($content, 50) . ' ...';
435                        if ( $link )
436                                $text = _c( '%1$s linked here <a href="%2$s">saying</a>, "%3$s"|feed_display' );
437                        else
438                                $text = _c( '%1$s linked here saying, "%3$s"|feed_display' );
439
440                        if ( $show_date ) {
441                                if ( $show_author || $show_summary )
442                                        $text .= _c( ' on %4$s|feed_display' );
443                                $date = wp_specialchars( strip_tags( isset($item['pubdate']) ? $item['pubdate'] : $item['published'] ) );
444                                $date = strtotime( $date );
445                                $date = gmdate( get_option( 'date_format' ), $date );
446                        }
447
448                        echo "\t<li>" . sprintf( _c( "$text|feed_display" ), $publisher, $link, $content, $date ) . "</li>\n";
449                }
450
451                echo "</ul>\n";
452
453        } else {
454                echo '<p>' . __('This dashboard widget queries <a href="http://blogsearch.google.com/">Google Blog Search</a> so that when another blog links to your site it will show up here. It has found no incoming links&hellip; yet. It&#8217;s okay &#8212; there is no rush.') . "</p>\n";
455        }
456}
457
458function wp_dashboard_incoming_links_control() {
459        wp_dashboard_rss_control( 'dashboard_incoming_links', array( 'title' => false, 'show_summary' => false, 'show_author' => false ) );
460}
461
462function wp_dashboard_primary() {
463        wp_dashboard_cached_rss_widget( 'dashboard_primary', 'wp_dashboard_rss_output' );
464}
465
466function wp_dashboard_primary_control() {
467        wp_dashboard_rss_control( 'dashboard_primary' );
468}
469
470/**
471 * {@internal Missing Short Description}}
472 *
473 * @since unknown
474 *
475 * @param int $widget_id
476 */
477function wp_dashboard_rss_output( $widget_id ) {
478        $widgets = get_option( 'dashboard_widget_options' );
479        echo "<div class='rss-widget'>";
480        wp_widget_rss_output( $widgets[$widget_id] );
481        echo "</div>";
482}
483
484function wp_dashboard_secondary() {
485        wp_dashboard_cached_rss_widget( 'dashboard_secondary', 'wp_dashboard_secondary_output' );
486}
487
488function wp_dashboard_secondary_control() {
489        wp_dashboard_rss_control( 'dashboard_secondary' );
490}
491
492/**
493 * Display secondary dashboard RSS widget feed.
494 *
495 * @since unknown
496 *
497 * @return unknown
498 */
499function wp_dashboard_secondary_output() {
500        $widgets = get_option( 'dashboard_widget_options' );
501        @extract( @$widgets['dashboard_secondary'], EXTR_SKIP );
502        $rss = @fetch_rss( $url );
503
504        if ( !isset($rss->items) || 0 == count($rss->items) )
505                return false;
506
507        $rss->items = array_slice($rss->items, 0, $items);
508
509        if ( 'http://planet.wordpress.org/' == $rss->channel['link'] ) {
510                foreach ( array_keys($rss->items) as $i ) {
511                        list($site, $description) = explode( ':', wp_specialchars($rss->items[$i]['title']), 2 );
512                        $rss->items[$i]['dc']['creator'] = trim($site);
513                        $rss->items[$i]['title'] = trim($description);
514                }
515        }
516
517        echo "<div class='rss-widget'>";
518        wp_widget_rss_output( $rss, $widgets['dashboard_secondary'] );
519        echo "</div>";
520}
521
522function wp_dashboard_plugins() {
523        wp_dashboard_cached_rss_widget( 'dashboard_plugins', 'wp_dashboard_plugins_output', array(
524                'http://wordpress.org/extend/plugins/rss/browse/popular/',
525                'http://wordpress.org/extend/plugins/rss/browse/new/',
526                'http://wordpress.org/extend/plugins/rss/browse/updated/'
527        ) );
528}
529
530/**
531 * Display plugins most popular, newest plugins, and recently updated widget text.
532 *
533 * @since unknown
534 */
535function wp_dashboard_plugins_output() {
536        $popular = @fetch_rss( 'http://wordpress.org/extend/plugins/rss/browse/popular/' );
537        $new     = @fetch_rss( 'http://wordpress.org/extend/plugins/rss/browse/new/' );
538        $updated = @fetch_rss( 'http://wordpress.org/extend/plugins/rss/browse/updated/' );
539
540        foreach ( array( 'popular' => __('Most Popular'), 'new' => __('Newest Plugins'), 'updated' => __('Recently Updated') ) as $feed => $label ) {
541                if ( !isset($$feed->items) || 0 == count($$feed->items) )
542                        continue;
543
544                $$feed->items = array_slice($$feed->items, 0, 5);
545                $item_key = array_rand($$feed->items);
546
547                // Eliminate some common badly formed plugin descriptions
548                while ( ( null !== $item_key = array_rand($$feed->items) ) && false !== strpos( $$feed->items[$item_key]['description'], 'Plugin Name:' ) )
549                        unset($$feed->items[$item_key]);
550
551                if ( !isset($$feed->items[$item_key]) )
552                        continue;
553
554                $item = $$feed->items[$item_key];
555
556                // current bbPress feed item titles are: user on "topic title"
557                if ( preg_match( '/"(.*)"/s', $item['title'], $matches ) )
558                        $title = $matches[1];
559                else // but let's make it forward compatible if things change
560                        $title = $item['title'];
561                $title = wp_specialchars( $title );
562
563                $description = wp_specialchars( strip_tags(html_entity_decode($item['description'], ENT_QUOTES)) );
564
565                list($link, $frag) = explode( '#', $item['link'] );
566
567                $link = clean_url($link);
568                if( preg_match('|/([^/]+?)/?$|', $link, $matches) )
569                        $slug = $matches[1];
570                else
571                        $slug = '';
572
573                $ilink = wp_nonce_url('plugin-install.php?tab=plugin-information&plugin=' . $slug, 'install-plugin_' . $slug) .
574                                                        '&amp;TB_iframe=true&amp;width=600&amp;height=800';
575
576                echo "<h4>$label</h4>\n";
577                echo "<h5><a href='$link'>$title</a></h5>&nbsp;<span>(<a href='$ilink' class='thickbox' title='$title'>" . __( 'Install' ) . "</a>)</span>\n";
578                echo "<p>$description</p>\n";
579        }
580}
581
582/**
583 * Checks to see if all of the feed url in $check_urls are cached.
584 *
585 * If $check_urls is empty, look for the rss feed url found in the dashboard
586 * widget optios of $widget_id. If cached, call $callback, a function that
587 * echoes out output for this widget. If not cache, echo a "Loading..." stub
588 * which is later replaced by AJAX call (see top of /wp-admin/index.php)
589 *
590 * @since unknown
591 *
592 * @param int $widget_id
593 * @param callback $callback
594 * @param array $check_urls RSS feeds
595 * @return bool False on failure. True on success.
596 */
597function wp_dashboard_cached_rss_widget( $widget_id, $callback, $check_urls = array() ) {
598        $loading = '<p class="widget-loading">' . __( 'Loading&#8230;' ) . '</p>';
599
600        if ( empty($check_urls) ) {
601                $widgets = get_option( 'dashboard_widget_options' );
602                if ( empty($widgets[$widget_id]['url']) ) {
603                        echo $loading;
604                        return false;
605                }
606                $check_urls = array( $widgets[$widget_id]['url'] );
607        }
608
609
610        require_once( ABSPATH . WPINC . '/rss.php' );
611        init(); // initialize rss constants
612
613        $cache = new RSSCache( MAGPIE_CACHE_DIR, MAGPIE_CACHE_AGE );
614
615        foreach ( $check_urls as $check_url ) {
616                $status = $cache->check_cache( $check_url );
617                if ( 'HIT' !== $status ) {
618                        echo $loading;
619                        return false;
620                }
621        }
622
623        if ( $callback && is_callable( $callback ) ) {
624                $args = array_slice( func_get_args(), 2 );
625                array_unshift( $args, $widget_id );
626                call_user_func_array( $callback, $args );
627        }
628
629        return true;
630}
631
632/* Dashboard Widgets Controls */
633
634// Calls widget_control callback
635/**
636 * Calls widget control callback.
637 *
638 * @since unknown
639 *
640 * @param int $widget_control_id Registered Widget ID.
641 */
642function wp_dashboard_trigger_widget_control( $widget_control_id = false ) {
643        global $wp_dashboard_control_callbacks;
644       
645        if ( is_scalar($widget_control_id) && $widget_control_id && isset($wp_dashboard_control_callbacks[$widget_control_id]) && is_callable($wp_dashboard_control_callbacks[$widget_control_id]) ) {
646                call_user_func( $wp_dashboard_control_callbacks[$widget_control_id], '', array( 'id' => $widget_control_id, 'callback' => $wp_dashboard_control_callbacks[$widget_control_id] ) );
647        }
648}
649
650/**
651 * The RSS dashboard widget control.
652 *
653 * Sets up $args to be used as input to wp_widget_rss_form(). Handles POST data
654 * from RSS-type widgets.
655 *
656 * @since unknown
657 *
658 * @param string widget_id
659 * @param array form_inputs
660 */
661function wp_dashboard_rss_control( $widget_id, $form_inputs = array() ) {
662        if ( !$widget_options = get_option( 'dashboard_widget_options' ) )
663                $widget_options = array();
664
665        if ( !isset($widget_options[$widget_id]) )
666                $widget_options[$widget_id] = array();
667
668        $number = 1; // Hack to use wp_widget_rss_form()
669        $widget_options[$widget_id]['number'] = $number;
670
671        if ( 'POST' == $_SERVER['REQUEST_METHOD'] && isset($_POST['widget-rss'][$number]) ) {
672                $_POST['widget-rss'][$number] = stripslashes_deep( $_POST['widget-rss'][$number] );
673                $widget_options[$widget_id] = wp_widget_rss_process( $_POST['widget-rss'][$number] );
674                // title is optional.  If black, fill it if possible
675                if ( !$widget_options[$widget_id]['title'] && isset($_POST['widget-rss'][$number]['title']) ) {
676                        require_once(ABSPATH . WPINC . '/rss.php');
677                        $rss = fetch_rss($widget_options[$widget_id]['url']);
678                        $widget_options[$widget_id]['title'] = htmlentities(strip_tags($rss->channel['title']));
679                }
680                update_option( 'dashboard_widget_options', $widget_options );
681        }
682
683        wp_widget_rss_form( $widget_options[$widget_id], $form_inputs );
684}
685
686?>