+
+/**
+ * Load the auth check for monitoring whether the user is still logged in.
+ *
+ * Can be disabled with remove_action( 'admin_enqueue_scripts', 'wp_auth_check_load' );
+ *
+ * This is disabled for certain screens where a login screen could cause an
+ * inconvenient interruption. A filter called {@see 'wp_auth_check_load'} can be used
+ * for fine-grained control.
+ *
+ * @since 3.6.0
+ */
+function wp_auth_check_load() {
+ if ( ! is_admin() && ! is_user_logged_in() )
+ return;
+
+ if ( defined( 'IFRAME_REQUEST' ) )
+ return;
+
+ $screen = get_current_screen();
+ $hidden = array( 'update', 'update-network', 'update-core', 'update-core-network', 'upgrade', 'upgrade-network', 'network' );
+ $show = ! in_array( $screen->id, $hidden );
+
+ /**
+ * Filters whether to load the authentication check.
+ *
+ * Passing a falsey value to the filter will effectively short-circuit
+ * loading the authentication check.
+ *
+ * @since 3.6.0
+ *
+ * @param bool $show Whether to load the authentication check.
+ * @param WP_Screen $screen The current screen object.
+ */
+ if ( apply_filters( 'wp_auth_check_load', $show, $screen ) ) {
+ wp_enqueue_style( 'wp-auth-check' );
+ wp_enqueue_script( 'wp-auth-check' );
+
+ add_action( 'admin_print_footer_scripts', 'wp_auth_check_html', 5 );
+ add_action( 'wp_print_footer_scripts', 'wp_auth_check_html', 5 );
+ }
+}
+
+/**
+ * Output the HTML that shows the wp-login dialog when the user is no longer logged in.
+ *
+ * @since 3.6.0
+ */
+function wp_auth_check_html() {
+ $login_url = wp_login_url();
+ $current_domain = ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'];
+ $same_domain = ( strpos( $login_url, $current_domain ) === 0 );
+
+ /**
+ * Filters whether the authentication check originated at the same domain.
+ *
+ * @since 3.6.0
+ *
+ * @param bool $same_domain Whether the authentication check originated at the same domain.
+ */
+ $same_domain = apply_filters( 'wp_auth_check_same_domain', $same_domain );
+ $wrap_class = $same_domain ? 'hidden' : 'hidden fallback';
+
+ ?>
+ <div id="wp-auth-check-wrap" class="<?php echo $wrap_class; ?>">
+ <div id="wp-auth-check-bg"></div>
+ <div id="wp-auth-check">
+ <button type="button" class="wp-auth-check-close button-link"><span class="screen-reader-text"><?php _e( 'Close dialog' ); ?></span></button>
+ <?php
+
+ if ( $same_domain ) {
+ ?>
+ <div id="wp-auth-check-form" class="loading" data-src="<?php echo esc_url( add_query_arg( array( 'interim-login' => 1 ), $login_url ) ); ?>"></div>
+ <?php
+ }
+
+ ?>
+ <div class="wp-auth-fallback">
+ <p><b class="wp-auth-fallback-expired" tabindex="0"><?php _e('Session expired'); ?></b></p>
+ <p><a href="<?php echo esc_url( $login_url ); ?>" target="_blank"><?php _e('Please log in again.'); ?></a>
+ <?php _e('The login page will open in a new window. After logging in you can close it and return to this page.'); ?></p>
+ </div>
+ </div>
+ </div>
+ <?php
+}
+
+/**
+ * Check whether a user is still logged in, for the heartbeat.
+ *
+ * Send a result that shows a log-in box if the user is no longer logged in,
+ * or if their cookie is within the grace period.
+ *
+ * @since 3.6.0
+ *
+ * @global int $login_grace_period
+ *
+ * @param array $response The Heartbeat response.
+ * @return array $response The Heartbeat response with 'wp-auth-check' value set.
+ */
+function wp_auth_check( $response ) {
+ $response['wp-auth-check'] = is_user_logged_in() && empty( $GLOBALS['login_grace_period'] );
+ return $response;
+}
+
+/**
+ * Return RegEx body to liberally match an opening HTML tag.
+ *
+ * Matches an opening HTML tag that:
+ * 1. Is self-closing or
+ * 2. Has no body but has a closing tag of the same name or
+ * 3. Contains a body and a closing tag of the same name
+ *
+ * Note: this RegEx does not balance inner tags and does not attempt
+ * to produce valid HTML
+ *
+ * @since 3.6.0
+ *
+ * @param string $tag An HTML tag name. Example: 'video'.
+ * @return string Tag RegEx.
+ */
+function get_tag_regex( $tag ) {
+ if ( empty( $tag ) )
+ return;
+ return sprintf( '<%1$s[^<]*(?:>[\s\S]*<\/%1$s>|\s*\/>)', tag_escape( $tag ) );
+}
+
+/**
+ * Retrieve a canonical form of the provided charset appropriate for passing to PHP
+ * functions such as htmlspecialchars() and charset html attributes.
+ *
+ * @since 3.6.0
+ * @access private
+ *
+ * @see https://core.trac.wordpress.org/ticket/23688
+ *
+ * @param string $charset A charset name.
+ * @return string The canonical form of the charset.
+ */
+function _canonical_charset( $charset ) {
+ if ( 'UTF-8' === $charset || 'utf-8' === $charset || 'utf8' === $charset ||
+ 'UTF8' === $charset )
+ return 'UTF-8';
+
+ if ( 'ISO-8859-1' === $charset || 'iso-8859-1' === $charset ||
+ 'iso8859-1' === $charset || 'ISO8859-1' === $charset )
+ return 'ISO-8859-1';
+
+ return $charset;
+}
+
+/**
+ * Set the mbstring internal encoding to a binary safe encoding when func_overload
+ * is enabled.
+ *
+ * When mbstring.func_overload is in use for multi-byte encodings, the results from
+ * strlen() and similar functions respect the utf8 characters, causing binary data
+ * to return incorrect lengths.
+ *
+ * This function overrides the mbstring encoding to a binary-safe encoding, and
+ * resets it to the users expected encoding afterwards through the
+ * `reset_mbstring_encoding` function.
+ *
+ * It is safe to recursively call this function, however each
+ * `mbstring_binary_safe_encoding()` call must be followed up with an equal number
+ * of `reset_mbstring_encoding()` calls.
+ *
+ * @since 3.7.0
+ *
+ * @see reset_mbstring_encoding()
+ *
+ * @staticvar array $encodings
+ * @staticvar bool $overloaded
+ *
+ * @param bool $reset Optional. Whether to reset the encoding back to a previously-set encoding.
+ * Default false.
+ */
+function mbstring_binary_safe_encoding( $reset = false ) {
+ static $encodings = array();
+ static $overloaded = null;
+
+ if ( is_null( $overloaded ) )
+ $overloaded = function_exists( 'mb_internal_encoding' ) && ( ini_get( 'mbstring.func_overload' ) & 2 );
+
+ if ( false === $overloaded )
+ return;
+
+ if ( ! $reset ) {
+ $encoding = mb_internal_encoding();
+ array_push( $encodings, $encoding );
+ mb_internal_encoding( 'ISO-8859-1' );
+ }
+
+ if ( $reset && $encodings ) {
+ $encoding = array_pop( $encodings );
+ mb_internal_encoding( $encoding );
+ }
+}
+
+/**
+ * Reset the mbstring internal encoding to a users previously set encoding.
+ *
+ * @see mbstring_binary_safe_encoding()
+ *
+ * @since 3.7.0
+ */
+function reset_mbstring_encoding() {
+ mbstring_binary_safe_encoding( true );
+}
+
+/**
+ * Filter/validate a variable as a boolean.
+ *
+ * Alternative to `filter_var( $var, FILTER_VALIDATE_BOOLEAN )`.
+ *
+ * @since 4.0.0
+ *
+ * @param mixed $var Boolean value to validate.
+ * @return bool Whether the value is validated.
+ */
+function wp_validate_boolean( $var ) {
+ if ( is_bool( $var ) ) {
+ return $var;
+ }
+
+ if ( is_string( $var ) && 'false' === strtolower( $var ) ) {
+ return false;
+ }
+
+ return (bool) $var;
+}
+
+/**
+ * Delete a file
+ *
+ * @since 4.2.0
+ *
+ * @param string $file The path to the file to delete.
+ */
+function wp_delete_file( $file ) {
+ /**
+ * Filters the path of the file to delete.
+ *
+ * @since 2.1.0
+ *
+ * @param string $medium Path to the file to delete.
+ */
+ $delete = apply_filters( 'wp_delete_file', $file );
+ if ( ! empty( $delete ) ) {
+ @unlink( $delete );
+ }
+}
+
+/**
+ * Outputs a small JS snippet on preview tabs/windows to remove `window.name` on unload.
+ *
+ * This prevents reusing the same tab for a preview when the user has navigated away.
+ *
+ * @since 4.3.0
+ */
+function wp_post_preview_js() {
+ global $post;
+
+ if ( ! is_preview() || empty( $post ) ) {
+ return;
+ }
+
+ // Has to match the window name used in post_submit_meta_box()
+ $name = 'wp-preview-' . (int) $post->ID;
+
+ ?>
+ <script>
+ ( function() {
+ var query = document.location.search;
+
+ if ( query && query.indexOf( 'preview=true' ) !== -1 ) {
+ window.name = '<?php echo $name; ?>';
+ }
+
+ if ( window.addEventListener ) {
+ window.addEventListener( 'unload', function() { window.name = ''; }, false );
+ }
+ }());
+ </script>
+ <?php
+}
+
+/**
+ * Parses and formats a MySQL datetime (Y-m-d H:i:s) for ISO8601/RFC3339.
+ *
+ * Explicitly strips timezones, as datetimes are not saved with any timezone
+ * information. Including any information on the offset could be misleading.
+ *
+ * @since 4.4.0
+ *
+ * @param string $date_string Date string to parse and format.
+ * @return string Date formatted for ISO8601/RFC3339.
+ */
+function mysql_to_rfc3339( $date_string ) {
+ $formatted = mysql2date( 'c', $date_string, false );
+
+ // Strip timezone information
+ return preg_replace( '/(?:Z|[+-]\d{2}(?::\d{2})?)$/', '', $formatted );
+}
+
+/**
+ * Attempts to raise the PHP memory limit for memory intensive processes.
+ *
+ * Only allows raising the existing limit and prevents lowering it.
+ *
+ * @since 4.6.0
+ *
+ * @param string $context Optional. Context in which the function is called. Accepts either 'admin',
+ * 'image', or an arbitrary other context. If an arbitrary context is passed,
+ * the similarly arbitrary {@see '{$context}_memory_limit'} filter will be
+ * invoked. Default 'admin'.
+ * @return bool|int|string The limit that was set or false on failure.
+ */
+function wp_raise_memory_limit( $context = 'admin' ) {
+ // Exit early if the limit cannot be changed.
+ if ( false === wp_is_ini_value_changeable( 'memory_limit' ) ) {
+ return false;
+ }
+
+ $current_limit = @ini_get( 'memory_limit' );
+ $current_limit_int = wp_convert_hr_to_bytes( $current_limit );
+
+ if ( -1 === $current_limit_int ) {
+ return false;
+ }
+
+ $wp_max_limit = WP_MAX_MEMORY_LIMIT;
+ $wp_max_limit_int = wp_convert_hr_to_bytes( $wp_max_limit );
+ $filtered_limit = $wp_max_limit;
+
+ switch ( $context ) {
+ case 'admin':
+ /**
+ * Filters the maximum memory limit available for administration screens.
+ *
+ * This only applies to administrators, who may require more memory for tasks
+ * like updates. Memory limits when processing images (uploaded or edited by
+ * users of any role) are handled separately.
+ *
+ * The `WP_MAX_MEMORY_LIMIT` constant specifically defines the maximum memory
+ * limit available when in the administration back end. The default is 256M
+ * (256 megabytes of memory) or the original `memory_limit` php.ini value if
+ * this is higher.
+ *
+ * @since 3.0.0
+ * @since 4.6.0 The default now takes the original `memory_limit` into account.
+ *
+ * @param int|string $filtered_limit The maximum WordPress memory limit. Accepts an integer
+ * (bytes), or a shorthand string notation, such as '256M'.
+ */
+ $filtered_limit = apply_filters( 'admin_memory_limit', $filtered_limit );
+ break;
+
+ case 'image':
+ /**
+ * Filters the memory limit allocated for image manipulation.
+ *
+ * @since 3.5.0
+ * @since 4.6.0 The default now takes the original `memory_limit` into account.
+ *
+ * @param int|string $filtered_limit Maximum memory limit to allocate for images.
+ * Default `WP_MAX_MEMORY_LIMIT` or the original
+ * php.ini `memory_limit`, whichever is higher.
+ * Accepts an integer (bytes), or a shorthand string
+ * notation, such as '256M'.
+ */
+ $filtered_limit = apply_filters( 'image_memory_limit', $filtered_limit );
+ break;
+
+ default:
+ /**
+ * Filters the memory limit allocated for arbitrary contexts.
+ *
+ * The dynamic portion of the hook name, `$context`, refers to an arbitrary
+ * context passed on calling the function. This allows for plugins to define
+ * their own contexts for raising the memory limit.
+ *
+ * @since 4.6.0
+ *
+ * @param int|string $filtered_limit Maximum memory limit to allocate for images.
+ * Default '256M' or the original php.ini `memory_limit`,
+ * whichever is higher. Accepts an integer (bytes), or a
+ * shorthand string notation, such as '256M'.
+ */
+ $filtered_limit = apply_filters( "{$context}_memory_limit", $filtered_limit );
+ break;
+ }
+
+ $filtered_limit_int = wp_convert_hr_to_bytes( $filtered_limit );
+
+ if ( -1 === $filtered_limit_int || ( $filtered_limit_int > $wp_max_limit_int && $filtered_limit_int > $current_limit_int ) ) {
+ if ( false !== @ini_set( 'memory_limit', $filtered_limit ) ) {
+ return $filtered_limit;
+ } else {
+ return false;
+ }
+ } elseif ( -1 === $wp_max_limit_int || $wp_max_limit_int > $current_limit_int ) {
+ if ( false !== @ini_set( 'memory_limit', $wp_max_limit ) ) {
+ return $wp_max_limit;
+ } else {
+ return false;
+ }
+ }
+
+ return false;
+}