PageRenderTime 58ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/wp-admin/includes/dashboard.php

https://bitbucket.org/aqge/deptandashboard
PHP | 1363 lines | 982 code | 214 blank | 167 comment | 216 complexity | 67dd8395366e4da60678cc978355917c MD5 | raw file
Possible License(s): AGPL-1.0, GPL-2.0, LGPL-2.1
  1. <?php
  2. /**
  3. * WordPress Dashboard Widget Administration Screen API
  4. *
  5. * @package WordPress
  6. * @subpackage Administration
  7. */
  8. /**
  9. * Registers dashboard widgets.
  10. *
  11. * Handles POST data, sets up filters.
  12. *
  13. * @since 2.5.0
  14. */
  15. function wp_dashboard_setup() {
  16. global $wp_registered_widgets, $wp_registered_widget_controls, $wp_dashboard_control_callbacks;
  17. $wp_dashboard_control_callbacks = array();
  18. $screen = get_current_screen();
  19. $update = false;
  20. $widget_options = get_option( 'dashboard_widget_options' );
  21. if ( !$widget_options || !is_array($widget_options) )
  22. $widget_options = array();
  23. /* Register Widgets and Controls */
  24. $response = wp_check_browser_version();
  25. if ( $response && $response['upgrade'] ) {
  26. add_filter( 'postbox_classes_dashboard_dashboard_browser_nag', 'dashboard_browser_nag_class' );
  27. if ( $response['insecure'] )
  28. wp_add_dashboard_widget( 'dashboard_browser_nag', __( 'You are using an insecure browser!' ), 'wp_dashboard_browser_nag' );
  29. else
  30. wp_add_dashboard_widget( 'dashboard_browser_nag', __( 'Your browser is out of date!' ), 'wp_dashboard_browser_nag' );
  31. }
  32. // Right Now
  33. if ( is_blog_admin() && current_user_can('edit_posts') )
  34. wp_add_dashboard_widget( 'dashboard_right_now', __( 'Right Now' ), 'wp_dashboard_right_now' );
  35. if ( is_network_admin() )
  36. wp_add_dashboard_widget( 'network_dashboard_right_now', __( 'Right Now' ), 'wp_network_dashboard_right_now' );
  37. // Recent Comments Widget
  38. if ( is_blog_admin() && current_user_can('moderate_comments') ) {
  39. if ( !isset( $widget_options['dashboard_recent_comments'] ) || !isset( $widget_options['dashboard_recent_comments']['items'] ) ) {
  40. $update = true;
  41. $widget_options['dashboard_recent_comments'] = array(
  42. 'items' => 5,
  43. );
  44. }
  45. $recent_comments_title = __( 'Recent Comments' );
  46. wp_add_dashboard_widget( 'dashboard_recent_comments', $recent_comments_title, 'wp_dashboard_recent_comments', 'wp_dashboard_recent_comments_control' );
  47. }
  48. // Incoming Links Widget
  49. if ( is_blog_admin() && current_user_can('publish_posts') ) {
  50. if ( !isset( $widget_options['dashboard_incoming_links'] ) || !isset( $widget_options['dashboard_incoming_links']['home'] ) || $widget_options['dashboard_incoming_links']['home'] != get_option('home') ) {
  51. $update = true;
  52. $num_items = isset($widget_options['dashboard_incoming_links']['items']) ? $widget_options['dashboard_incoming_links']['items'] : 10;
  53. $widget_options['dashboard_incoming_links'] = array(
  54. 'home' => get_option('home'),
  55. 'link' => apply_filters( 'dashboard_incoming_links_link', 'http://blogsearch.google.com/blogsearch?scoring=d&partner=wordpress&q=link:' . trailingslashit( get_option('home') ) ),
  56. 'url' => isset($widget_options['dashboard_incoming_links']['url']) ? apply_filters( 'dashboard_incoming_links_feed', $widget_options['dashboard_incoming_links']['url'] ) : apply_filters( 'dashboard_incoming_links_feed', 'http://blogsearch.google.com/blogsearch_feeds?scoring=d&ie=utf-8&num=' . $num_items . '&output=rss&partner=wordpress&q=link:' . trailingslashit( get_option('home') ) ),
  57. 'items' => $num_items,
  58. 'show_date' => isset($widget_options['dashboard_incoming_links']['show_date']) ? $widget_options['dashboard_incoming_links']['show_date'] : false
  59. );
  60. }
  61. wp_add_dashboard_widget( 'dashboard_incoming_links', __( 'Incoming Links' ), 'wp_dashboard_incoming_links', 'wp_dashboard_incoming_links_control' );
  62. }
  63. // WP Plugins Widget
  64. if ( ( ! is_multisite() && is_blog_admin() && current_user_can( 'install_plugins' ) ) || ( is_network_admin() && current_user_can( 'manage_network_plugins' ) && current_user_can( 'install_plugins' ) ) )
  65. wp_add_dashboard_widget( 'dashboard_plugins', __( 'Plugins' ), 'wp_dashboard_plugins' );
  66. // QuickPress Widget
  67. if ( is_blog_admin() && current_user_can('edit_posts') )
  68. wp_add_dashboard_widget( 'dashboard_quick_press', __( 'QuickPress' ), 'wp_dashboard_quick_press' );
  69. // Recent Drafts
  70. if ( is_blog_admin() && current_user_can('edit_posts') )
  71. wp_add_dashboard_widget( 'dashboard_recent_drafts', __('Recent Drafts'), 'wp_dashboard_recent_drafts' );
  72. // Primary feed (Dev Blog) Widget
  73. if ( !isset( $widget_options['dashboard_primary'] ) ) {
  74. $update = true;
  75. $widget_options['dashboard_primary'] = array(
  76. 'link' => apply_filters( 'dashboard_primary_link', __( 'http://wordpress.org/news/' ) ),
  77. 'url' => apply_filters( 'dashboard_primary_feed', __( 'http://wordpress.org/news/feed/' ) ),
  78. 'title' => apply_filters( 'dashboard_primary_title', __( 'WordPress Blog' ) ),
  79. 'items' => 2,
  80. 'show_summary' => 1,
  81. 'show_author' => 0,
  82. 'show_date' => 1,
  83. );
  84. }
  85. wp_add_dashboard_widget( 'dashboard_primary', $widget_options['dashboard_primary']['title'], 'wp_dashboard_primary', 'wp_dashboard_primary_control' );
  86. // Secondary Feed (Planet) Widget
  87. if ( !isset( $widget_options['dashboard_secondary'] ) ) {
  88. $update = true;
  89. $widget_options['dashboard_secondary'] = array(
  90. 'link' => apply_filters( 'dashboard_secondary_link', __( 'http://planet.wordpress.org/' ) ),
  91. 'url' => apply_filters( 'dashboard_secondary_feed', __( 'http://planet.wordpress.org/feed/' ) ),
  92. 'title' => apply_filters( 'dashboard_secondary_title', __( 'Other WordPress News' ) ),
  93. 'items' => 5,
  94. 'show_summary' => 0,
  95. 'show_author' => 0,
  96. 'show_date' => 0,
  97. );
  98. }
  99. wp_add_dashboard_widget( 'dashboard_secondary', $widget_options['dashboard_secondary']['title'], 'wp_dashboard_secondary', 'wp_dashboard_secondary_control' );
  100. // Hook to register new widgets
  101. // Filter widget order
  102. if ( is_network_admin() ) {
  103. do_action( 'wp_network_dashboard_setup' );
  104. $dashboard_widgets = apply_filters( 'wp_network_dashboard_widgets', array() );
  105. } elseif ( is_user_admin() ) {
  106. do_action( 'wp_user_dashboard_setup' );
  107. $dashboard_widgets = apply_filters( 'wp_user_dashboard_widgets', array() );
  108. } else {
  109. do_action( 'wp_dashboard_setup' );
  110. $dashboard_widgets = apply_filters( 'wp_dashboard_widgets', array() );
  111. }
  112. foreach ( $dashboard_widgets as $widget_id ) {
  113. $name = empty( $wp_registered_widgets[$widget_id]['all_link'] ) ? $wp_registered_widgets[$widget_id]['name'] : $wp_registered_widgets[$widget_id]['name'] . " <a href='{$wp_registered_widgets[$widget_id]['all_link']}' class='edit-box open-box'>" . __('View all') . '</a>';
  114. wp_add_dashboard_widget( $widget_id, $name, $wp_registered_widgets[$widget_id]['callback'], $wp_registered_widget_controls[$widget_id]['callback'] );
  115. }
  116. if ( 'POST' == $_SERVER['REQUEST_METHOD'] && isset($_POST['widget_id']) ) {
  117. ob_start(); // hack - but the same hack wp-admin/widgets.php uses
  118. wp_dashboard_trigger_widget_control( $_POST['widget_id'] );
  119. ob_end_clean();
  120. wp_redirect( remove_query_arg( 'edit' ) );
  121. exit;
  122. }
  123. if ( $update )
  124. update_option( 'dashboard_widget_options', $widget_options );
  125. do_action('do_meta_boxes', $screen->id, 'normal', '');
  126. do_action('do_meta_boxes', $screen->id, 'side', '');
  127. }
  128. function wp_add_dashboard_widget( $widget_id, $widget_name, $callback, $control_callback = null ) {
  129. $screen = get_current_screen();
  130. global $wp_dashboard_control_callbacks;
  131. if ( $control_callback && current_user_can( 'edit_dashboard' ) && is_callable( $control_callback ) ) {
  132. $wp_dashboard_control_callbacks[$widget_id] = $control_callback;
  133. if ( isset( $_GET['edit'] ) && $widget_id == $_GET['edit'] ) {
  134. list($url) = explode( '#', add_query_arg( 'edit', false ), 2 );
  135. $widget_name .= ' <span class="postbox-title-action"><a href="' . esc_url( $url ) . '">' . __( 'Cancel' ) . '</a></span>';
  136. $callback = '_wp_dashboard_control_callback';
  137. } else {
  138. list($url) = explode( '#', add_query_arg( 'edit', $widget_id ), 2 );
  139. $widget_name .= ' <span class="postbox-title-action"><a href="' . esc_url( "$url#$widget_id" ) . '" class="edit-box open-box">' . __( 'Configure' ) . '</a></span>';
  140. }
  141. }
  142. if ( is_blog_admin () )
  143. $side_widgets = array('dashboard_quick_press', 'dashboard_recent_drafts', 'dashboard_primary', 'dashboard_secondary');
  144. else if (is_network_admin() )
  145. $side_widgets = array('dashboard_primary', 'dashboard_secondary');
  146. else
  147. $side_widgets = array();
  148. $location = 'normal';
  149. if ( in_array($widget_id, $side_widgets) )
  150. $location = 'side';
  151. $priority = 'core';
  152. if ( 'dashboard_browser_nag' === $widget_id )
  153. $priority = 'high';
  154. add_meta_box( $widget_id, $widget_name, $callback, $screen, $location, $priority );
  155. }
  156. function _wp_dashboard_control_callback( $dashboard, $meta_box ) {
  157. echo '<form action="" method="post" class="dashboard-widget-control-form">';
  158. wp_dashboard_trigger_widget_control( $meta_box['id'] );
  159. echo '<input type="hidden" name="widget_id" value="' . esc_attr($meta_box['id']) . '" />';
  160. submit_button( __('Submit') );
  161. echo '</form>';
  162. }
  163. /**
  164. * Displays the dashboard.
  165. *
  166. * @since 2.5.0
  167. */
  168. function wp_dashboard() {
  169. global $screen_layout_columns;
  170. $screen = get_current_screen();
  171. $hide2 = $hide3 = $hide4 = '';
  172. switch ( $screen_layout_columns ) {
  173. case 4:
  174. $width = 'width:25%;';
  175. break;
  176. case 3:
  177. $width = 'width:33.333333%;';
  178. $hide4 = 'display:none;';
  179. break;
  180. case 2:
  181. $width = 'width:50%;';
  182. $hide3 = $hide4 = 'display:none;';
  183. break;
  184. default:
  185. $width = 'width:100%;';
  186. $hide2 = $hide3 = $hide4 = 'display:none;';
  187. }
  188. ?>
  189. <div id="dashboard-widgets" class="metabox-holder">
  190. <?php
  191. echo "\t<div id='postbox-container-1' class='postbox-container' style='$width'>\n";
  192. do_meta_boxes( $screen->id, 'normal', '' );
  193. echo "\t</div><div id='postbox-container-2' class='postbox-container' style='{$hide2}$width'>\n";
  194. do_meta_boxes( $screen->id, 'side', '' );
  195. echo "\t</div><div id='postbox-container-3' class='postbox-container' style='{$hide3}$width'>\n";
  196. do_meta_boxes( $screen->id, 'column3', '' );
  197. echo "\t</div><div id='postbox-container-4' class='postbox-container' style='{$hide4}$width'>\n";
  198. do_meta_boxes( $screen->id, 'column4', '' );
  199. ?>
  200. </div></div>
  201. <form style="display:none" method="get" action="">
  202. <p>
  203. <?php
  204. wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false );
  205. wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false );
  206. ?>
  207. </p>
  208. </form>
  209. <?php
  210. }
  211. /* Dashboard Widgets */
  212. function wp_dashboard_right_now() {
  213. global $wp_registered_sidebars;
  214. $num_posts = wp_count_posts( 'post' );
  215. $num_pages = wp_count_posts( 'page' );
  216. $num_cats = wp_count_terms('category');
  217. $num_tags = wp_count_terms('post_tag');
  218. $num_comm = wp_count_comments( );
  219. echo "\n\t".'<div class="table table_content">';
  220. echo "\n\t".'<p class="sub">' . __('Content') . '</p>'."\n\t".'<table>';
  221. echo "\n\t".'<tr class="first">';
  222. // Posts
  223. $num = number_format_i18n( $num_posts->publish );
  224. $text = _n( 'Post', 'Posts', intval($num_posts->publish) );
  225. if ( current_user_can( 'edit_posts' ) ) {
  226. $num = "<a href='edit.php'>$num</a>";
  227. $text = "<a href='edit.php'>$text</a>";
  228. }
  229. echo '<td class="first b b-posts">' . $num . '</td>';
  230. echo '<td class="t posts">' . $text . '</td>';
  231. echo '</tr><tr>';
  232. /* TODO: Show status breakdown on hover
  233. if ( $can_edit_pages && !empty($num_pages->publish) ) { // how many pages is not exposed in feeds. Don't show if !current_user_can
  234. $post_type_texts[] = '<a href="edit-pages.php">'.sprintf( _n( '%s page', '%s pages', $num_pages->publish ), number_format_i18n( $num_pages->publish ) ).'</a>';
  235. }
  236. if ( $can_edit_posts && !empty($num_posts->draft) ) {
  237. $post_type_texts[] = '<a href="edit.php?post_status=draft">'.sprintf( _n( '%s draft', '%s drafts', $num_posts->draft ), number_format_i18n( $num_posts->draft ) ).'</a>';
  238. }
  239. if ( $can_edit_posts && !empty($num_posts->future) ) {
  240. $post_type_texts[] = '<a href="edit.php?post_status=future">'.sprintf( _n( '%s scheduled post', '%s scheduled posts', $num_posts->future ), number_format_i18n( $num_posts->future ) ).'</a>';
  241. }
  242. if ( current_user_can('publish_posts') && !empty($num_posts->pending) ) {
  243. $pending_text = sprintf( _n( 'There is <a href="%1$s">%2$s post</a> pending your review.', 'There are <a href="%1$s">%2$s posts</a> pending your review.', $num_posts->pending ), 'edit.php?post_status=pending', number_format_i18n( $num_posts->pending ) );
  244. } else {
  245. $pending_text = '';
  246. }
  247. */
  248. // Pages
  249. $num = number_format_i18n( $num_pages->publish );
  250. $text = _n( 'Page', 'Pages', $num_pages->publish );
  251. if ( current_user_can( 'edit_pages' ) ) {
  252. $num = "<a href='edit.php?post_type=page'>$num</a>";
  253. $text = "<a href='edit.php?post_type=page'>$text</a>";
  254. }
  255. echo '<td class="first b b_pages">' . $num . '</td>';
  256. echo '<td class="t pages">' . $text . '</td>';
  257. echo '</tr><tr>';
  258. // Categories
  259. $num = number_format_i18n( $num_cats );
  260. $text = _n( 'Category', 'Categories', $num_cats );
  261. if ( current_user_can( 'manage_categories' ) ) {
  262. $num = "<a href='edit-tags.php?taxonomy=category'>$num</a>";
  263. $text = "<a href='edit-tags.php?taxonomy=category'>$text</a>";
  264. }
  265. echo '<td class="first b b-cats">' . $num . '</td>';
  266. echo '<td class="t cats">' . $text . '</td>';
  267. echo '</tr><tr>';
  268. // Tags
  269. $num = number_format_i18n( $num_tags );
  270. $text = _n( 'Tag', 'Tags', $num_tags );
  271. if ( current_user_can( 'manage_categories' ) ) {
  272. $num = "<a href='edit-tags.php'>$num</a>";
  273. $text = "<a href='edit-tags.php'>$text</a>";
  274. }
  275. echo '<td class="first b b-tags">' . $num . '</td>';
  276. echo '<td class="t tags">' . $text . '</td>';
  277. echo "</tr>";
  278. do_action('right_now_content_table_end');
  279. echo "\n\t</table>\n\t</div>";
  280. echo "\n\t".'<div class="table table_discussion">';
  281. echo "\n\t".'<p class="sub">' . __('Discussion') . '</p>'."\n\t".'<table>';
  282. echo "\n\t".'<tr class="first">';
  283. // Total Comments
  284. $num = '<span class="total-count">' . number_format_i18n($num_comm->total_comments) . '</span>';
  285. $text = _n( 'Comment', 'Comments', $num_comm->total_comments );
  286. if ( current_user_can( 'moderate_comments' ) ) {
  287. $num = '<a href="edit-comments.php">' . $num . '</a>';
  288. $text = '<a href="edit-comments.php">' . $text . '</a>';
  289. }
  290. echo '<td class="b b-comments">' . $num . '</td>';
  291. echo '<td class="last t comments">' . $text . '</td>';
  292. echo '</tr><tr>';
  293. // Approved Comments
  294. $num = '<span class="approved-count">' . number_format_i18n($num_comm->approved) . '</span>';
  295. $text = _nx( 'Approved', 'Approved', $num_comm->approved, 'Right Now' );
  296. if ( current_user_can( 'moderate_comments' ) ) {
  297. $num = "<a href='edit-comments.php?comment_status=approved'>$num</a>";
  298. $text = "<a class='approved' href='edit-comments.php?comment_status=approved'>$text</a>";
  299. }
  300. echo '<td class="b b_approved">' . $num . '</td>';
  301. echo '<td class="last t">' . $text . '</td>';
  302. echo "</tr>\n\t<tr>";
  303. // Pending Comments
  304. $num = '<span class="pending-count">' . number_format_i18n($num_comm->moderated) . '</span>';
  305. $text = _n( 'Pending', 'Pending', $num_comm->moderated );
  306. if ( current_user_can( 'moderate_comments' ) ) {
  307. $num = "<a href='edit-comments.php?comment_status=moderated'>$num</a>";
  308. $text = "<a class='waiting' href='edit-comments.php?comment_status=moderated'>$text</a>";
  309. }
  310. echo '<td class="b b-waiting">' . $num . '</td>';
  311. echo '<td class="last t">' . $text . '</td>';
  312. echo "</tr>\n\t<tr>";
  313. // Spam Comments
  314. $num = number_format_i18n($num_comm->spam);
  315. $text = _nx( 'Spam', 'Spam', $num_comm->spam, 'comment' );
  316. if ( current_user_can( 'moderate_comments' ) ) {
  317. $num = "<a href='edit-comments.php?comment_status=spam'><span class='spam-count'>$num</span></a>";
  318. $text = "<a class='spam' href='edit-comments.php?comment_status=spam'>$text</a>";
  319. }
  320. echo '<td class="b b-spam">' . $num . '</td>';
  321. echo '<td class="last t">' . $text . '</td>';
  322. echo "</tr>";
  323. do_action('right_now_table_end');
  324. do_action('right_now_discussion_table_end');
  325. echo "\n\t</table>\n\t</div>";
  326. echo "\n\t".'<div class="versions">';
  327. $ct = current_theme_info();
  328. echo "\n\t<p>";
  329. if ( empty( $ct->stylesheet_dir ) ) {
  330. if ( ! is_multisite() || is_super_admin() )
  331. echo '<span class="error-message">' . __('ERROR: The themes directory is either empty or doesn&#8217;t exist. Please check your installation.') . '</span>';
  332. } elseif ( ! empty($wp_registered_sidebars) ) {
  333. $sidebars_widgets = wp_get_sidebars_widgets();
  334. $num_widgets = 0;
  335. foreach ( (array) $sidebars_widgets as $k => $v ) {
  336. if ( 'wp_inactive_widgets' == $k || 'orphaned_widgets' == substr( $k, 0, 16 ) )
  337. continue;
  338. if ( is_array($v) )
  339. $num_widgets = $num_widgets + count($v);
  340. }
  341. $num = number_format_i18n( $num_widgets );
  342. $switch_themes = $ct->title;
  343. if ( current_user_can( 'switch_themes') )
  344. $switch_themes = '<a href="themes.php">' . $switch_themes . '</a>';
  345. if ( current_user_can( 'edit_theme_options' ) ) {
  346. printf(_n('Theme <span class="b">%1$s</span> with <span class="b"><a href="widgets.php">%2$s Widget</a></span>', 'Theme <span class="b">%1$s</span> with <span class="b"><a href="widgets.php">%2$s Widgets</a></span>', $num_widgets), $switch_themes, $num);
  347. } else {
  348. printf(_n('Theme <span class="b">%1$s</span> with <span class="b">%2$s Widget</span>', 'Theme <span class="b">%1$s</span> with <span class="b">%2$s Widgets</span>', $num_widgets), $switch_themes, $num);
  349. }
  350. } else {
  351. if ( current_user_can( 'switch_themes' ) )
  352. printf( __('Theme <span class="b"><a href="themes.php">%1$s</a></span>'), $ct->title );
  353. else
  354. printf( __('Theme <span class="b">%1$s</span>'), $ct->title );
  355. }
  356. echo '</p>';
  357. // Check if search engines are blocked.
  358. if ( !is_network_admin() && !is_user_admin() && current_user_can('manage_options') && '1' != get_option('blog_public') ) {
  359. $title = apply_filters('privacy_on_link_title', __('Your site is asking search engines not to index its content') );
  360. $content = apply_filters('privacy_on_link_text', __('Search Engines Blocked') );
  361. echo "<p><a href='options-privacy.php' title='$title'>$content</a></p>";
  362. }
  363. update_right_now_message();
  364. echo "\n\t".'<br class="clear" /></div>';
  365. do_action( 'rightnow_end' );
  366. do_action( 'activity_box_end' );
  367. }
  368. function wp_network_dashboard_right_now() {
  369. $actions = array();
  370. if ( current_user_can('create_sites') )
  371. $actions['create-site'] = '<a href="' . network_admin_url('site-new.php') . '">' . __( 'Create a New Site' ) . '</a>';
  372. if ( current_user_can('create_users') )
  373. $actions['create-user'] = '<a href="' . network_admin_url('user-new.php') . '">' . __( 'Create a New User' ) . '</a>';
  374. $c_users = get_user_count();
  375. $c_blogs = get_blog_count();
  376. $user_text = sprintf( _n( '%s user', '%s users', $c_users ), number_format_i18n( $c_users ) );
  377. $blog_text = sprintf( _n( '%s site', '%s sites', $c_blogs ), number_format_i18n( $c_blogs ) );
  378. $sentence = sprintf( __( 'You have %1$s and %2$s.' ), $blog_text, $user_text );
  379. if ( $actions ) {
  380. echo '<ul class="subsubsub">';
  381. foreach ( $actions as $class => $action ) {
  382. $actions[ $class ] = "\t<li class='$class'>$action";
  383. }
  384. echo implode( " |</li>\n", $actions ) . "</li>\n";
  385. echo '</ul>';
  386. }
  387. ?>
  388. <br class="clear" />
  389. <p class="youhave"><?php echo $sentence; ?></p>
  390. <?php do_action( 'wpmuadminresult', '' ); ?>
  391. <form name="searchform" action="<?php echo network_admin_url('users.php'); ?>" method="get">
  392. <p>
  393. <input type="text" name="s" value="" size="17" />
  394. <?php submit_button( __( 'Search Users' ), 'button', 'submit', false, array( 'id' => 'submit_users' ) ); ?>
  395. </p>
  396. </form>
  397. <form name="searchform" action="<?php echo network_admin_url('sites.php'); ?>" method="get">
  398. <p>
  399. <input type="text" name="s" value="" size="17" />
  400. <?php submit_button( __( 'Search Sites' ), 'button', 'submit', false, array( 'id' => 'submit_sites' ) ); ?>
  401. </p>
  402. </form>
  403. <?php
  404. do_action( 'mu_rightnow_end' );
  405. do_action( 'mu_activity_box_end' );
  406. }
  407. function wp_dashboard_quick_press() {
  408. global $post_ID;
  409. $drafts = false;
  410. if ( 'post' === strtolower( $_SERVER['REQUEST_METHOD'] ) && isset( $_POST['action'] ) && 0 === strpos( $_POST['action'], 'post-quickpress' ) && (int) $_POST['post_ID'] ) {
  411. $view = get_permalink( $_POST['post_ID'] );
  412. $edit = esc_url( get_edit_post_link( $_POST['post_ID'] ) );
  413. if ( 'post-quickpress-publish' == $_POST['action'] ) {
  414. if ( current_user_can('publish_posts') )
  415. printf( '<div class="updated"><p>' . __( 'Post published. <a href="%s">View post</a> | <a href="%s">Edit post</a>' ) . '</p></div>', esc_url( $view ), $edit );
  416. else
  417. printf( '<div class="updated"><p>' . __( 'Post submitted. <a href="%s">Preview post</a> | <a href="%s">Edit post</a>' ) . '</p></div>', esc_url( add_query_arg( 'preview', 1, $view ) ), $edit );
  418. } else {
  419. printf( '<div class="updated"><p>' . __( 'Draft saved. <a href="%s">Preview post</a> | <a href="%s">Edit post</a>' ) . '</p></div>', esc_url( add_query_arg( 'preview', 1, $view ) ), $edit );
  420. $drafts_query = new WP_Query( array(
  421. 'post_type' => 'post',
  422. 'post_status' => 'draft',
  423. 'author' => $GLOBALS['current_user']->ID,
  424. 'posts_per_page' => 1,
  425. 'orderby' => 'modified',
  426. 'order' => 'DESC'
  427. ) );
  428. if ( $drafts_query->posts )
  429. $drafts =& $drafts_query->posts;
  430. }
  431. printf('<p class="textright">' . __('You can also try %s, easy blogging from anywhere on the Web.') . '</p>', '<a href="' . esc_url( admin_url( 'tools.php' ) ) . '">' . __('Press This') . '</a>' );
  432. $_REQUEST = array(); // hack for get_default_post_to_edit()
  433. }
  434. /* Check if a new auto-draft (= no new post_ID) is needed or if the old can be used */
  435. $last_post_id = (int) get_user_option( 'dashboard_quick_press_last_post_id' ); // Get the last post_ID
  436. if ( $last_post_id ) {
  437. $post = get_post( $last_post_id );
  438. if ( empty( $post ) || $post->post_status != 'auto-draft' ) { // auto-draft doesn't exists anymore
  439. $post = get_default_post_to_edit('post', true);
  440. update_user_option( (int) $GLOBALS['current_user']->ID, 'dashboard_quick_press_last_post_id', (int) $post->ID ); // Save post_ID
  441. } else {
  442. $post->post_title = ''; // Remove the auto draft title
  443. }
  444. } else {
  445. $post = get_default_post_to_edit('post', true);
  446. update_user_option( (int) $GLOBALS['current_user']->ID, 'dashboard_quick_press_last_post_id', (int) $post->ID ); // Save post_ID
  447. }
  448. $post_ID = (int) $post->ID;
  449. ?>
  450. <form name="post" action="<?php echo esc_url( admin_url( 'post.php' ) ); ?>" method="post" id="quick-press">
  451. <h4 id="quick-post-title"><label for="title"><?php _e('Title') ?></label></h4>
  452. <div class="input-text-wrap">
  453. <input type="text" name="post_title" id="title" tabindex="1" autocomplete="off" value="<?php echo esc_attr( $post->post_title ); ?>" />
  454. </div>
  455. <?php if ( current_user_can( 'upload_files' ) ) : ?>
  456. <div id="wp-content-wrap" class="wp-editor-wrap hide-if-no-js wp-media-buttons">
  457. <?php do_action( 'media_buttons', 'content' ); ?>
  458. </div>
  459. <?php endif; ?>
  460. <h4 id="content-label"><label for="content"><?php _e('Content') ?></label></h4>
  461. <div class="textarea-wrap">
  462. <textarea name="content" id="content" class="mceEditor" rows="3" cols="15" tabindex="2"><?php echo esc_textarea( $post->post_content ); ?></textarea>
  463. </div>
  464. <script type="text/javascript">edCanvas = document.getElementById('content');edInsertContent = null;</script>
  465. <h4><label for="tags-input"><?php _e('Tags') ?></label></h4>
  466. <div class="input-text-wrap">
  467. <input type="text" name="tags_input" id="tags-input" tabindex="3" value="<?php echo get_tags_to_edit( $post->ID ); ?>" />
  468. </div>
  469. <p class="submit">
  470. <input type="hidden" name="action" id="quickpost-action" value="post-quickpress-save" />
  471. <input type="hidden" name="post_ID" value="<?php echo $post_ID; ?>" />
  472. <input type="hidden" name="post_type" value="post" />
  473. <?php wp_nonce_field('add-post'); ?>
  474. <?php submit_button( __( 'Save Draft' ), 'button', 'save', false, array( 'id' => 'save-post', 'tabindex'=> 4 ) ); ?>
  475. <input type="reset" value="<?php esc_attr_e( 'Reset' ); ?>" class="button" />
  476. <span id="publishing-action">
  477. <input type="submit" name="publish" id="publish" accesskey="p" tabindex="5" class="button-primary" value="<?php current_user_can('publish_posts') ? esc_attr_e('Publish') : esc_attr_e('Submit for Review'); ?>" />
  478. <img class="waiting" src="<?php echo esc_url( admin_url( 'images/wpspin_light.gif' ) ); ?>" alt="" />
  479. </span>
  480. <br class="clear" />
  481. </p>
  482. </form>
  483. <?php
  484. if ( $drafts )
  485. wp_dashboard_recent_drafts( $drafts );
  486. }
  487. function wp_dashboard_recent_drafts( $drafts = false ) {
  488. if ( !$drafts ) {
  489. $drafts_query = new WP_Query( array(
  490. 'post_type' => 'post',
  491. 'post_status' => 'draft',
  492. 'author' => $GLOBALS['current_user']->ID,
  493. 'posts_per_page' => 5,
  494. 'orderby' => 'modified',
  495. 'order' => 'DESC'
  496. ) );
  497. $drafts =& $drafts_query->posts;
  498. }
  499. if ( $drafts && is_array( $drafts ) ) {
  500. $list = array();
  501. foreach ( $drafts as $draft ) {
  502. $url = get_edit_post_link( $draft->ID );
  503. $title = _draft_or_post_title( $draft->ID );
  504. $item = "<h4><a href='$url' title='" . sprintf( __( 'Edit &#8220;%s&#8221;' ), esc_attr( $title ) ) . "'>" . esc_html($title) . "</a> <abbr title='" . get_the_time(__('Y/m/d g:i:s A'), $draft) . "'>" . get_the_time( get_option( 'date_format' ), $draft ) . '</abbr></h4>';
  505. if ( $the_content = preg_split( '#\s#', strip_tags( $draft->post_content ), 11, PREG_SPLIT_NO_EMPTY ) )
  506. $item .= '<p>' . join( ' ', array_slice( $the_content, 0, 10 ) ) . ( 10 < count( $the_content ) ? '&hellip;' : '' ) . '</p>';
  507. $list[] = $item;
  508. }
  509. ?>
  510. <ul>
  511. <li><?php echo join( "</li>\n<li>", $list ); ?></li>
  512. </ul>
  513. <p class="textright"><a href="edit.php?post_status=draft" ><?php _e('View all'); ?></a></p>
  514. <?php
  515. } else {
  516. _e('There are no drafts at the moment');
  517. }
  518. }
  519. /**
  520. * Display recent comments dashboard widget content.
  521. *
  522. * @since 2.5.0
  523. */
  524. function wp_dashboard_recent_comments() {
  525. global $wpdb;
  526. if ( current_user_can('edit_posts') )
  527. $allowed_states = array('0', '1');
  528. else
  529. $allowed_states = array('1');
  530. // Select all comment types and filter out spam later for better query performance.
  531. $comments = array();
  532. $start = 0;
  533. $widgets = get_option( 'dashboard_widget_options' );
  534. $total_items = isset( $widgets['dashboard_recent_comments'] ) && isset( $widgets['dashboard_recent_comments']['items'] )
  535. ? absint( $widgets['dashboard_recent_comments']['items'] ) : 5;
  536. while ( count( $comments ) < $total_items && $possible = $wpdb->get_results( "SELECT * FROM $wpdb->comments c LEFT JOIN $wpdb->posts p ON c.comment_post_ID = p.ID WHERE p.post_status != 'trash' ORDER BY c.comment_date_gmt DESC LIMIT $start, 50" ) ) {
  537. foreach ( $possible as $comment ) {
  538. if ( count( $comments ) >= $total_items )
  539. break;
  540. if ( in_array( $comment->comment_approved, $allowed_states ) && current_user_can( 'read_post', $comment->comment_post_ID ) )
  541. $comments[] = $comment;
  542. }
  543. $start = $start + 50;
  544. }
  545. if ( $comments ) :
  546. ?>
  547. <div id="the-comment-list" class="list:comment">
  548. <?php
  549. foreach ( $comments as $comment )
  550. _wp_dashboard_recent_comments_row( $comment );
  551. ?>
  552. </div>
  553. <?php
  554. if ( current_user_can('edit_posts') ) { ?>
  555. <?php _get_list_table('WP_Comments_List_Table')->views(); ?>
  556. <?php }
  557. wp_comment_reply( -1, false, 'dashboard', false );
  558. wp_comment_trashnotice();
  559. else :
  560. ?>
  561. <p><?php _e( 'No comments yet.' ); ?></p>
  562. <?php
  563. endif; // $comments;
  564. }
  565. function _wp_dashboard_recent_comments_row( &$comment, $show_date = true ) {
  566. $GLOBALS['comment'] =& $comment;
  567. $comment_post_url = get_edit_post_link( $comment->comment_post_ID );
  568. $comment_post_title = strip_tags(get_the_title( $comment->comment_post_ID ));
  569. $comment_post_link = "<a href='$comment_post_url'>$comment_post_title</a>";
  570. $comment_link = '<a class="comment-link" href="' . esc_url(get_comment_link()) . '">#</a>';
  571. $actions_string = '';
  572. if ( current_user_can( 'edit_comment', $comment->comment_ID ) ) {
  573. // preorder it: Approve | Reply | Edit | Spam | Trash
  574. $actions = array(
  575. 'approve' => '', 'unapprove' => '',
  576. 'reply' => '',
  577. 'edit' => '',
  578. 'spam' => '',
  579. 'trash' => '', 'delete' => ''
  580. );
  581. $del_nonce = esc_html( '_wpnonce=' . wp_create_nonce( "delete-comment_$comment->comment_ID" ) );
  582. $approve_nonce = esc_html( '_wpnonce=' . wp_create_nonce( "approve-comment_$comment->comment_ID" ) );
  583. $approve_url = esc_url( "comment.php?action=approvecomment&p=$comment->comment_post_ID&c=$comment->comment_ID&$approve_nonce" );
  584. $unapprove_url = esc_url( "comment.php?action=unapprovecomment&p=$comment->comment_post_ID&c=$comment->comment_ID&$approve_nonce" );
  585. $spam_url = esc_url( "comment.php?action=spamcomment&p=$comment->comment_post_ID&c=$comment->comment_ID&$del_nonce" );
  586. $trash_url = esc_url( "comment.php?action=trashcomment&p=$comment->comment_post_ID&c=$comment->comment_ID&$del_nonce" );
  587. $delete_url = esc_url( "comment.php?action=deletecomment&p=$comment->comment_post_ID&c=$comment->comment_ID&$del_nonce" );
  588. $actions['approve'] = "<a href='$approve_url' class='dim:the-comment-list:comment-$comment->comment_ID:unapproved:e7e7d3:e7e7d3:new=approved vim-a' title='" . esc_attr__( 'Approve this comment' ) . "'>" . __( 'Approve' ) . '</a>';
  589. $actions['unapprove'] = "<a href='$unapprove_url' class='dim:the-comment-list:comment-$comment->comment_ID:unapproved:e7e7d3:e7e7d3:new=unapproved vim-u' title='" . esc_attr__( 'Unapprove this comment' ) . "'>" . __( 'Unapprove' ) . '</a>';
  590. $actions['edit'] = "<a href='comment.php?action=editcomment&amp;c={$comment->comment_ID}' title='" . esc_attr__('Edit comment') . "'>". __('Edit') . '</a>';
  591. $actions['reply'] = '<a onclick="commentReply.open(\''.$comment->comment_ID.'\',\''.$comment->comment_post_ID.'\');return false;" class="vim-r hide-if-no-js" title="'.esc_attr__('Reply to this comment').'" href="#">' . __('Reply') . '</a>';
  592. $actions['spam'] = "<a href='$spam_url' class='delete:the-comment-list:comment-$comment->comment_ID::spam=1 vim-s vim-destructive' title='" . esc_attr__( 'Mark this comment as spam' ) . "'>" . /* translators: mark as spam link */ _x( 'Spam', 'verb' ) . '</a>';
  593. if ( !EMPTY_TRASH_DAYS )
  594. $actions['delete'] = "<a href='$delete_url' class='delete:the-comment-list:comment-$comment->comment_ID::trash=1 delete vim-d vim-destructive'>" . __('Delete Permanently') . '</a>';
  595. else
  596. $actions['trash'] = "<a href='$trash_url' class='delete:the-comment-list:comment-$comment->comment_ID::trash=1 delete vim-d vim-destructive' title='" . esc_attr__( 'Move this comment to the trash' ) . "'>" . _x('Trash', 'verb') . '</a>';
  597. $actions = apply_filters( 'comment_row_actions', array_filter($actions), $comment );
  598. $i = 0;
  599. foreach ( $actions as $action => $link ) {
  600. ++$i;
  601. ( ( ('approve' == $action || 'unapprove' == $action) && 2 === $i ) || 1 === $i ) ? $sep = '' : $sep = ' | ';
  602. // Reply and quickedit need a hide-if-no-js span
  603. if ( 'reply' == $action || 'quickedit' == $action )
  604. $action .= ' hide-if-no-js';
  605. $actions_string .= "<span class='$action'>$sep$link</span>";
  606. }
  607. }
  608. ?>
  609. <div id="comment-<?php echo $comment->comment_ID; ?>" <?php comment_class( array( 'comment-item', wp_get_comment_status($comment->comment_ID) ) ); ?>>
  610. <?php if ( !$comment->comment_type || 'comment' == $comment->comment_type ) : ?>
  611. <?php echo get_avatar( $comment, 50 ); ?>
  612. <div class="dashboard-comment-wrap">
  613. <h4 class="comment-meta">
  614. <?php printf( /* translators: 1: comment author, 2: post link, 3: notification if the comment is pending */__( 'From %1$s on %2$s%3$s' ),
  615. '<cite class="comment-author">' . get_comment_author_link() . '</cite>', $comment_post_link.' '.$comment_link, ' <span class="approve">' . __( '[Pending]' ) . '</span>' ); ?>
  616. </h4>
  617. <?php
  618. else :
  619. switch ( $comment->comment_type ) :
  620. case 'pingback' :
  621. $type = __( 'Pingback' );
  622. break;
  623. case 'trackback' :
  624. $type = __( 'Trackback' );
  625. break;
  626. default :
  627. $type = ucwords( $comment->comment_type );
  628. endswitch;
  629. $type = esc_html( $type );
  630. ?>
  631. <div class="dashboard-comment-wrap">
  632. <?php /* translators: %1$s is type of comment, %2$s is link to the post */ ?>
  633. <h4 class="comment-meta"><?php printf( _x( '%1$s on %2$s', 'dashboard' ), "<strong>$type</strong>", $comment_post_link." ".$comment_link ); ?></h4>
  634. <p class="comment-author"><?php comment_author_link(); ?></p>
  635. <?php endif; // comment_type ?>
  636. <blockquote><p><?php comment_excerpt(); ?></p></blockquote>
  637. <p class="row-actions"><?php echo $actions_string; ?></p>
  638. </div>
  639. </div>
  640. <?php
  641. }
  642. /**
  643. * The recent comments dashboard widget control.
  644. *
  645. * @since 3.0.0
  646. */
  647. function wp_dashboard_recent_comments_control() {
  648. if ( !$widget_options = get_option( 'dashboard_widget_options' ) )
  649. $widget_options = array();
  650. if ( !isset($widget_options['dashboard_recent_comments']) )
  651. $widget_options['dashboard_recent_comments'] = array();
  652. if ( 'POST' == $_SERVER['REQUEST_METHOD'] && isset($_POST['widget-recent-comments']) ) {
  653. $number = absint( $_POST['widget-recent-comments']['items'] );
  654. $widget_options['dashboard_recent_comments']['items'] = $number;
  655. update_option( 'dashboard_widget_options', $widget_options );
  656. }
  657. $number = isset( $widget_options['dashboard_recent_comments']['items'] ) ? (int) $widget_options['dashboard_recent_comments']['items'] : '';
  658. echo '<p><label for="comments-number">' . __('Number of comments to show:') . '</label>';
  659. echo '<input id="comments-number" name="widget-recent-comments[items]" type="text" value="' . $number . '" size="3" /></p>';
  660. }
  661. function wp_dashboard_incoming_links() {
  662. wp_dashboard_cached_rss_widget( 'dashboard_incoming_links', 'wp_dashboard_incoming_links_output' );
  663. }
  664. /**
  665. * Display incoming links dashboard widget content.
  666. *
  667. * @since 2.5.0
  668. */
  669. function wp_dashboard_incoming_links_output() {
  670. $widgets = get_option( 'dashboard_widget_options' );
  671. @extract( @$widgets['dashboard_incoming_links'], EXTR_SKIP );
  672. $rss = fetch_feed( $url );
  673. if ( is_wp_error($rss) ) {
  674. if ( is_admin() || current_user_can('manage_options') ) {
  675. echo '<p>';
  676. printf(__('<strong>RSS Error</strong>: %s'), $rss->get_error_message());
  677. echo '</p>';
  678. }
  679. return;
  680. }
  681. if ( !$rss->get_item_quantity() ) {
  682. 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";
  683. $rss->__destruct();
  684. unset($rss);
  685. return;
  686. }
  687. echo "<ul>\n";
  688. if ( !isset($items) )
  689. $items = 10;
  690. foreach ( $rss->get_items(0, $items) as $item ) {
  691. $publisher = '';
  692. $site_link = '';
  693. $link = '';
  694. $content = '';
  695. $date = '';
  696. $link = esc_url( strip_tags( $item->get_link() ) );
  697. $author = $item->get_author();
  698. if ( $author ) {
  699. $site_link = esc_url( strip_tags( $author->get_link() ) );
  700. if ( !$publisher = esc_html( strip_tags( $author->get_name() ) ) )
  701. $publisher = __( 'Somebody' );
  702. } else {
  703. $publisher = __( 'Somebody' );
  704. }
  705. if ( $site_link )
  706. $publisher = "<a href='$site_link'>$publisher</a>";
  707. else
  708. $publisher = "<strong>$publisher</strong>";
  709. $content = $item->get_content();
  710. $content = wp_html_excerpt($content, 50) . ' ...';
  711. if ( $link )
  712. /* translators: incoming links feed, %1$s is other person, %3$s is content */
  713. $text = __( '%1$s linked here <a href="%2$s">saying</a>, "%3$s"' );
  714. else
  715. /* translators: incoming links feed, %1$s is other person, %3$s is content */
  716. $text = __( '%1$s linked here saying, "%3$s"' );
  717. if ( !empty($show_date) ) {
  718. if ( !empty($show_author) || !empty($show_summary) )
  719. /* translators: incoming links feed, %4$s is the date */
  720. $text .= ' ' . __( 'on %4$s' );
  721. $date = esc_html( strip_tags( $item->get_date() ) );
  722. $date = strtotime( $date );
  723. $date = gmdate( get_option( 'date_format' ), $date );
  724. }
  725. echo "\t<li>" . sprintf( $text, $publisher, $link, $content, $date ) . "</li>\n";
  726. }
  727. echo "</ul>\n";
  728. $rss->__destruct();
  729. unset($rss);
  730. }
  731. function wp_dashboard_incoming_links_control() {
  732. wp_dashboard_rss_control( 'dashboard_incoming_links', array( 'title' => false, 'show_summary' => false, 'show_author' => false ) );
  733. }
  734. function wp_dashboard_primary() {
  735. wp_dashboard_cached_rss_widget( 'dashboard_primary', 'wp_dashboard_rss_output' );
  736. }
  737. function wp_dashboard_primary_control() {
  738. wp_dashboard_rss_control( 'dashboard_primary' );
  739. }
  740. /**
  741. * {@internal Missing Short Description}}
  742. *
  743. * @since 2.5.0
  744. *
  745. * @param string $widget_id
  746. */
  747. function wp_dashboard_rss_output( $widget_id ) {
  748. $widgets = get_option( 'dashboard_widget_options' );
  749. echo '<div class="rss-widget">';
  750. wp_widget_rss_output( $widgets[$widget_id] );
  751. echo "</div>";
  752. }
  753. function wp_dashboard_secondary() {
  754. wp_dashboard_cached_rss_widget( 'dashboard_secondary', 'wp_dashboard_secondary_output' );
  755. }
  756. function wp_dashboard_secondary_control() {
  757. wp_dashboard_rss_control( 'dashboard_secondary' );
  758. }
  759. /**
  760. * Display secondary dashboard RSS widget feed.
  761. *
  762. * @since 2.5.0
  763. *
  764. * @return unknown
  765. */
  766. function wp_dashboard_secondary_output() {
  767. $widgets = get_option( 'dashboard_widget_options' );
  768. @extract( @$widgets['dashboard_secondary'], EXTR_SKIP );
  769. $rss = @fetch_feed( $url );
  770. if ( is_wp_error($rss) ) {
  771. if ( is_admin() || current_user_can('manage_options') ) {
  772. echo '<div class="rss-widget"><p>';
  773. printf(__('<strong>RSS Error</strong>: %s'), $rss->get_error_message());
  774. echo '</p></div>';
  775. }
  776. } elseif ( !$rss->get_item_quantity() ) {
  777. $rss->__destruct();
  778. unset($rss);
  779. return false;
  780. } else {
  781. echo '<div class="rss-widget">';
  782. wp_widget_rss_output( $rss, $widgets['dashboard_secondary'] );
  783. echo '</div>';
  784. $rss->__destruct();
  785. unset($rss);
  786. }
  787. }
  788. function wp_dashboard_plugins() {
  789. wp_dashboard_cached_rss_widget( 'dashboard_plugins', 'wp_dashboard_plugins_output', array(
  790. 'http://wordpress.org/extend/plugins/rss/browse/popular/',
  791. 'http://wordpress.org/extend/plugins/rss/browse/new/',
  792. 'http://wordpress.org/extend/plugins/rss/browse/updated/'
  793. ) );
  794. }
  795. /**
  796. * Display plugins most popular, newest plugins, and recently updated widget text.
  797. *
  798. * @since 2.5.0
  799. */
  800. function wp_dashboard_plugins_output() {
  801. $popular = fetch_feed( 'http://wordpress.org/extend/plugins/rss/browse/popular/' );
  802. $new = fetch_feed( 'http://wordpress.org/extend/plugins/rss/browse/new/' );
  803. $updated = fetch_feed( 'http://wordpress.org/extend/plugins/rss/browse/updated/' );
  804. if ( false === $plugin_slugs = get_transient( 'plugin_slugs' ) ) {
  805. $plugin_slugs = array_keys( get_plugins() );
  806. set_transient( 'plugin_slugs', $plugin_slugs, 86400 );
  807. }
  808. foreach ( array( 'popular' => __('Most Popular'), 'new' => __('Newest Plugins'), 'updated' => __('Recently Updated') ) as $feed => $label ) {
  809. if ( is_wp_error($$feed) || !$$feed->get_item_quantity() )
  810. continue;
  811. $items = $$feed->get_items(0, 5);
  812. // Pick a random, non-installed plugin
  813. while ( true ) {
  814. // Abort this foreach loop iteration if there's no plugins left of this type
  815. if ( 0 == count($items) )
  816. continue 2;
  817. $item_key = array_rand($items);
  818. $item = $items[$item_key];
  819. list($link, $frag) = explode( '#', $item->get_link() );
  820. $link = esc_url($link);
  821. if ( preg_match( '|/([^/]+?)/?$|', $link, $matches ) )
  822. $slug = $matches[1];
  823. else {
  824. unset( $items[$item_key] );
  825. continue;
  826. }
  827. // Is this random plugin's slug already installed? If so, try again.
  828. reset( $plugin_slugs );
  829. foreach ( $plugin_slugs as $plugin_slug ) {
  830. if ( $slug == substr( $plugin_slug, 0, strlen( $slug ) ) ) {
  831. unset( $items[$item_key] );
  832. continue 2;
  833. }
  834. }
  835. // If we get to this point, then the random plugin isn't installed and we can stop the while().
  836. break;
  837. }
  838. // Eliminate some common badly formed plugin descriptions
  839. while ( ( null !== $item_key = array_rand($items) ) && false !== strpos( $items[$item_key]->get_description(), 'Plugin Name:' ) )
  840. unset($items[$item_key]);
  841. if ( !isset($items[$item_key]) )
  842. continue;
  843. // current bbPress feed item titles are: user on "topic title"
  844. if ( preg_match( '/&quot;(.*)&quot;/s', $item->get_title(), $matches ) )
  845. $title = $matches[1];
  846. else // but let's make it forward compatible if things change
  847. $title = $item->get_title();
  848. $title = esc_html( $title );
  849. $description = esc_html( strip_tags(@html_entity_decode($item->get_description(), ENT_QUOTES, get_option('blog_charset'))) );
  850. $ilink = wp_nonce_url('plugin-install.php?tab=plugin-information&plugin=' . $slug, 'install-plugin_' . $slug) .
  851. '&amp;TB_iframe=true&amp;width=600&amp;height=800';
  852. echo "<h4>$label</h4>\n";
  853. echo "<h5><a href='$link'>$title</a></h5>&nbsp;<span>(<a href='$ilink' class='thickbox' title='$title'>" . __( 'Install' ) . "</a>)</span>\n";
  854. echo "<p>$description</p>\n";
  855. $$feed->__destruct();
  856. unset($$feed);
  857. }
  858. }
  859. /**
  860. * Checks to see if all of the feed url in $check_urls are cached.
  861. *
  862. * If $check_urls is empty, look for the rss feed url found in the dashboard
  863. * widget options of $widget_id. If cached, call $callback, a function that
  864. * echoes out output for this widget. If not cache, echo a "Loading..." stub
  865. * which is later replaced by AJAX call (see top of /wp-admin/index.php)
  866. *
  867. * @since 2.5.0
  868. *
  869. * @param string $widget_id
  870. * @param callback $callback
  871. * @param array $check_urls RSS feeds
  872. * @return bool False on failure. True on success.
  873. */
  874. function wp_dashboard_cached_rss_widget( $widget_id, $callback, $check_urls = array() ) {
  875. $loading = '<p class="widget-loading hide-if-no-js">' . __( 'Loading&#8230;' ) . '</p><p class="hide-if-js">' . __( 'This widget requires JavaScript.' ) . '</p>';
  876. $doing_ajax = ( defined('DOING_AJAX') && DOING_AJAX );
  877. if ( empty($check_urls) ) {
  878. $widgets = get_option( 'dashboard_widget_options' );
  879. if ( empty($widgets[$widget_id]['url']) && ! $doing_ajax ) {
  880. echo $loading;
  881. return false;
  882. }
  883. $check_urls = array( $widgets[$widget_id]['url'] );
  884. }
  885. $cache_key = 'dash_' . md5( $widget_id );
  886. if ( false !== ( $output = get_transient( $cache_key ) ) ) {
  887. echo $output;
  888. return true;
  889. }
  890. if ( ! $doing_ajax ) {
  891. echo $loading;
  892. return false;
  893. }
  894. if ( $callback && is_callable( $callback ) ) {
  895. $args = array_slice( func_get_args(), 2 );
  896. array_unshift( $args, $widget_id );
  897. ob_start();
  898. call_user_func_array( $callback, $args );
  899. set_transient( $cache_key, ob_get_flush(), 43200); // Default lifetime in cache of 12 hours (same as the feeds)
  900. }
  901. return true;
  902. }
  903. /* Dashboard Widgets Controls */
  904. // Calls widget_control callback
  905. /**
  906. * Calls widget control callback.
  907. *
  908. * @since 2.5.0
  909. *
  910. * @param int $widget_control_id Registered Widget ID.
  911. */
  912. function wp_dashboard_trigger_widget_control( $widget_control_id = false ) {
  913. global $wp_dashboard_control_callbacks;
  914. 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]) ) {
  915. call_user_func( $wp_dashboard_control_callbacks[$widget_control_id], '', array( 'id' => $widget_control_id, 'callback' => $wp_dashboard_control_callbacks[$widget_control_id] ) );
  916. }
  917. }
  918. /**
  919. * The RSS dashboard widget control.
  920. *
  921. * Sets up $args to be used as input to wp_widget_rss_form(). Handles POST data
  922. * from RSS-type widgets.
  923. *
  924. * @since 2.5.0
  925. *
  926. * @param string $widget_id
  927. * @param array $form_inputs
  928. */
  929. function wp_dashboard_rss_control( $widget_id, $form_inputs = array() ) {
  930. if ( !$widget_options = get_option( 'dashboard_widget_options' ) )
  931. $widget_options = array();
  932. if ( !isset($widget_options[$widget_id]) )
  933. $widget_options[$widget_id] = array();
  934. $number = 1; // Hack to use wp_widget_rss_form()
  935. $widget_options[$widget_id]['number'] = $number;
  936. if ( 'POST' == $_SERVER['REQUEST_METHOD'] && isset($_POST['widget-rss'][$number]) ) {
  937. $_POST['widget-rss'][$number] = stripslashes_deep( $_POST['widget-rss'][$number] );
  938. $widget_options[$widget_id] = wp_widget_rss_process( $_POST['widget-rss'][$number] );
  939. // title is optional. If black, fill it if possible
  940. if ( !$widget_options[$widget_id]['title'] && isset($_POST['widget-rss'][$number]['title']) ) {
  941. $rss = fetch_feed($widget_options[$widget_id]['url']);
  942. if ( is_wp_error($rss) ) {
  943. $widget_options[$widget_id]['title'] = htmlentities(__('Unknown Feed'));
  944. } else {
  945. $widget_options[$widget_id]['title'] = htmlentities(strip_tags($rss->get_title()));
  946. $rss->__destruct();
  947. unset($rss);
  948. }
  949. }
  950. update_option( 'dashboard_widget_options', $widget_options );
  951. $cache_key = 'dash_' . md5( $widget_id );
  952. delete_transient( $cache_key );
  953. }
  954. wp_widget_rss_form( $widget_options[$widget_id], $form_inputs );
  955. }
  956. // Display File upload quota on dashboard
  957. function wp_dashboard_quota() {
  958. if ( !is_multisite() || !current_user_can('upload_files') || get_site_option( 'upload_space_check_disabled' ) )
  959. return true;
  960. $quota = get_space_allowed();
  961. $used = get_dirsize( BLOGUPLOADDIR ) / 1024 / 1024;
  962. if ( $used > $quota )
  963. $percentused = '100';
  964. else
  965. $percentused = ( $used / $quota ) * 100;
  966. $used_color = ( $percentused >= 70 ) ? ' spam' : '';
  967. $used = round( $used, 2 );
  968. $percentused = number_format( $percentused );
  969. ?>
  970. <p class="sub musub"><?php _e( 'Storage Space' ); ?></p>
  971. <div class="table table_content musubtable">
  972. <table>
  973. <tr class="first">
  974. <td class="first b b-posts"><?php printf( __( '<a href="%1$s" title="Manage Uploads" class="musublink">%2$sMB</a>' ), esc_url( admin_url( 'upload.php' ) ), $quota ); ?></td>
  975. <td class="t posts"><?php _e( 'Space Allowed' ); ?></td>
  976. </tr>
  977. </table>
  978. </div>
  979. <div class="table table_discussion musubtable">
  980. <table>
  981. <tr class="first">
  982. <td class="b b-comments"><?php printf( __( '<a href="%1$s" title="Manage Uploads" class="musublink">%2$sMB (%3$s%%)</a>' ), esc_url( admin_url( 'upload.php' ) ), $used, $percentused ); ?></td>
  983. <td class="last t comments<?php echo $used_color;?>"><?php _e( 'Space Used' );?></td>
  984. </tr>
  985. </table>
  986. </div>
  987. <br class="clear" />
  988. <?php
  989. }
  990. add_action( 'activity_box_end', 'wp_dashboard_quota' );
  991. // Display Browser Nag Meta Box
  992. function wp_dashboard_browser_nag() {
  993. $notice = '';
  994. $response = wp_check_browser_version();
  995. if ( $response ) {
  996. if ( $response['insecure'] ) {
  997. $msg = sprintf( __( "It looks like you're using an insecure version of <a href='%s'>%s</a>. Using an outdated browser makes your computer unsafe. For the best WordPress experience, please update your browser." ), esc_attr( $response['update_url'] ), esc_html( $response['name'] ) );
  998. } else {
  999. $msg = sprintf( __( "It looks like you're using an old version of <a href='%s'>%s</a>. For the best WordPress experience, please update your browser." ), esc_attr( $response['update_url'] ), esc_html( $response['name'] ) );
  1000. }
  1001. $browser_nag_class = '';
  1002. if ( !empty( $response['img_src'] ) ) {
  1003. $img_src = ( is_ssl() && ! empty( $response['img_src_ssl'] ) )? $response['img_src_ssl'] : $response['img_src'];
  1004. $notice .= '<div class="alignright browser-icon"><a href="' . esc_attr($response['update_url']) . '"><img src="' . esc_attr( $img_src ) . '" alt="" /></a></div>';
  1005. $browser_nag_class = ' has-browser-icon';
  1006. }
  1007. $notice .= "<p class='browser-update-nag{$browser_nag_class}'>{$msg}</p>";
  1008. $notice .= '<p>' . sprintf( __( '<a href="%1$s" class="update-browser-link">Update %2$s</a> or learn how to <a href="%3$s" class="browse-happy-link">browse happy</a>' ), esc_attr( $response['update_url'] ), esc_html( $response['name'] ), 'http://browsehappy.com/' ) . '</p>';
  1009. $notice .= '<p class="hide-if-no-js"><a href="" class="dismiss">' . __( 'Dismiss' ) . '</a></p>';
  1010. $notice .= '<div class="clear"></div>';
  1011. }
  1012. echo apply_filters( 'browse-happy-notice', $notice, $response );
  1013. }
  1014. function dashboard_browser_nag_class( $classes ) {
  1015. $response = wp_check_browser_version();
  1016. if ( $response && $response['insecure'] )
  1017. $classes[] = 'browser-insecure';
  1018. return $classes;
  1019. }
  1020. /**
  1021. * Check if the user needs a browser update
  1022. *
  1023. * @since 3.2.0
  1024. *
  1025. * @return array|bool False on failure, array of browser data on success.
  1026. */
  1027. function wp_check_browser_version() {
  1028. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  1029. return false;
  1030. $key = md5( $_SERVER['HTTP_USER_AGENT'] );
  1031. if ( false === ($response = get_site_transient('browser_' . $key) ) ) {
  1032. global $wp_version;
  1033. $options = array(
  1034. 'body' => array( 'useragent' => $_SERVER['HTTP_USER_AGENT'] ),
  1035. 'user-agent' => 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' )
  1036. );
  1037. $response = wp_remote_post( 'http://api.wordpress.org/core/browse-happy/1.0/', $options );
  1038. if ( is_wp_error( $response ) || 200 != wp_remote_retrieve_response_code( $response ) )
  1039. return false;
  1040. /**
  1041. * Response should be an array with:
  1042. * 'name' - string - A user friendly browser name
  1043. * 'version' - string - The most recent version of the browser
  1044. * 'current_version' - string - The version of the browser the user is using
  1045. * 'upgrade' - boolean - Whether the browser needs an upgrade
  1046. * 'insecure' - boolean - Whether the browser is deemed insecure
  1047. * 'upgrade_url' - string - The url to visit to upgrade
  1048. * 'img_src' - string - An image representing the browser
  1049. * 'img_src_ssl' - string - An image (over SSL) representing the browser
  1050. */
  1051. $response = unserialize( wp_remote_retrieve_body( $response ) );
  1052. if ( ! $response )
  1053. return false;
  1054. set_site_transient( 'browser_' . $key, $response, 604800 ); // cache for 1 week
  1055. }
  1056. return $response;
  1057. }
  1058. /**
  1059. * Empty function usable by plugins to output empty dashboard widget (to be populated later by JS).
  1060. */
  1061. function wp_dashboard_empty() {}
  1062. /**
  1063. * Displays a welcome panel to introduce users to WordPress.
  1064. *
  1065. * @since 3.3
  1066. */
  1067. function wp_welcome_panel() {
  1068. global $wp_version;
  1069. if ( ! current_user_can( 'edit_theme_options' ) )
  1070. return;
  1071. $classes = 'welcome-panel';
  1072. $option = get_user_meta( get_current_user_id(), 'show_welcome_panel', true );
  1073. // 0 = hide, 1 = toggled to show or single site creator, 2 = multisite site owner
  1074. $hide = 0 == $option || ( 2 == $option && wp_get_current_user()->user_email != get_option( 'admin_email' ) );
  1075. if ( $hide )
  1076. $classes .= ' hidden';
  1077. list( $display_version ) = explode( '-', $wp_version );
  1078. ?>
  1079. <div id="welcome-panel" class="<?php echo esc_attr( $classes ); ?>">
  1080. <?php wp_nonce_field( 'welcome-panel-nonce', 'welcomepanelnonce', false ); ?>
  1081. <a class="welcome-panel-close" href="<?php echo esc_url( admin_url( '?welcome=0' ) ); ?>"><?php _e('Dismiss'); ?></a>
  1082. <div class="wp-badge"><?php printf( __( 'Version %s' ), $display_version ); ?></div>
  1083. <div class="welcome-panel-content">
  1084. <h3><?php _e( 'Welcome to your new WordPress site! ' ); ?></h3>
  1085. <p class="about-description"><?php _e( 'If you need help getting started, check out our documentation on <a href="http://codex.wordpress.org/First_Steps_With_WordPress">First Steps with WordPress</a>. If you&#8217;d rather dive right in, here are a few things most people do first when they set up a new WordPress site. If you need help, use the Help tabs in the upper right corner to get information on how to use your current screen and where to go for more assistance.' ); ?></p>
  1086. <div class="welcome-panel-column-container">
  1087. <div class="welcome-panel-column">
  1088. <h4><span class="icon16 icon-settings"></span> <?php _e( 'Basic Settings' ); ?></h4>
  1089. <p><?php _e( 'Here are a few easy things you can do to get your feet wet. Make sure to click Save on each Settings screen.' ); ?></p>
  1090. <ul>
  1091. <li><?php echo sprintf( __( '<a href="%s">Choose your privacy setting</a>' ), esc_url( admin_url('options-privacy.php') ) ); ?></li>
  1092. <li><?php echo sprintf( __( '<a href="%s">Select your tagline and time zone</a>' ), esc_url( admin_url('options-general.php') ) ); ?></li>
  1093. <li><?php echo sprintf( __( '<a href="%s">Turn comments on or off</a>' ), esc_url( admin_url('options-discussion.php') ) ); ?></li>
  1094. <li><?php echo sprintf( __( '<a href="%s">Fill in your profile</a>' ), esc_url( admin_url('profile.php') ) ); ?></li>
  1095. </ul>
  1096. </div>
  1097. <div class="welcome-panel-column">
  1098. <h4><span class="icon16 icon-page"></span> <?php _e( 'Add Real Content' ); ?></h4>
  1099. <p><?php _e( 'Check out the sample page & post editors to see how it all works, then delete the default content and write your own!' ); ?></p>
  1100. <ul>
  1101. <li><?php echo sprintf( __( 'View the <a href="%1$s">sample page</a> and <a href="%2$s">post</a>' ), esc_url( get_permalink( 2 ) ), esc_url( get_permalink( 1 ) ) ); ?></li>
  1102. <li><?php echo sprintf( __( 'Delete the <a href="%1$s">sample page</a> and <a href="%2$s">post</a>' ), esc_url( admin_url('edit.php?post_type=page') ), esc_url( admin_url('edit.php') ) ); ?></li>
  1103. <li><?php echo sprintf( __( '<a href="%s">Create an About Me page</a>' ), esc_url( admin_url('edit.php?post_type=page') ) ); ?></li>
  1104. <li><?php echo sprintf( __( '<a href="%s">Write your first post</a>' ), esc_url( admin_url('post-new.php') ) ); ?></li>
  1105. </ul>
  1106. </div>
  1107. <div class="welcome-panel-column welcome-panel-last">
  1108. <h4><span class="icon16 icon-appearance"></span> <?php _e( 'Customize Your Site' ); ?></h4>
  1109. <?php
  1110. $ct = current_theme_info();
  1111. if ( empty ( $ct->stylesheet_dir ) ) :
  1112. echo '<p>';
  1113. printf( __( '<a href="%s">Install a theme</a> to get started customizing your site.' ), esc_url( admin_url( 'themes.php' ) ) );
  1114. echo '</p>';
  1115. else:
  1116. $customize_links = array();
  1117. if ( 'twentyeleven' == $ct->stylesheet )
  1118. $customize_links[] = sprintf( __( '<a href="%s">Choose light or dark</a>' ), esc_url( admin_url( 'themes.php?page=theme_options' ) ) );
  1119. if ( current_theme_supports( 'custom-background' ) )
  1120. $customize_links[] = sprintf( __( '<a href="%s">Set a background color</a>' ), esc_url( admin_url( 'themes.php?page=custom-background' ) ) );
  1121. if ( current_theme_supports( 'custom-header' ) )
  1122. $customize_links[] = sprintf( __( '<a href="%s">Select a new header image</a>' ), esc_url( admin_url( 'themes.php?page=custom-header' ) ) );
  1123. if ( current_theme_supports( 'widgets' ) )
  1124. $customize_links[] = sprintf( __( '<a href="%s">Add some widgets</a>' ), esc_url( admin_url( 'widgets.php' ) ) );
  1125. if ( ! empty( $customize_links ) ) {
  1126. echo '<p>';
  1127. printf( __( 'Use the current theme &mdash; %1$s &mdash; or <a href="%2$s">choose a new one</a>. If you stick with %3$s, here are a few ways to make your site look unique.' ), $ct->title, esc_url( admin_url( 'themes.php' ) ), $ct->title );
  1128. echo '</p>';
  1129. ?>
  1130. <ul>
  1131. <?php foreach ( $customize_links as $customize_link ) : ?>
  1132. <li><?php echo $customize_link ?></li>
  1133. <?php endforeach; ?>
  1134. </ul>
  1135. <?php
  1136. } else {
  1137. echo '<p>';
  1138. printf( __( 'Use the current theme &mdash; %1$s &mdash; or <a href="%2$s">choose a new one</a>.' ), $ct->title, esc_url( admin_url( 'themes.php' ) ) );
  1139. echo '</p>';
  1140. }
  1141. endif; ?>
  1142. </div>
  1143. </div>
  1144. <p class="welcome-panel-dismiss"><?php printf( __( 'Already know what you&#8217;re doing? <a href="%s">Dismiss this message</a>.' ), esc_url( admin_url( '?welcome=0' ) ) ); ?></p>
  1145. </div>
  1146. </div>
  1147. <?php
  1148. }
  1149. ?>