+
+/**
+ * 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 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 );
+
+ /**
+ * Filter 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 );
+
+ /**
+ * Filter 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 ) {
+ /**
+ * Filter 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 );
+}