/** * Determine if uploaded file exceeds space quota. * * @since 3.0.0 * * @param array $file $_FILES array for a given file. * @return array $_FILES array with 'error' key set if file exceeds quota. 'error' is empty otherwise. */ function check_upload_size($file) { if (get_site_option('upload_space_check_disabled')) { return $file; } if ($file['error'] != '0') { // there's already an error return $file; } if (defined('WP_IMPORTING')) { return $file; } $space_left = get_upload_space_available(); $file_size = filesize($file['tmp_name']); if ($space_left < $file_size) { $file['error'] = sprintf(__('Not enough space to upload. %1$s KB needed.'), number_format(($file_size - $space_left) / KB_IN_BYTES)); } if ($file_size > KB_IN_BYTES * get_site_option('fileupload_maxk', 1500)) { $file['error'] = sprintf(__('This file is too big. Files must be less than %1$s KB in size.'), get_site_option('fileupload_maxk', 1500)); } if (upload_is_user_over_quota(false)) { $file['error'] = __('You have used your space quota. Please delete files before uploading.'); } if ($file['error'] != '0' && !isset($_POST['html-upload']) && !wp_doing_ajax()) { wp_die($file['error'] . ' <a href="javascript:history.go(-1)">' . __('Back') . '</a>'); } return $file; }
/** * Send a JSON response back to an Ajax request. * * @since 3.5.0 * @since 4.7.0 The `$status_code` parameter was added. * * @param mixed $response Variable (usually an array or object) to encode as JSON, * then print and die. * @param int $status_code The HTTP status code to output. */ function wp_send_json($response, $status_code = null) { @header('Content-Type: application/json; charset=' . get_option('blog_charset')); if (null !== $status_code) { status_header($status_code); } echo wp_json_encode($response); if (wp_doing_ajax()) { wp_die('', '', array('response' => null)); } else { die; } }
/** * Retrieves theme installer pages from the WordPress.org Themes API. * * It is possible for a theme to override the Themes API result with three * filters. Assume this is for themes, which can extend on the Theme Info to * offer more choices. This is very powerful and must be used with care, when * overriding the filters. * * The first filter, {@see 'themes_api_args'}, is for the args and gives the action * as the second parameter. The hook for {@see 'themes_api_args'} must ensure that * an object is returned. * * The second filter, {@see 'themes_api'}, allows a plugin to override the WordPress.org * Theme API entirely. If `$action` is 'query_themes', 'theme_information', or 'feature_list', * an object MUST be passed. If `$action` is 'hot_tags', an array should be passed. * * Finally, the third filter, {@see 'themes_api_result'}, makes it possible to filter the * response object or array, depending on the `$action` type. * * Supported arguments per action: * * | Argument Name | 'query_themes' | 'theme_information' | 'hot_tags' | 'feature_list' | * | -------------------| :------------: | :-----------------: | :--------: | :--------------: | * | `$slug` | No | Yes | No | No | * | `$per_page` | Yes | No | No | No | * | `$page` | Yes | No | No | No | * | `$number` | No | No | Yes | No | * | `$search` | Yes | No | No | No | * | `$tag` | Yes | No | No | No | * | `$author` | Yes | No | No | No | * | `$user` | Yes | No | No | No | * | `$browse` | Yes | No | No | No | * | `$locale` | Yes | Yes | No | No | * | `$fields` | Yes | Yes | No | No | * * @since 2.8.0 * * @param string $action API action to perform: 'query_themes', 'theme_information', * 'hot_tags' or 'feature_list'. * @param array|object $args { * Optional. Array or object of arguments to serialize for the Themes API. * * @type string $slug The theme slug. Default empty. * @type int $per_page Number of themes per page. Default 24. * @type int $page Number of current page. Default 1. * @type int $number Number of tags to be queried. * @type string $search A search term. Default empty. * @type string $tag Tag to filter themes. Default empty. * @type string $author Username of an author to filter themes. Default empty. * @type string $user Username to query for their favorites. Default empty. * @type string $browse Browse view: 'featured', 'popular', 'updated', 'favorites'. * @type string $locale Locale to provide context-sensitive results. Default is the value of get_locale(). * @type array $fields { * Array of fields which should or should not be returned. * * @type bool $description Whether to return the theme full description. Default false. * @type bool $sections Whether to return the theme readme sections: description, installation, * FAQ, screenshots, other notes, and changelog. Default false. * @type bool $rating Whether to return the rating in percent and total number of ratings. * Default false. * @type bool $ratings Whether to return the number of rating for each star (1-5). Default false. * @type bool $downloaded Whether to return the download count. Default false. * @type bool $downloadlink Whether to return the download link for the package. Default false. * @type bool $last_updated Whether to return the date of the last update. Default false. * @type bool $tags Whether to return the assigned tags. Default false. * @type bool $homepage Whether to return the theme homepage link. Default false. * @type bool $screenshots Whether to return the screenshots. Default false. * @type int $screenshot_count Number of screenshots to return. Default 1. * @type bool $screenshot_url Whether to return the URL of the first screenshot. Default false. * @type bool $photon_screenshots Whether to return the screenshots via Photon. Default false. * @type bool $template Whether to return the slug of the parent theme. Default false. * @type bool $parent Whether to return the slug, name and homepage of the parent theme. Default false. * @type bool $versions Whether to return the list of all available versions. Default false. * @type bool $theme_url Whether to return theme's URL. Default false. * @type bool $extended_author Whether to return nicename or nicename and display name. Default false. * } * } * @return object|array|WP_Error Response object or array on success, WP_Error on failure. See the * {@link https://developer.wordpress.org/reference/functions/themes_api/ function reference article} * for more information on the make-up of possible return objects depending on the value of `$action`. */ function themes_api($action, $args = array()) { if (is_array($args)) { $args = (object) $args; } if (!isset($args->per_page)) { $args->per_page = 24; } if (!isset($args->locale)) { $args->locale = get_user_locale(); } /** * Filters arguments used to query for installer pages from the WordPress.org Themes API. * * Important: An object MUST be returned to this filter. * * @since 2.8.0 * * @param object $args Arguments used to query for installer pages from the WordPress.org Themes API. * @param string $action Requested action. Likely values are 'theme_information', * 'feature_list', or 'query_themes'. */ $args = apply_filters('themes_api_args', $args, $action); /** * Filters whether to override the WordPress.org Themes API. * * Passing a non-false value will effectively short-circuit the WordPress.org API request. * * If `$action` is 'query_themes', 'theme_information', or 'feature_list', an object MUST * be passed. If `$action` is 'hot_tags', an array should be passed. * * @since 2.8.0 * * @param false|object|array $override Whether to override the WordPress.org Themes API. Default false. * @param string $action Requested action. Likely values are 'theme_information', * 'feature_list', or 'query_themes'. * @param object $args Arguments used to query for installer pages from the Themes API. */ $res = apply_filters('themes_api', false, $action, $args); if (!$res) { $url = $http_url = 'http://api.wordpress.org/themes/info/1.0/'; if ($ssl = wp_http_supports(array('ssl'))) { $url = set_url_scheme($url, 'https'); } $http_args = array('body' => array('action' => $action, 'request' => serialize($args))); $request = wp_remote_post($url, $http_args); if ($ssl && is_wp_error($request)) { if (!wp_doing_ajax()) { trigger_error(sprintf(__('An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.'), __('https://wordpress.org/support/')) . ' ' . __('(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)'), headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE); } $request = wp_remote_post($http_url, $http_args); } if (is_wp_error($request)) { $res = new WP_Error('themes_api_failed', sprintf(__('An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.'), __('https://wordpress.org/support/')), $request->get_error_message()); } else { $res = maybe_unserialize(wp_remote_retrieve_body($request)); if (!is_object($res) && !is_array($res)) { $res = new WP_Error('themes_api_failed', sprintf(__('An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.'), __('https://wordpress.org/support/')), wp_remote_retrieve_body($request)); } } } /** * Filters the returned WordPress.org Themes API response. * * @since 2.8.0 * * @param array|object|WP_Error $res WordPress.org Themes API response. * @param string $action Requested action. Likely values are 'theme_information', * 'feature_list', or 'query_themes'. * @param object $args Arguments used to query for installer pages from the WordPress.org Themes API. */ return apply_filters('themes_api_result', $res, $action, $args); }
/** * Set PHP error reporting based on WordPress debug settings. * * Uses three constants: `WP_DEBUG`, `WP_DEBUG_DISPLAY`, and `WP_DEBUG_LOG`. * All three can be defined in wp-config.php. By default, `WP_DEBUG` and * `WP_DEBUG_LOG` are set to false, and `WP_DEBUG_DISPLAY` is set to true. * * When `WP_DEBUG` is true, all PHP notices are reported. WordPress will also * display internal notices: when a deprecated WordPress function, function * argument, or file is used. Deprecated code may be removed from a later * version. * * It is strongly recommended that plugin and theme developers use `WP_DEBUG` * in their development environments. * * `WP_DEBUG_DISPLAY` and `WP_DEBUG_LOG` perform no function unless `WP_DEBUG` * is true. * * When `WP_DEBUG_DISPLAY` is true, WordPress will force errors to be displayed. * `WP_DEBUG_DISPLAY` defaults to true. Defining it as null prevents WordPress * from changing the global configuration setting. Defining `WP_DEBUG_DISPLAY` * as false will force errors to be hidden. * * When `WP_DEBUG_LOG` is true, errors will be logged to debug.log in the content * directory. * * Errors are never displayed for XML-RPC, REST, and Ajax requests. * * @since 3.0.0 * @access private */ function wp_debug_mode() { /** * Filters whether to allow the debug mode check to occur. * * This filter runs before it can be used by plugins. It is designed for * non-web run-times. Returning false causes the `WP_DEBUG` and related * constants to not be checked and the default php values for errors * will be used unless you take care to update them yourself. * * @since 4.6.0 * * @param bool $enable_debug_mode Whether to enable debug mode checks to occur. Default true. */ if (!apply_filters('enable_wp_debug_mode_checks', true)) { return; } if (WP_DEBUG) { error_reporting(E_ALL); if (WP_DEBUG_DISPLAY) { ini_set('display_errors', 1); } elseif (null !== WP_DEBUG_DISPLAY) { ini_set('display_errors', 0); } if (WP_DEBUG_LOG) { ini_set('log_errors', 1); ini_set('error_log', WP_CONTENT_DIR . '/debug.log'); } } else { error_reporting(E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_ERROR | E_WARNING | E_PARSE | E_USER_ERROR | E_USER_WARNING | E_RECOVERABLE_ERROR); } if (defined('XMLRPC_REQUEST') || defined('REST_REQUEST') || defined('WP_INSTALLING') && WP_INSTALLING || wp_doing_ajax()) { @ini_set('display_errors', 0); } }
/** * Return true if it's an Ajax request. * * @since 3.4.0 * @since 4.2.0 Added `$action` param. * @access public * * @param string|null $action Whether the supplied Ajax action is being run. * @return bool True if it's an Ajax request, false otherwise. */ public function doing_ajax($action = null) { if (!wp_doing_ajax()) { return false; } if (!$action) { return true; } else { /* * Note: we can't just use doing_action( "wp_ajax_{$action}" ) because we need * to check before admin-ajax.php gets to that point. */ return isset($_REQUEST['action']) && wp_unslash($_REQUEST['action']) === $action; } }
/** * Send a JSON response back to an Ajax request. * * @since 3.5.0 * * @param mixed $response Variable (usually an array or object) to encode as JSON, * then print and die. */ function wp_send_json($response) { @header('Content-Type: application/json; charset=' . get_option('blog_charset')); echo wp_json_encode($response); if (wp_doing_ajax()) { wp_die(); } else { die; } }
/** * Saves and restores user interface settings stored in a cookie. * * Checks if the current user-settings cookie is updated and stores it. When no * cookie exists (different browser used), adds the last saved cookie restoring * the settings. * * @since 2.7.0 */ function wp_user_settings() { if (!is_admin() || wp_doing_ajax()) { return; } if (!($user_id = get_current_user_id())) { return; } if (is_super_admin() && !is_user_member_of_blog()) { return; } $settings = (string) get_user_option('user-settings', $user_id); if (isset($_COOKIE['wp-settings-' . $user_id])) { $cookie = preg_replace('/[^A-Za-z0-9=&_]/', '', $_COOKIE['wp-settings-' . $user_id]); // No change or both empty if ($cookie == $settings) { return; } $last_saved = (int) get_user_option('user-settings-time', $user_id); $current = isset($_COOKIE['wp-settings-time-' . $user_id]) ? preg_replace('/[^0-9]/', '', $_COOKIE['wp-settings-time-' . $user_id]) : 0; // The cookie is newer than the saved value. Update the user_option and leave the cookie as-is if ($current > $last_saved) { update_user_option($user_id, 'user-settings', $cookie, false); update_user_option($user_id, 'user-settings-time', time() - 5, false); return; } } // The cookie is not set in the current browser or the saved value is newer. $secure = 'https' === parse_url(admin_url(), PHP_URL_SCHEME); setcookie('wp-settings-' . $user_id, $settings, time() + YEAR_IN_SECONDS, SITECOOKIEPATH, null, $secure); setcookie('wp-settings-time-' . $user_id, time(), time() + YEAR_IN_SECONDS, SITECOOKIEPATH, null, $secure); $_COOKIE['wp-settings-' . $user_id] = $settings; }
/** * Clear existing update caches for plugins, themes, and core. * * @since 4.1.0 */ function wp_clean_update_cache() { if (function_exists('wp_clean_plugins_cache')) { wp_clean_plugins_cache(); } else { delete_site_transient('update_plugins'); } wp_clean_themes_cache(); delete_site_transient('update_core'); } if (!is_main_site() && !is_network_admin() || wp_doing_ajax()) { return; } add_action('admin_init', '_maybe_update_core'); add_action('wp_version_check', 'wp_version_check'); add_action('load-plugins.php', 'wp_update_plugins'); add_action('load-update.php', 'wp_update_plugins'); add_action('load-update-core.php', 'wp_update_plugins'); add_action('admin_init', '_maybe_update_plugins'); add_action('wp_update_plugins', 'wp_update_plugins'); add_action('load-themes.php', 'wp_update_themes'); add_action('load-update.php', 'wp_update_themes'); add_action('load-update-core.php', 'wp_update_themes'); add_action('admin_init', '_maybe_update_themes'); add_action('wp_update_themes', 'wp_update_themes'); add_action('update_option_WPLANG', 'wp_clean_update_cache', 10, 0);
/** * Checks to see if all of the feed url in $check_urls are cached. * * If $check_urls is empty, look for the rss feed url found in the dashboard * widget options of $widget_id. If cached, call $callback, a function that * echoes out output for this widget. If not cache, echo a "Loading..." stub * which is later replaced by Ajax call (see top of /wp-admin/index.php) * * @since 2.5.0 * * @param string $widget_id * @param callable $callback * @param array $check_urls RSS feeds * @return bool False on failure. True on success. */ function wp_dashboard_cached_rss_widget($widget_id, $callback, $check_urls = array()) { $loading = '<p class="widget-loading hide-if-no-js">' . __('Loading…') . '</p><p class="hide-if-js">' . __('This widget requires JavaScript.') . '</p>'; $doing_ajax = wp_doing_ajax(); if (empty($check_urls)) { $widgets = get_option('dashboard_widget_options'); if (empty($widgets[$widget_id]['url']) && !$doing_ajax) { echo $loading; return false; } $check_urls = array($widgets[$widget_id]['url']); } $locale = get_locale(); $cache_key = 'dash_' . md5($widget_id . '_' . $locale); if (false !== ($output = get_transient($cache_key))) { echo $output; return true; } if (!$doing_ajax) { echo $loading; return false; } if ($callback && is_callable($callback)) { $args = array_slice(func_get_args(), 3); array_unshift($args, $widget_id, $check_urls); ob_start(); call_user_func_array($callback, $args); set_transient($cache_key, ob_get_flush(), 12 * HOUR_IN_SECONDS); // Default lifetime in cache of 12 hours (same as the feeds) } return true; }
/** * Display XML formatted responses. * * Sets the content type header to text/xml. * * @since 2.1.0 */ public function send() { header('Content-Type: text/xml; charset=' . get_option('blog_charset')); echo "<?xml version='1.0' encoding='" . get_option('blog_charset') . "' standalone='yes'?><wp_ajax>"; foreach ((array) $this->responses as $response) { echo $response; } echo '</wp_ajax>'; if (wp_doing_ajax()) { wp_die(); } else { die; } }
/** * Generate and display row actions links. * * @since 4.3.0 * @access protected * * @global string $comment_status Status for the current listed comments. * * @param WP_Comment $comment The comment object. * @param string $column_name Current column name. * @param string $primary Primary column name. * @return string|void Comment row actions output. */ protected function handle_row_actions($comment, $column_name, $primary) { global $comment_status; if ($primary !== $column_name) { return ''; } if (!$this->user_can) { return; } $the_comment_status = wp_get_comment_status($comment); $out = ''; $del_nonce = esc_html('_wpnonce=' . wp_create_nonce("delete-comment_{$comment->comment_ID}")); $approve_nonce = esc_html('_wpnonce=' . wp_create_nonce("approve-comment_{$comment->comment_ID}")); $url = "comment.php?c={$comment->comment_ID}"; $approve_url = esc_url($url . "&action=approvecomment&{$approve_nonce}"); $unapprove_url = esc_url($url . "&action=unapprovecomment&{$approve_nonce}"); $spam_url = esc_url($url . "&action=spamcomment&{$del_nonce}"); $unspam_url = esc_url($url . "&action=unspamcomment&{$del_nonce}"); $trash_url = esc_url($url . "&action=trashcomment&{$del_nonce}"); $untrash_url = esc_url($url . "&action=untrashcomment&{$del_nonce}"); $delete_url = esc_url($url . "&action=deletecomment&{$del_nonce}"); // Preorder it: Approve | Reply | Quick Edit | Edit | Spam | Trash. $actions = array('approve' => '', 'unapprove' => '', 'reply' => '', 'quickedit' => '', 'edit' => '', 'spam' => '', 'unspam' => '', 'trash' => '', 'untrash' => '', 'delete' => ''); // Not looking at all comments. if ($comment_status && 'all' != $comment_status) { if ('approved' === $the_comment_status) { $actions['unapprove'] = "<a href='{$unapprove_url}' data-wp-lists='delete:the-comment-list:comment-{$comment->comment_ID}:e7e7d3:action=dim-comment&new=unapproved' class='vim-u vim-destructive' aria-label='" . esc_attr__('Unapprove this comment') . "'>" . __('Unapprove') . '</a>'; } elseif ('unapproved' === $the_comment_status) { $actions['approve'] = "<a href='{$approve_url}' data-wp-lists='delete:the-comment-list:comment-{$comment->comment_ID}:e7e7d3:action=dim-comment&new=approved' class='vim-a vim-destructive' aria-label='" . esc_attr__('Approve this comment') . "'>" . __('Approve') . '</a>'; } } else { $actions['approve'] = "<a href='{$approve_url}' data-wp-lists='dim:the-comment-list:comment-{$comment->comment_ID}:unapproved:e7e7d3:e7e7d3:new=approved' class='vim-a' aria-label='" . esc_attr__('Approve this comment') . "'>" . __('Approve') . '</a>'; $actions['unapprove'] = "<a href='{$unapprove_url}' data-wp-lists='dim:the-comment-list:comment-{$comment->comment_ID}:unapproved:e7e7d3:e7e7d3:new=unapproved' class='vim-u' aria-label='" . esc_attr__('Unapprove this comment') . "'>" . __('Unapprove') . '</a>'; } if ('spam' !== $the_comment_status) { $actions['spam'] = "<a href='{$spam_url}' data-wp-lists='delete:the-comment-list:comment-{$comment->comment_ID}::spam=1' class='vim-s vim-destructive' aria-label='" . esc_attr__('Mark this comment as spam') . "'>" . _x('Spam', 'verb') . '</a>'; } elseif ('spam' === $the_comment_status) { $actions['unspam'] = "<a href='{$unspam_url}' data-wp-lists='delete:the-comment-list:comment-{$comment->comment_ID}:66cc66:unspam=1' class='vim-z vim-destructive' aria-label='" . esc_attr__('Restore this comment from the spam') . "'>" . _x('Not Spam', 'comment') . '</a>'; } if ('trash' === $the_comment_status) { $actions['untrash'] = "<a href='{$untrash_url}' data-wp-lists='delete:the-comment-list:comment-{$comment->comment_ID}:66cc66:untrash=1' class='vim-z vim-destructive' aria-label='" . esc_attr__('Restore this comment from the Trash') . "'>" . __('Restore') . '</a>'; } if ('spam' === $the_comment_status || 'trash' === $the_comment_status || !EMPTY_TRASH_DAYS) { $actions['delete'] = "<a href='{$delete_url}' data-wp-lists='delete:the-comment-list:comment-{$comment->comment_ID}::delete=1' class='delete vim-d vim-destructive' aria-label='" . esc_attr__('Delete this comment permanently') . "'>" . __('Delete Permanently') . '</a>'; } else { $actions['trash'] = "<a href='{$trash_url}' data-wp-lists='delete:the-comment-list:comment-{$comment->comment_ID}::trash=1' class='delete vim-d vim-destructive' aria-label='" . esc_attr__('Move this comment to the Trash') . "'>" . _x('Trash', 'verb') . '</a>'; } if ('spam' !== $the_comment_status && 'trash' !== $the_comment_status) { $actions['edit'] = "<a href='comment.php?action=editcomment&c={$comment->comment_ID}' aria-label='" . esc_attr__('Edit this comment') . "'>" . __('Edit') . '</a>'; $format = '<a data-comment-id="%d" data-post-id="%d" data-action="%s" class="%s" aria-label="%s" href="#">%s</a>'; $actions['quickedit'] = sprintf($format, $comment->comment_ID, $comment->comment_post_ID, 'edit', 'vim-q comment-inline', esc_attr__('Quick edit this comment inline'), __('Quick Edit')); $actions['reply'] = sprintf($format, $comment->comment_ID, $comment->comment_post_ID, 'replyto', 'vim-r comment-inline', esc_attr__('Reply to this comment'), __('Reply')); } /** This filter is documented in wp-admin/includes/dashboard.php */ $actions = apply_filters('comment_row_actions', array_filter($actions), $comment); $i = 0; $out .= '<div class="row-actions">'; foreach ($actions as $action => $link) { ++$i; ('approve' === $action || 'unapprove' === $action) && 2 === $i || 1 === $i ? $sep = '' : ($sep = ' | '); // Reply and quickedit need a hide-if-no-js span when not added with ajax if (('reply' === $action || 'quickedit' === $action) && !wp_doing_ajax()) { $action .= ' hide-if-no-js'; } elseif ($action === 'untrash' && $the_comment_status === 'trash' || $action === 'unspam' && $the_comment_status === 'spam') { if ('1' == get_comment_meta($comment->comment_ID, '_wp_trash_meta_status', true)) { $action .= ' approve'; } else { $action .= ' unapprove'; } } $out .= "<span class='{$action}'>{$sep}{$link}</span>"; } $out .= '</div>'; $out .= '<button type="button" class="toggle-row"><span class="screen-reader-text">' . __('Show more details') . '</span></button>'; return $out; }
/** * An internal method that sets all the necessary pagination arguments * * @since 3.1.0 * @access protected * * @param array|string $args Array or string of arguments with information about the pagination. */ protected function set_pagination_args($args) { $args = wp_parse_args($args, array('total_items' => 0, 'total_pages' => 0, 'per_page' => 0)); if (!$args['total_pages'] && $args['per_page'] > 0) { $args['total_pages'] = ceil($args['total_items'] / $args['per_page']); } // Redirect if page number is invalid and headers are not already sent. if (!headers_sent() && !wp_doing_ajax() && $args['total_pages'] > 0 && $this->get_pagenum() > $args['total_pages']) { wp_redirect(add_query_arg('paged', $args['total_pages'])); exit; } $this->_pagination_args = $args; }
/** * Check whether comment flooding is occurring. * * Won't run, if current user can manage options, so to not block * administrators. * * @since 2.3.0 * * @global wpdb $wpdb WordPress database abstraction object. * * @param string $ip Comment IP. * @param string $email Comment author email address. * @param string $date MySQL time string. */ function check_comment_flood_db($ip, $email, $date) { global $wpdb; // don't throttle admins or moderators if (current_user_can('manage_options') || current_user_can('moderate_comments')) { return; } $hour_ago = gmdate('Y-m-d H:i:s', time() - HOUR_IN_SECONDS); if (is_user_logged_in()) { $user = get_current_user_id(); $check_column = '`user_id`'; } else { $user = $ip; $check_column = '`comment_author_IP`'; } $sql = $wpdb->prepare("SELECT `comment_date_gmt` FROM `{$wpdb->comments}` WHERE `comment_date_gmt` >= %s AND ( {$check_column} = %s OR `comment_author_email` = %s ) ORDER BY `comment_date_gmt` DESC LIMIT 1", $hour_ago, $user, $email); $lasttime = $wpdb->get_var($sql); if ($lasttime) { $time_lastcomment = mysql2date('U', $lasttime, false); $time_newcomment = mysql2date('U', $date, false); /** * Filters the comment flood status. * * @since 2.1.0 * * @param bool $bool Whether a comment flood is occurring. Default false. * @param int $time_lastcomment Timestamp of when the last comment was posted. * @param int $time_newcomment Timestamp of when the new comment was posted. */ $flood_die = apply_filters('comment_flood_filter', false, $time_lastcomment, $time_newcomment); if ($flood_die) { /** * Fires before the comment flood message is triggered. * * @since 1.5.0 * * @param int $time_lastcomment Timestamp of when the last comment was posted. * @param int $time_newcomment Timestamp of when the new comment was posted. */ do_action('comment_flood_trigger', $time_lastcomment, $time_newcomment); if (wp_doing_ajax()) { die(__('You are posting comments too quickly. Slow down.')); } wp_die(__('You are posting comments too quickly. Slow down.'), 429); } } }
/** * Generates and displays row action links. * * @since 4.3.0 * @access protected * * @param WP_Term $tag Tag being acted upon. * @param string $column_name Current column name. * @param string $primary Primary column name. * @return string Row actions output for terms. */ protected function handle_row_actions($tag, $column_name, $primary) { if ($primary !== $column_name) { return ''; } $taxonomy = $this->screen->taxonomy; $tax = get_taxonomy($taxonomy); $default_term = get_option('default_' . $taxonomy); $uri = wp_doing_ajax() ? wp_get_referer() : $_SERVER['REQUEST_URI']; $edit_link = add_query_arg('wp_http_referer', urlencode(wp_unslash($uri)), get_edit_term_link($tag->term_id, $taxonomy, $this->screen->post_type)); $actions = array(); if (current_user_can($tax->cap->edit_terms)) { $actions['edit'] = sprintf('<a href="%s" aria-label="%s">%s</a>', esc_url($edit_link), esc_attr(sprintf(__('Edit “%s”'), $tag->name)), __('Edit')); $actions['inline hide-if-no-js'] = sprintf('<a href="#" class="editinline aria-button-if-js" aria-label="%s">%s</a>', esc_attr(sprintf(__('Quick edit “%s” inline'), $tag->name)), __('Quick Edit')); } if (current_user_can($tax->cap->delete_terms) && $tag->term_id != $default_term) { $actions['delete'] = sprintf('<a href="%s" class="delete-tag aria-button-if-js" aria-label="%s">%s</a>', wp_nonce_url("edit-tags.php?action=delete&taxonomy={$taxonomy}&tag_ID={$tag->term_id}", 'delete-tag_' . $tag->term_id), esc_attr(sprintf(__('Delete “%s”'), $tag->name)), __('Delete')); } if ($tax->public) { $actions['view'] = sprintf('<a href="%s" aria-label="%s">%s</a>', get_term_link($tag), esc_attr(sprintf(__('View “%s” archive'), $tag->name)), __('View')); } /** * Filters the action links displayed for each term in the Tags list table. * * @since 2.8.0 * @deprecated 3.0.0 Use {$taxonomy}_row_actions instead. * * @param array $actions An array of action links to be displayed. Default * 'Edit', 'Quick Edit', 'Delete', and 'View'. * @param WP_Term $tag Term object. */ $actions = apply_filters('tag_row_actions', $actions, $tag); /** * Filters the action links displayed for each term in the terms list table. * * The dynamic portion of the hook name, `$taxonomy`, refers to the taxonomy slug. * * @since 3.0.0 * * @param array $actions An array of action links to be displayed. Default * 'Edit', 'Quick Edit', 'Delete', and 'View'. * @param WP_Term $tag Term object. */ $actions = apply_filters("{$taxonomy}_row_actions", $actions, $tag); return $this->row_actions($actions); }
/** * Verifies the Ajax request to prevent processing requests external of the blog. * * @since 2.0.3 * * @param int|string $action Action nonce. * @param false|string $query_arg Optional. Key to check for the nonce in `$_REQUEST` (since 2.5). If false, * `$_REQUEST` values will be evaluated for '_ajax_nonce', and '_wpnonce' * (in that order). Default false. * @param bool $die Optional. Whether to die early when the nonce cannot be verified. * Default true. * @return false|int False if the nonce is invalid, 1 if the nonce is valid and generated between * 0-12 hours ago, 2 if the nonce is valid and generated between 12-24 hours ago. */ function check_ajax_referer($action = -1, $query_arg = false, $die = true) { if (-1 == $action) { _doing_it_wrong(__FUNCTION__, __('You should specify a nonce action to be verified by using the first parameter.'), '4.7'); } $nonce = ''; if ($query_arg && isset($_REQUEST[$query_arg])) { $nonce = $_REQUEST[$query_arg]; } elseif (isset($_REQUEST['_ajax_nonce'])) { $nonce = $_REQUEST['_ajax_nonce']; } elseif (isset($_REQUEST['_wpnonce'])) { $nonce = $_REQUEST['_wpnonce']; } $result = wp_verify_nonce($nonce, $action); /** * Fires once the Ajax request has been validated or not. * * @since 2.1.0 * * @param string $action The Ajax nonce action. * @param false|int $result False if the nonce is invalid, 1 if the nonce is valid and generated between * 0-12 hours ago, 2 if the nonce is valid and generated between 12-24 hours ago. */ do_action('check_ajax_referer', $action, $result); if ($die && false === $result) { if (wp_doing_ajax()) { wp_die(-1, 403); } else { die('-1'); } } return $result; }
/** * Verifies the Ajax request to prevent processing requests external of the blog. * * @since 2.0.3 * * @param int|string $action Action nonce. * @param false|string $query_arg Optional. Key to check for the nonce in `$_REQUEST` (since 2.5). If false, * `$_REQUEST` values will be evaluated for '_ajax_nonce', and '_wpnonce' * (in that order). Default false. * @param bool $die Optional. Whether to die early when the nonce cannot be verified. * Default true. * @return false|int False if the nonce is invalid, 1 if the nonce is valid and generated between * 0-12 hours ago, 2 if the nonce is valid and generated between 12-24 hours ago. */ function check_ajax_referer($action = -1, $query_arg = false, $die = true) { $nonce = ''; if ($query_arg && isset($_REQUEST[$query_arg])) { $nonce = $_REQUEST[$query_arg]; } elseif (isset($_REQUEST['_ajax_nonce'])) { $nonce = $_REQUEST['_ajax_nonce']; } elseif (isset($_REQUEST['_wpnonce'])) { $nonce = $_REQUEST['_wpnonce']; } $result = wp_verify_nonce($nonce, $action); /** * Fires once the Ajax request has been validated or not. * * @since 2.1.0 * * @param string $action The Ajax nonce action. * @param false|int $result False if the nonce is invalid, 1 if the nonce is valid and generated between * 0-12 hours ago, 2 if the nonce is valid and generated between 12-24 hours ago. */ do_action('check_ajax_referer', $action, $result); if ($die && false === $result) { if (wp_doing_ajax()) { wp_die(-1); } else { die('-1'); } } return $result; }