WordPress.org

Make WordPress Core

Ticket #7403: dashboard.php

File dashboard.php, 21.9 KB (added by radzio, 7 years ago)
Line 
1<?php
2
3// Registers dashboard widgets, handles POST data, sets up filters
4function wp_dashboard_setup() {
5        global $wpdb, $wp_dashboard_sidebars;
6        $update = false;
7        $widget_options = get_option( 'dashboard_widget_options' );
8        if ( !$widget_options || !is_array($widget_options) )
9                $widget_options = array();
10
11
12        /* Register WP Dashboard Dynamic Sidebar */
13        register_sidebar( array(
14                'name' => 'WordPress Dashboard',
15                'id' => 'wp_dashboard',
16                'before_widget' => "\t<div class='dashboard-widget-holder %2\$s' id='%1\$s'>\n\n\t\t<div class='dashboard-widget'>\n\n",
17                'after_widget' => "\t\t</div>\n\n\t</div>\n\n",
18                'before_title' => "\t\t\t<h3 class='dashboard-widget-title'>",
19                'after_title' => "</h3>\n\n"
20        ) );
21
22
23        /* Register Widgets and Controls */
24
25        // Recent Comments Widget
26        $mod_comments = wp_count_comments();
27        $mod_comments = $mod_comments->moderated;
28        if ( current_user_can( 'moderate_comments' ) && $mod_comments ) {
29                $notice = sprintf( __ngettext( '%d comment awaiting moderation', '%d comments awaiting moderation', $mod_comments ), $mod_comments );
30                $notice = "<a href='edit-comments.php?comment_status=moderated'>$notice</a>";
31        } else {
32                $notice = '';
33        }
34        wp_register_sidebar_widget( 'dashboard_recent_comments', __( 'Recent Comments' ), 'wp_dashboard_recent_comments',
35                array( 'all_link' => 'edit-comments.php', 'notice' => $notice, 'width' => 'half' )
36        );
37
38        // Incoming Links Widget
39        if ( !isset( $widget_options['dashboard_incoming_links'] ) || !isset( $widget_options['dashboard_incoming_links']['home'] ) || $widget_options['dashboard_incoming_links']['home'] != get_option('home') ) {
40                $update = true;
41                $widget_options['dashboard_incoming_links'] = array(
42                        'home' => get_option('home'),
43                        'link' => apply_filters( 'dashboard_incoming_links_link', 'http://blogsearch.google.com/blogsearch?hl=en&scoring=d&partner=wordpress&q=link:' . trailingslashit( get_option('home') ) ),
44                        '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') ) ),
45                        'items' => 5,
46                        'show_date' => 0
47                );
48        }
49        wp_register_sidebar_widget( 'dashboard_incoming_links', __( 'Incoming Links' ), 'wp_dashboard_empty',
50                array( 'all_link' => $widget_options['dashboard_incoming_links']['link'], 'feed_link' => $widget_options['dashboard_incoming_links']['url'], 'width' => 'half' ),
51                'wp_dashboard_cached_rss_widget', 'wp_dashboard_incoming_links_output'
52        );
53        wp_register_widget_control( 'dashboard_incoming_links', __( 'Incoming Links' ), 'wp_dashboard_rss_control', array(),
54                array( 'widget_id' => 'dashboard_incoming_links', 'form_inputs' => array( 'title' => false, 'show_summary' => false, 'show_author' => false ) )
55        );
56
57
58        // WP Plugins Widget
59        wp_register_sidebar_widget( 'dashboard_plugins', __( 'Plugins' ), 'wp_dashboard_empty',
60                array( 'all_link' => 'http://wordpress.org/extend/plugins/', 'feed_link' => 'http://wordpress.org/extend/plugins/rss/topics/', 'width' => 'half' ),
61                'wp_dashboard_cached_rss_widget', 'wp_dashboard_plugins_output',
62                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/' )
63        );
64
65        // Primary feed (Dev Blog) Widget
66        if ( !isset( $widget_options['dashboard_primary'] ) ) {
67                $update = true;
68                $widget_options['dashboard_primary'] = array(
69                        'link' => apply_filters( 'dashboard_primary_link',  __( 'http://wordpress.org/development/' ) ),
70                        'url' => apply_filters( 'dashboard_primary_feed',  __( 'http://wordpress.org/development/feed/' ) ),
71                        'title' => apply_filters( 'dashboard_primary_title', __( 'WordPress Development Blog' ) ),
72                        'items' => 2,
73                        'show_summary' => 1,
74                        'show_author' => 0,
75                        'show_date' => 1
76                );
77        }
78        wp_register_sidebar_widget( 'dashboard_primary', $widget_options['dashboard_primary']['title'], 'wp_dashboard_empty',
79                array( 'all_link' => $widget_options['dashboard_primary']['link'], 'feed_link' => $widget_options['dashboard_primary']['url'], 'width' => 'half', 'class' => 'widget_rss' ),
80                'wp_dashboard_cached_rss_widget', 'wp_dashboard_rss_output'
81        );
82        wp_register_widget_control( 'dashboard_primary', __( 'Primary Feed' ), 'wp_dashboard_rss_control', array(),
83                array( 'widget_id' => 'dashboard_primary' )
84        );
85
86
87        // Secondary Feed (Planet) Widget
88        if ( !isset( $widget_options['dashboard_secondary'] ) ) {
89                $update = true;
90                $widget_options['dashboard_secondary'] = array(
91                        'link' => apply_filters( 'dashboard_secondary_link',  __( 'http://planet.wordpress.org/' ) ),
92                        'url' => apply_filters( 'dashboard_secondary_feed',  __( 'http://planet.wordpress.org/feed/' ) ),
93                        'title' => apply_filters( 'dashboard_secondary_title', __( 'Other WordPress News' ) ),
94                        'items' => 15
95                );
96        }
97        wp_register_sidebar_widget( 'dashboard_secondary', $widget_options['dashboard_secondary']['title'], 'wp_dashboard_empty',
98                array( 'all_link' => $widget_options['dashboard_secondary']['link'], 'feed_link' => $widget_options['dashboard_secondary']['url'], 'width' => 'full' ),
99                'wp_dashboard_cached_rss_widget', 'wp_dashboard_secondary_output'
100        );
101        wp_register_widget_control( 'dashboard_secondary', __( 'Secondary Feed' ), 'wp_dashboard_rss_control', array(),
102                array( 'widget_id' => 'dashboard_secondary', 'form_inputs' => array( 'show_summary' => false, 'show_author' => false, 'show_date' => false ) )
103        );
104
105
106                /* Dashboard Widget Template
107                wp_register_sidebar_widget( $widget_id (unique slug) , $widget_title, $output_callback,
108                        array(
109                                'all_link'  => full url for "See All" link,
110                                'feed_link' => full url for "RSS" link,
111                                'width'     => 'fourth', 'third', 'half', 'full' (defaults to 'half'),
112                                'height'    => 'single', 'double' (defaults to 'single'),
113                        ),
114                        $wp_dashboard_empty_callback (only needed if using 'wp_dashboard_empty' as your $output_callback),
115                        $arg, $arg, $arg... (further args passed to callbacks)
116                );
117
118                // optional: if you want users to be able to edit the settings of your widget, you need to register a widget_control
119                wp_register_widget_control( $widget_id, $widget_control_title, $control_output_callback,
120                        array(), // leave an empty array here: oddity in widget code
121                        array(
122                                'widget_id' => $widget_id, // Yes - again.  This is required: oddity in widget code
123                                'arg'       => an arg to pass to the $control_output_callback,
124                                'another'   => another arg to pass to the $control_output_callback,
125                                ...
126                        )
127                );
128                */
129
130        // Hook to register new widgets
131        do_action( 'wp_dashboard_setup' );
132
133        // Hard code the sidebar's widgets and order
134        $dashboard_widgets = array();
135        $dashboard_widgets[] = 'dashboard_recent_comments';
136        $dashboard_widgets[] = 'dashboard_incoming_links';
137        $dashboard_widgets[] = 'dashboard_primary';
138        if ( current_user_can( 'activate_plugins' ) )
139                $dashboard_widgets[] = 'dashboard_plugins';
140        $dashboard_widgets[] = 'dashboard_secondary';
141
142        // Filter widget order
143        $dashboard_widgets = apply_filters( 'wp_dashboard_widgets', $dashboard_widgets );
144
145        $wp_dashboard_sidebars = array( 'wp_dashboard' => $dashboard_widgets, 'array_version' => 3.5 );
146
147        add_filter( 'dynamic_sidebar_params', 'wp_dashboard_dynamic_sidebar_params' );
148
149        if ( 'POST' == $_SERVER['REQUEST_METHOD'] && isset($_POST['widget_id']) ) {
150                ob_start(); // hack - but the same hack wp-admin/widgets.php uses
151                wp_dashboard_trigger_widget_control( $_POST['widget_id'] );
152                ob_end_clean();
153                wp_redirect( remove_query_arg( 'edit' ) );
154                exit;
155        }
156
157        if ( $update )
158                update_option( 'dashboard_widget_options', $widget_options );
159}
160
161// Echoes out the dashboard
162function wp_dashboard() {
163        echo "<div id='dashboard-widgets'>\n\n";
164
165        // We're already filtering dynamic_sidebar_params obove
166        add_filter( 'option_sidebars_widgets', 'wp_dashboard_sidebars_widgets' ); // here there be hackery
167        dynamic_sidebar( 'wp_dashboard' );
168        remove_filter( 'option_sidebars_widgets', 'wp_dashboard_sidebars_widgets' );
169
170        echo "<br class='clear' />\n</div>\n\n\n";
171}
172
173// Makes sidebar_widgets option reflect the dashboard settings
174function wp_dashboard_sidebars_widgets() { // hackery
175        return $GLOBALS['wp_dashboard_sidebars'];
176}
177
178// Modifies sidbar params on the fly to set up ids, class names, titles for each widget (called once per widget)
179// Switches widget to edit mode if $_GET['edit']
180function wp_dashboard_dynamic_sidebar_params( $params ) {
181        global $wp_registered_widgets, $wp_registered_widget_controls;
182
183        $sidebar_defaults = array('widget_id' => 0, 'before_widget' => '', 'after_widget' => '', 'before_title' => '', 'after_title' => '');
184        extract( $sidebar_defaults, EXTR_PREFIX_ALL, 'sidebar' );
185        extract( $params[0], EXTR_PREFIX_ALL, 'sidebar' );
186
187        if ( !isset($wp_registered_widgets[$sidebar_widget_id]) || !is_array($wp_registered_widgets[$sidebar_widget_id]) ) {
188                return $params;
189        }
190        $widget_defaults = array('id' => '', 'width' => '', 'height' => '', 'class' => '', 'feed_link' => '', 'all_link' => '', 'notice' => false, 'error' => false);
191        extract( $widget_defaults, EXTR_PREFIX_ALL, 'widget' );
192        extract( $wp_registered_widgets[$sidebar_widget_id], EXTR_PREFIX_ALL, 'widget' );
193
194        $the_classes = array();
195        if ( in_array($widget_width, array( 'third', 'fourth', 'full' ) ) )
196                $the_classes[] = $widget_width;
197
198        if ( 'double' == $widget_height )
199                $the_classes[] = 'double';
200
201        if ( $widget_class )
202                $the_classes[] = $widget_class;
203
204        // Add classes to the widget holder
205        if ( $the_classes )
206                $sidebar_before_widget = str_replace( "<div class='dashboard-widget-holder ", "<div class='dashboard-widget-holder " . join( ' ', $the_classes ) . ' ', $sidebar_before_widget );
207
208        $links = array();
209        if ( $widget_all_link )
210                $links[] = '<a href="' . clean_url( $widget_all_link ) . '">' . __( 'See&nbsp;All' ) . '</a>';
211
212        $content_class = 'dashboard-widget-content';
213        if ( current_user_can( 'edit_dashboard' ) && isset($wp_registered_widget_controls[$widget_id]) && is_callable($wp_registered_widget_controls[$widget_id]['callback']) ) {
214                // Switch this widget to edit mode
215                if ( isset($_GET['edit']) && $_GET['edit'] == $widget_id ) {
216                        $content_class .= ' dashboard-widget-control';
217                        $wp_registered_widgets[$widget_id]['callback'] = 'wp_dashboard_empty';
218                        $sidebar_widget_name = $wp_registered_widget_controls[$widget_id]['name'];
219                        $params[1] = 'wp_dashboard_trigger_widget_control';
220                        $sidebar_before_widget .= '<form action="' . clean_url(remove_query_arg( 'edit' ))  . '" method="post">';
221                        $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";
222                        $links[] = '<a href="' . clean_url(remove_query_arg( 'edit' )) . '">' . __( 'Cancel' ) . '</a>';
223                } else {
224                        $links[] = '<a href="' . clean_url(add_query_arg( 'edit', $widget_id )) . "#$widget_id" . '">' . __( 'Edit' ) . '</a>';
225                }
226        }
227
228        if ( $widget_feed_link )
229                $links[] = '<img class="rss-icon" src="' . includes_url('images/rss.png') . '" alt="' . __( 'rss icon' ) . '" /> <a href="' . clean_url( $widget_feed_link ) . '">' . __( 'RSS' ) . '</a>';
230
231        $links = apply_filters( "wp_dashboard_widget_links_$widget_id", $links );
232
233        // Add links to widget's title bar
234        if ( $links ) {
235                $sidebar_before_title .= '<span>';
236                $sidebar_after_title   = '</span><small>' . join( '&nbsp;|&nbsp;', $links ) . "</small><br class='clear' />$sidebar_after_title";
237        }
238
239        // Could have put this in widget-content.  Doesn't really matter
240        if ( $widget_notice )
241                $sidebar_after_title .= "\t\t\t<div class='dashboard-widget-notice'>$widget_notice</div>\n\n";
242
243        if ( $widget_error )
244                $sidebar_after_title .= "\t\t\t<div class='dashboard-widget-error'>$widget_error</div>\n\n";
245
246        $sidebar_after_title .= "\t\t\t<div class='$content_class'>\n\n";
247
248        $sidebar_after_widget .= "\t\t\t</div>\n\n";
249
250        foreach( array_keys( $params[0] ) as $key )
251                $$key = ${'sidebar_' . $key};
252
253        $params[0] = compact( array_keys( $params[0] ) );
254
255        return $params;
256}
257
258
259/* Dashboard Widgets */
260
261function wp_dashboard_recent_comments( $sidebar_args ) {
262        global $comment;
263        extract( $sidebar_args, EXTR_SKIP );
264
265        echo $before_widget;
266
267        echo $before_title;
268        echo $widget_name;
269        echo $after_title;
270
271        $lambda = create_function( '', 'return 5;' );
272        add_filter( 'option_posts_per_rss', $lambda ); // hack - comments query doesn't accept per_page parameter
273        $comments_query = new WP_Query(array('feed' => 'rss2', 'withcomments' => 1));
274        remove_filter( 'option_posts_per_rss', $lambda );
275
276        $is_first = true;
277
278        if ( $comments_query->have_comments() ) {
279                while ( $comments_query->have_comments() ) { $comments_query->the_comment();
280
281                        $comment_post_url = get_permalink( $comment->comment_post_ID );
282                        $comment_post_title = get_the_title( $comment->comment_post_ID );
283                        $comment_post_link = "<a href='$comment_post_url'>$comment_post_title</a>";
284                        $comment_link = '<a class="comment-link" href="' . get_comment_link() . '">#</a>';
285                        $comment_meta = sprintf( __( 'From <strong>%1$s</strong> on %2$s %3$s' ), get_comment_author(), $comment_post_link, $comment_link );
286
287                        if ( $is_first ) : $is_first = false;
288?>
289                                <blockquote><p>&#8220;<?php comment_excerpt(); ?>&#8221;</p></blockquote>
290                                <p class='comment-meta'><?php echo $comment_meta; ?></p>
291<?php
292                                if ( $comments_query->comment_count > 1 ) : ?>
293                                <ul id="dashboard-comments-list">
294<?php
295                                endif; // comment_count
296                        else : // is_first
297?>
298
299                                        <li class='comment-meta'><?php echo $comment_meta; ?></li>
300<?php
301                        endif; // is_first
302                }
303
304                if ( $comments_query->comment_count > 1 ) : ?>
305                                </ul>
306<?php
307                endif; // comment_count;
308
309        }
310
311        echo $after_widget;
312}
313
314// $sidebar_args are handled by wp_dashboard_empty()
315function wp_dashboard_incoming_links_output() {
316        $widgets = get_option( 'dashboard_widget_options' );
317        @extract( @$widgets['dashboard_incoming_links'], EXTR_SKIP );
318        $rss = @fetch_rss( $url );
319        if ( isset($rss->items) && 0 < count($rss->items) )  {
320
321                echo "<ul>\n";
322
323                $rss->items = array_slice($rss->items, 0, $items);
324                foreach ( $rss->items as $item ) {
325                        $publisher = '';
326                        $site_link = '';
327                        $link = '';
328                        $content = '';
329                        $date = '';
330                        $link = clean_url( strip_tags( $item['link'] ) );
331
332                        if ( isset( $item['author_uri'] ) )
333                                $site_link = clean_url( strip_tags( $item['author_uri'] ) );
334
335                        if ( !$publisher = wp_specialchars( strip_tags( isset($item['dc']['publisher']) ? $item['dc']['publisher'] : $item['author_name'] ) ) )
336                                $publisher = __( 'Somebody' );
337                        if ( $site_link )
338                                $publisher = "<a href='$site_link'>$publisher</a>";
339                        else
340                                $publisher = "<strong>$publisher</strong>";
341
342                        if ( isset($item['description']) )
343                                $content = $item['description'];
344                        elseif ( isset($item['summary']) )
345                                $content = $item['summary'];
346                        elseif ( isset($item['atom_content']) )
347                                $content = $item['atom_content'];
348                        else
349                                $content = __( 'something' );
350                        $content = wp_html_excerpt($content, 50) . ' ...';
351                        if ( $link )
352                                $text = _c( '%1$s linked here <a href="%2$s">saying</a>, "%3$s"|feed_display' );
353                        else
354                                $text = _c( '%1$s linked here saying, "%3$s"|feed_display' );
355
356                        if ( $show_date ) {
357                                if ( $show_author || $show_summary )
358                                        $text .= _c( ' on %4$s|feed_display' );
359                                $date = wp_specialchars( strip_tags( isset($item['pubdate']) ? $item['pubdate'] : $item['published'] ) );
360                                $date = strtotime( $date );
361                                $date = gmdate( get_option( 'date_format' ), $date );
362                        }
363
364                        echo "\t<li>" . sprintf( _c( "$text|feed_display" ), $publisher, $link, $content, $date ) . "</li>\n";
365                }
366
367                echo "</ul>\n";
368
369        } else {
370                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";
371        }
372}
373
374// $sidebar_args are handled by wp_dashboard_empty()
375function wp_dashboard_rss_output( $widget_id ) {
376        $widgets = get_option( 'dashboard_widget_options' );
377        wp_widget_rss_output( $widgets[$widget_id] );
378}
379
380// $sidebar_args are handled by wp_dashboard_empty()
381function wp_dashboard_secondary_output() {
382        $widgets = get_option( 'dashboard_widget_options' );
383        @extract( @$widgets['dashboard_secondary'], EXTR_SKIP );
384        $rss = @fetch_rss( $url );
385        if ( !isset($rss->items) || 0 == count($rss->items) )
386                return false;
387
388        echo "<ul id='planetnews'>\n";
389
390        $rss->items = array_slice($rss->items, 0, $items);
391        foreach ($rss->items as $item ) {
392                $title = wp_specialchars($item['title']);
393                list($author,$post) = explode( ':', $title, 2 );
394                $link = clean_url($item['link']);
395
396                #echo "\t<li><a href='$link'><span class='post'>$post</span><span class='hidden'> - </span><cite>$author</cite></a></li>\n";
397                echo "\t<li><a href='$link'><span class='post'>$title</span> <span class='hidden'> - </span> <span class='hidden'> - </span><cite>$author</cite></a></li>\n";
398       
399        }
400
401        echo "</ul>\n<br class='clear' />\n";
402}
403
404// $sidebar_args are handled by wp_dashboard_empty()
405function wp_dashboard_plugins_output() {
406        $popular = @fetch_rss( 'http://wordpress.org/extend/plugins/rss/browse/popular/' );
407        $new     = @fetch_rss( 'http://wordpress.org/extend/plugins/rss/browse/new/' );
408        $updated = @fetch_rss( 'http://wordpress.org/extend/plugins/rss/browse/updated/' );
409
410        foreach ( array( 'popular' => __('Most Popular'), 'new' => __('Newest Plugins'), 'updated' => __('Recently Updated') ) as $feed => $label ) {
411                if ( !isset($$feed->items) || 0 == count($$feed->items) )
412                        continue;
413
414                $$feed->items = array_slice($$feed->items, 0, 5);
415                $item_key = array_rand($$feed->items);
416
417                // Eliminate some common badly formed plugin descriptions
418                while ( ( null !== $item_key = array_rand($$feed->items) ) && false !== strpos( $$feed->items[$item_key]['description'], 'Plugin Name:' ) )
419                        unset($$feed->items[$item_key]);
420
421                if ( !isset($$feed->items[$item_key]) )
422                        continue;
423
424                $item = $$feed->items[$item_key];
425
426                // current bbPress feed item titles are: user on "topic title"
427                if ( preg_match( '/"(.*)"/s', $item['title'], $matches ) )
428                        $title = $matches[1];
429                else // but let's make it forward compatible if things change
430                        $title = $item['title'];
431                $title = wp_specialchars( $title );
432
433                $description = wp_specialchars( strip_tags(html_entity_decode($item['description'], ENT_QUOTES)) );
434
435                list($link, $frag) = explode( '#', $item['link'] );
436
437                $link = clean_url($link);
438                $dlink = rtrim($link, '/') . '/download/';
439
440                echo "<h4>$label</h4>\n";
441                echo "<h5><a href='$link'>$title</a></h5>&nbsp;<span>(<a href='$dlink'>" . __( 'Download' ) . "</a>)</span>\n";
442                echo "<p>$description</p>\n";
443        }
444}
445
446// Checks to see if all of the feed url in $check_urls are cached.
447// If $check_urls is empty, look for the rss feed url found in the dashboard widget optios of $widget_id.
448// If cached, call $callback, a function that echoes out output for this widget.
449// If not cache, echo a "Loading..." stub which is later replaced by AJAX call (see top of /wp-admin/index.php)
450function wp_dashboard_cached_rss_widget( $widget_id, $callback, $check_urls = array() ) {
451        $loading = '<p class="widget-loading">' . __( 'Loading&#8230;' ) . '</p>';
452
453        if ( empty($check_urls) ) {
454                $widgets = get_option( 'dashboard_widget_options' );
455                if ( empty($widgets[$widget_id]['url']) ) {
456                        echo $loading;
457                        return false;
458                }
459                $check_urls = array( $widgets[$widget_id]['url'] );
460        }
461
462
463        require_once( ABSPATH . WPINC . '/rss.php' );
464        init(); // initialize rss constants
465
466        $cache = new RSSCache( MAGPIE_CACHE_DIR, MAGPIE_CACHE_AGE );
467
468        foreach ( $check_urls as $check_url ) {
469                $status = $cache->check_cache( $check_url );
470                if ( 'HIT' !== $status ) {
471                        echo $loading;
472                        return false;
473                }
474        }
475
476        if ( $callback && is_callable( $callback ) ) {
477                $args = array_slice( func_get_args(), 2 );
478                array_unshift( $args, $widget_id );
479                call_user_func_array( $callback, $args );
480        }
481
482        return true;
483}
484
485// Empty widget used for JS/AJAX created output.
486// Callback inserts content between before_widget and after_widget.  Used when widget is in edit mode.  Can also be used for custom widgets.
487function wp_dashboard_empty( $sidebar_args, $callback = false ) {
488        extract( $sidebar_args, EXTR_SKIP );
489
490        echo $before_widget;
491
492        echo $before_title;
493        echo $widget_name;
494        echo $after_title;
495
496        // When in edit mode, the callback passed to this function is the widget_control callback
497        if ( $callback && is_callable( $callback ) ) {
498                $args = array_slice( func_get_args(), 2 );
499                array_unshift( $args, $widget_id );
500                call_user_func_array( $callback, $args );
501        }
502
503        echo $after_widget;
504}
505
506/* Dashboard Widgets Controls. Ssee also wp_dashboard_empty() */
507
508// Calls widget_control callback
509function wp_dashboard_trigger_widget_control( $widget_control_id = false ) {
510        global $wp_registered_widget_controls;
511        if ( is_scalar($widget_control_id) && $widget_control_id && isset($wp_registered_widget_controls[$widget_control_id]) && is_callable($wp_registered_widget_controls[$widget_control_id]['callback']) )
512                call_user_func_array( $wp_registered_widget_controls[$widget_control_id]['callback'], $wp_registered_widget_controls[$widget_control_id]['params'] );
513}
514
515// Sets up $args to be used as input to wp_widget_rss_form(), handles POST data from RSS-type widgets
516function wp_dashboard_rss_control( $args ) {
517        extract( $args );
518        if ( !$widget_id )
519                return false;
520
521        if ( !$widget_options = get_option( 'dashboard_widget_options' ) )
522                $widget_options = array();
523
524        if ( !isset($widget_options[$widget_id]) )
525                $widget_options[$widget_id] = array();
526
527        $number = 1; // Hack to use wp_widget_rss_form()
528        $widget_options[$widget_id]['number'] = $number;
529
530        if ( 'POST' == $_SERVER['REQUEST_METHOD'] && isset($_POST['widget-rss'][$number]) ) {
531                $_POST['widget-rss'][$number] = stripslashes_deep( $_POST['widget-rss'][$number] );
532                $widget_options[$widget_id] = wp_widget_rss_process( $_POST['widget-rss'][$number] );
533                // title is optional.  If black, fill it if possible
534                if ( !$widget_options[$widget_id]['title'] && isset($_POST['widget-rss'][$number]['title']) ) {
535                        require_once(ABSPATH . WPINC . '/rss.php');
536                        $rss = fetch_rss($widget_options[$widget_id]['url']);
537                        $widget_options[$widget_id]['title'] = htmlentities(strip_tags($rss->channel['title']));
538                }
539                update_option( 'dashboard_widget_options', $widget_options );
540        }
541
542        wp_widget_rss_form( $widget_options[$widget_id], $form_inputs );
543}
544
545?>