+/**
+ * WordPress implementation of PHP sprintf() with filters.
+ *
+ * @since 2.5.0
+ * @link http://www.php.net/sprintf
+ *
+ * @param string $pattern The string which formatted args are inserted.
+ * @param mixed $args,... Arguments to be formatted into the $pattern string.
+ * @return string The formatted string.
+ */
+function wp_sprintf( $pattern ) {
+ $args = func_get_args();
+ $len = strlen($pattern);
+ $start = 0;
+ $result = '';
+ $arg_index = 0;
+ while ( $len > $start ) {
+ // Last character: append and break
+ if ( strlen($pattern) - 1 == $start ) {
+ $result .= substr($pattern, -1);
+ break;
+ }
+
+ // Literal %: append and continue
+ if ( substr($pattern, $start, 2) == '%%' ) {
+ $start += 2;
+ $result .= '%';
+ continue;
+ }
+
+ // Get fragment before next %
+ $end = strpos($pattern, '%', $start + 1);
+ if ( false === $end )
+ $end = $len;
+ $fragment = substr($pattern, $start, $end - $start);
+
+ // Fragment has a specifier
+ if ( $pattern[$start] == '%' ) {
+ // Find numbered arguments or take the next one in order
+ if ( preg_match('/^%(\d+)\$/', $fragment, $matches) ) {
+ $arg = isset($args[$matches[1]]) ? $args[$matches[1]] : '';
+ $fragment = str_replace("%{$matches[1]}$", '%', $fragment);
+ } else {
+ ++$arg_index;
+ $arg = isset($args[$arg_index]) ? $args[$arg_index] : '';
+ }
+
+ // Apply filters OR sprintf
+ $_fragment = apply_filters( 'wp_sprintf', $fragment, $arg );
+ if ( $_fragment != $fragment )
+ $fragment = $_fragment;
+ else
+ $fragment = sprintf($fragment, strval($arg) );
+ }
+
+ // Append to result and move to next fragment
+ $result .= $fragment;
+ $start = $end;
+ }
+ return $result;
+}
+
+/**
+ * Localize list items before the rest of the content.
+ *
+ * The '%l' must be at the first characters can then contain the rest of the
+ * content. The list items will have ', ', ', and', and ' and ' added depending
+ * on the amount of list items in the $args parameter.
+ *
+ * @since 2.5.0
+ *
+ * @param string $pattern Content containing '%l' at the beginning.
+ * @param array $args List items to prepend to the content and replace '%l'.
+ * @return string Localized list items and rest of the content.
+ */
+function wp_sprintf_l($pattern, $args) {
+ // Not a match
+ if ( substr($pattern, 0, 2) != '%l' )
+ return $pattern;
+
+ // Nothing to work with
+ if ( empty($args) )
+ return '';
+
+ // Translate and filter the delimiter set (avoid ampersands and entities here)
+ $l = apply_filters('wp_sprintf_l', array(
+ /* translators: used between list items, there is a space after the comma */
+ 'between' => __(', '),
+ /* translators: used between list items, there is a space after the and */
+ 'between_last_two' => __(', and '),
+ /* translators: used between only two list items, there is a space after the and */
+ 'between_only_two' => __(' and '),
+ ));
+
+ $args = (array) $args;
+ $result = array_shift($args);
+ if ( count($args) == 1 )
+ $result .= $l['between_only_two'] . array_shift($args);
+ // Loop when more than two args
+ $i = count($args);
+ while ( $i ) {
+ $arg = array_shift($args);
+ $i--;
+ if ( 0 == $i )
+ $result .= $l['between_last_two'] . $arg;
+ else
+ $result .= $l['between'] . $arg;
+ }
+ return $result . substr($pattern, 2);
+}
+
+/**
+ * Safely extracts not more than the first $count characters from html string.
+ *
+ * UTF-8, tags and entities safe prefix extraction. Entities inside will *NOT*
+ * be counted as one character. For example & will be counted as 4, < as
+ * 3, etc.
+ *
+ * @since 2.5.0
+ *
+ * @param string $str String to get the excerpt from.
+ * @param integer $count Maximum number of characters to take.
+ * @param string $more Optional. What to append if $str needs to be trimmed. Defaults to empty string.
+ * @return string The excerpt.
+ */
+function wp_html_excerpt( $str, $count, $more = null ) {
+ if ( null === $more )
+ $more = '';
+ $str = wp_strip_all_tags( $str, true );
+ $excerpt = mb_substr( $str, 0, $count );
+ // remove part of an entity at the end
+ $excerpt = preg_replace( '/&[^;\s]{0,6}$/', '', $excerpt );
+ if ( $str != $excerpt )
+ $excerpt = trim( $excerpt ) . $more;
+ return $excerpt;
+}
+
+/**
+ * Add a Base url to relative links in passed content.
+ *
+ * By default it supports the 'src' and 'href' attributes. However this can be
+ * changed via the 3rd param.
+ *
+ * @since 2.7.0
+ *
+ * @param string $content String to search for links in.
+ * @param string $base The base URL to prefix to links.
+ * @param array $attrs The attributes which should be processed.
+ * @return string The processed content.
+ */
+function links_add_base_url( $content, $base, $attrs = array('src', 'href') ) {
+ global $_links_add_base;
+ $_links_add_base = $base;
+ $attrs = implode('|', (array)$attrs);
+ return preg_replace_callback( "!($attrs)=(['\"])(.+?)\\2!i", '_links_add_base', $content );
+}
+
+/**
+ * Callback to add a base url to relative links in passed content.
+ *
+ * @since 2.7.0
+ * @access private
+ *
+ * @param string $m The matched link.
+ * @return string The processed link.
+ */
+function _links_add_base($m) {
+ global $_links_add_base;
+ //1 = attribute name 2 = quotation mark 3 = URL
+ return $m[1] . '=' . $m[2] .
+ ( preg_match( '#^(\w{1,20}):#', $m[3], $protocol ) && in_array( $protocol[1], wp_allowed_protocols() ) ?
+ $m[3] :
+ path_join( $_links_add_base, $m[3] ) )
+ . $m[2];
+}
+
+/**
+ * Adds a Target attribute to all links in passed content.
+ *
+ * This function by default only applies to <a> tags, however this can be
+ * modified by the 3rd param.
+ *
+ * <b>NOTE:</b> Any current target attributed will be stripped and replaced.
+ *
+ * @since 2.7.0
+ *
+ * @param string $content String to search for links in.
+ * @param string $target The Target to add to the links.
+ * @param array $tags An array of tags to apply to.
+ * @return string The processed content.
+ */
+function links_add_target( $content, $target = '_blank', $tags = array('a') ) {
+ global $_links_add_target;
+ $_links_add_target = $target;
+ $tags = implode('|', (array)$tags);
+ return preg_replace_callback( "!<($tags)(.+?)>!i", '_links_add_target', $content );
+}
+
+/**
+ * Callback to add a target attribute to all links in passed content.
+ *
+ * @since 2.7.0
+ * @access private
+ *
+ * @param string $m The matched link.
+ * @return string The processed link.
+ */
+function _links_add_target( $m ) {
+ global $_links_add_target;
+ $tag = $m[1];
+ $link = preg_replace('|(target=([\'"])(.*?)\2)|i', '', $m[2]);
+ return '<' . $tag . $link . ' target="' . esc_attr( $_links_add_target ) . '">';
+}
+
+/**
+ * Normalize EOL characters and strip duplicate whitespace.
+ *
+ * @since 2.7.0
+ *
+ * @param string $str The string to normalize.
+ * @return string The normalized string.
+ */
+function normalize_whitespace( $str ) {
+ $str = trim( $str );
+ $str = str_replace( "\r", "\n", $str );
+ $str = preg_replace( array( '/\n+/', '/[ \t]+/' ), array( "\n", ' ' ), $str );
+ return $str;
+}
+
+/**
+ * Properly strip all HTML tags including script and style
+ *
+ * @since 2.9.0
+ *
+ * @param string $string String containing HTML tags
+ * @param bool $remove_breaks optional Whether to remove left over line breaks and white space chars
+ * @return string The processed string.
+ */
+function wp_strip_all_tags($string, $remove_breaks = false) {
+ $string = preg_replace( '@<(script|style)[^>]*?>.*?</\\1>@si', '', $string );
+ $string = strip_tags($string);
+
+ if ( $remove_breaks )
+ $string = preg_replace('/[\r\n\t ]+/', ' ', $string);
+
+ return trim( $string );
+}
+
+/**
+ * Sanitize a string from user input or from the db
+ *
+ * check for invalid UTF-8,
+ * Convert single < characters to entity,
+ * strip all tags,
+ * remove line breaks, tabs and extra white space,
+ * strip octets.
+ *
+ * @since 2.9.0
+ *
+ * @param string $str
+ * @return string
+ */
+function sanitize_text_field($str) {
+ $filtered = wp_check_invalid_utf8( $str );
+
+ if ( strpos($filtered, '<') !== false ) {
+ $filtered = wp_pre_kses_less_than( $filtered );
+ // This will strip extra whitespace for us.
+ $filtered = wp_strip_all_tags( $filtered, true );
+ } else {
+ $filtered = trim( preg_replace('/[\r\n\t ]+/', ' ', $filtered) );
+ }
+
+ $found = false;
+ while ( preg_match('/%[a-f0-9]{2}/i', $filtered, $match) ) {
+ $filtered = str_replace($match[0], '', $filtered);
+ $found = true;
+ }
+
+ if ( $found ) {
+ // Strip out the whitespace that may now exist after removing the octets.
+ $filtered = trim( preg_replace('/ +/', ' ', $filtered) );
+ }
+
+ return apply_filters('sanitize_text_field', $filtered, $str);
+}
+
+/**
+ * i18n friendly version of basename()
+ *
+ * @since 3.1.0
+ *
+ * @param string $path A path.
+ * @param string $suffix If the filename ends in suffix this will also be cut off.
+ * @return string
+ */
+function wp_basename( $path, $suffix = '' ) {
+ return urldecode( basename( str_replace( array( '%2F', '%5C' ), '/', urlencode( $path ) ), $suffix ) );
+}
+
+/**
+ * Forever eliminate "Wordpress" from the planet (or at least the little bit we can influence).
+ *
+ * Violating our coding standards for a good function name.
+ *
+ * @since 3.0.0
+ */
+function capital_P_dangit( $text ) {
+ // Simple replacement for titles
+ if ( 'the_title' === current_filter() )
+ return str_replace( 'Wordpress', 'WordPress', $text );
+ // Still here? Use the more judicious replacement
+ static $dblq = false;
+ if ( false === $dblq )
+ $dblq = _x( '“', 'opening curly double quote' );
+ return str_replace(
+ array( ' Wordpress', '‘Wordpress', $dblq . 'Wordpress', '>Wordpress', '(Wordpress' ),
+ array( ' WordPress', '‘WordPress', $dblq . 'WordPress', '>WordPress', '(WordPress' ),
+ $text );
+
+}
+
+/**
+ * Sanitize a mime type
+ *
+ * @since 3.1.3
+ *
+ * @param string $mime_type Mime type
+ * @return string Sanitized mime type
+ */
+function sanitize_mime_type( $mime_type ) {
+ $sani_mime_type = preg_replace( '/[^-+*.a-zA-Z0-9\/]/', '', $mime_type );
+ return apply_filters( 'sanitize_mime_type', $sani_mime_type, $mime_type );
+}
+
+/**
+ * Sanitize space or carriage return separated URLs that are used to send trackbacks.
+ *
+ * @since 3.4.0
+ *
+ * @param string $to_ping Space or carriage return separated URLs
+ * @return string URLs starting with the http or https protocol, separated by a carriage return.
+ */
+function sanitize_trackback_urls( $to_ping ) {
+ $urls_to_ping = preg_split( '/[\r\n\t ]/', trim( $to_ping ), -1, PREG_SPLIT_NO_EMPTY );
+ foreach ( $urls_to_ping as $k => $url ) {
+ if ( !preg_match( '#^https?://.#i', $url ) )
+ unset( $urls_to_ping[$k] );
+ }
+ $urls_to_ping = array_map( 'esc_url_raw', $urls_to_ping );
+ $urls_to_ping = implode( "\n", $urls_to_ping );
+ return apply_filters( 'sanitize_trackback_urls', $urls_to_ping, $to_ping );
+}
+
+/**
+ * Add slashes to a string or array of strings.
+ *
+ * This should be used when preparing data for core API that expects slashed data.
+ * This should not be used to escape data going directly into an SQL query.
+ *
+ * @since 3.6.0
+ *
+ * @param string|array $value String or array of strings to slash.
+ * @return string|array Slashed $value
+ */
+function wp_slash( $value ) {
+ if ( is_array( $value ) ) {
+ foreach ( $value as $k => $v ) {
+ if ( is_array( $v ) ) {
+ $value[$k] = wp_slash( $v );
+ } else {
+ $value[$k] = addslashes( $v );
+ }
+ }
+ } else {
+ $value = addslashes( $value );
+ }
+
+ return $value;
+}
+
+/**
+ * Remove slashes from a string or array of strings.
+ *
+ * This should be used to remove slashes from data passed to core API that
+ * expects data to be unslashed.
+ *
+ * @since 3.6.0
+ *
+ * @param string|array $value String or array of strings to unslash.
+ * @return string|array Unslashed $value
+ */
+function wp_unslash( $value ) {
+ return stripslashes_deep( $value );
+}
+
+/**
+ * Extract and return the first URL from passed content.
+ *
+ * @since 3.6.0
+ *
+ * @param string $content A string which might contain a URL.
+ * @return string The found URL.
+ */
+function get_url_in_content( $content ) {
+ if ( empty( $content ) )
+ return '';
+
+ if ( preg_match( '/<a\s[^>]*?href=([\'"])(.+?)\1/is', $content, $matches ) )
+ return esc_url_raw( $matches[2] );
+
+ return false;
+}