| Current Path : /home/x/b/o/xbodynamge/namtation/wp-content/ |
| Current File : /home/x/b/o/xbodynamge/namtation/wp-content/Strings.php.tar |
home/xbodynamge/dev/wp-content/plugins/all-in-one-seo-pack/app/Common/Traits/Helpers/Strings.php 0000644 00000046236 15113750303 0026654 0 ustar 00 <?php
namespace AIOSEO\Plugin\Common\Traits\Helpers;
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Contains string specific helper methods.
*
* @since 4.0.13
*/
trait Strings {
/**
* Convert to snake case.
*
* @since 4.0.0
*
* @param string $string The string to convert.
* @return string The converted string.
*/
public function toSnakeCase( $string ) {
$string[0] = strtolower( $string[0] );
return preg_replace_callback( '/([A-Z])/', function ( $value ) {
return '_' . strtolower( $value[1] );
}, $string );
}
/**
* Convert to camel case.
*
* @since 4.0.0
*
* @param string $string The string to convert.
* @param bool $capitalize Whether or not to capitalize the first letter.
* @return string The converted string.
*/
public function toCamelCase( $string, $capitalize = false ) {
$string[0] = strtolower( $string[0] );
if ( $capitalize ) {
$string[0] = strtoupper( $string[0] );
}
return preg_replace_callback( '/_([a-z0-9])/', function ( $value ) {
return strtoupper( $value[1] );
}, $string );
}
/**
* Converts kebab case to camel case.
*
* @since 4.0.0
*
* @param string $string The string to convert.
* @param bool $capitalizeFirstCharacter Whether to capitalize the first letter.
* @return string The converted string.
*/
public function dashesToCamelCase( $string, $capitalizeFirstCharacter = false ) {
$string = str_replace( ' ', '', ucwords( str_replace( '-', ' ', $string ) ) );
if ( ! $capitalizeFirstCharacter ) {
$string[0] = strtolower( $string[0] );
}
return $string;
}
/**
* Truncates a given string.
*
* @since 4.0.0
*
* @param string $string The string.
* @param int $maxCharacters The max. amount of characters.
* @param boolean $shouldHaveEllipsis Whether the string should have a trailing ellipsis (defaults to true).
* @return string The string.
*/
public function truncate( $string, $maxCharacters, $shouldHaveEllipsis = true ) {
$length = strlen( $string );
$excessLength = $length - $maxCharacters;
if ( 0 < $excessLength ) {
// If the string is longer than 65535 characters, we first need to shorten it due to the character limit of the regex pattern quantifier.
if ( 65535 < $length ) {
$string = substr( $string, 0, 65534 );
}
$string = preg_replace( "#[^\pZ\pP]*.{{$excessLength}}$#", '', (string) $string );
if ( $shouldHaveEllipsis ) {
$string = $string . ' ...';
}
}
return $string;
}
/**
* Escapes special regex characters.
*
* @since 4.0.5
*
* @param string $string The string.
* @param string $delimiter The delimiter character.
* @return string The escaped string.
*/
public function escapeRegex( $string, $delimiter = '/' ) {
static $escapeRegex = [];
if ( isset( $escapeRegex[ $string ] ) ) {
return $escapeRegex[ $string ];
}
$escapeRegex[ $string ] = preg_quote( (string) $string, $delimiter );
return $escapeRegex[ $string ];
}
/**
* Escapes special regex characters inside the replacement string.
*
* @since 4.0.7
*
* @param string $string The string.
* @return string The escaped string.
*/
public function escapeRegexReplacement( $string ) {
static $escapeRegexReplacement = [];
if ( isset( $escapeRegexReplacement[ $string ] ) ) {
return $escapeRegexReplacement[ $string ];
}
$escapeRegexReplacement[ $string ] = str_replace( '$', '\$', $string );
return $escapeRegexReplacement[ $string ];
}
/**
* preg_replace but with the replacement escaped.
*
* @since 4.0.10
*
* @param string $pattern The pattern to search for.
* @param string $replacement The replacement string.
* @param string $subject The subject to search in.
* @return string The subject with matches replaced.
*/
public function pregReplace( $pattern, $replacement, $subject ) {
if ( ! $subject ) {
return $subject;
}
$key = $pattern . $replacement . $subject;
static $pregReplace = [];
if ( isset( $pregReplace[ $key ] ) ) {
return $pregReplace[ $key ];
}
// TODO: In the future, we should consider escaping the search pattern as well.
// We can use the following pattern for this - (?<!\\)([\/.^$*+?|()[{}\]]{1})
// The pattern above will only escape special characters if they're not escaped yet, which makes it compatible with all our patterns that are already escaped.
// The caveat is that we'd need to first trim off slash delimiters and add them back later - otherwise they'd be escaped as well.
$replacement = $this->escapeRegexReplacement( $replacement );
$pregReplace[ $key ] = preg_replace( $pattern, $replacement, (string) $subject );
return $pregReplace[ $key ];
}
/**
* Returns string after converting it to lowercase.
*
* @since 4.0.13
*
* @param string $string The original string.
* @return string The string converted to lowercase.
*/
public function toLowerCase( $string ) {
static $lowerCased = [];
if ( isset( $lowerCased[ $string ] ) ) {
return $lowerCased[ $string ];
}
$lowerCased[ $string ] = function_exists( 'mb_strtolower' ) ? mb_strtolower( $string, $this->getCharset() ) : strtolower( $string );
return $lowerCased[ $string ];
}
/**
* Returns the index of a substring in a string.
*
* @since 4.1.6
*
* @param string $stack The stack.
* @param string $needle The needle.
* @param int $offset The offset.
* @return int|bool The index where the string starts or false if it does not exist.
*/
public function stringIndex( $stack, $needle, $offset = 0 ) {
$key = $stack . $needle . $offset;
static $stringIndex = [];
if ( isset( $stringIndex[ $key ] ) ) {
return $stringIndex[ $key ];
}
$stringIndex[ $key ] = function_exists( 'mb_strpos' ) ? mb_strpos( $stack, $needle, $offset, $this->getCharset() ) : strpos( $stack, $needle, $offset );
return $stringIndex[ $key ];
}
/**
* Checks if the given string contains the given substring.
*
* @since 4.1.0.2
*
* @param string $stack The stack.
* @param string $needle The needle.
* @param int $offset The offset.
* @return bool Whether the substring occurs in the main string.
*/
public function stringContains( $stack, $needle, $offset = 0 ) {
$key = $stack . $needle . $offset;
static $stringContains = [];
if ( isset( $stringContains[ $key ] ) ) {
return $stringContains[ $key ];
}
$stringContains[ $key ] = false !== $this->stringIndex( $stack, $needle, $offset );
return $stringContains[ $key ];
}
/**
* Check if a string is JSON encoded or not.
*
* @since 4.1.2
*
* @param mixed $string The string to check.
* @return bool True if it is JSON or false if not.
*/
public function isJsonString( $string ) {
if ( ! is_string( $string ) ) {
return false;
}
json_decode( $string );
// Return a boolean whether or not the last error matches.
return json_last_error() === JSON_ERROR_NONE;
}
/**
* Strips punctuation from a given string.
*
* @since 4.0.0
* @version 4.7.9 Added the $keepSpaces parameter.
*
* @param string $string The string.
* @param array $charactersToKeep The characters that can't be stripped (optional).
* @param bool $keepSpaces Whether to keep spaces.
* @return string The string without punctuation.
*/
public function stripPunctuation( $string, $charactersToKeep = [], $keepSpaces = false ) {
$characterRegexPattern = '';
if ( ! empty( $charactersToKeep ) ) {
$characterString = implode( '', $charactersToKeep );
$characterRegexPattern = "(?![$characterString])";
}
$string = aioseo()->helpers->decodeHtmlEntities( (string) $string );
$string = preg_replace( "/{$characterRegexPattern}[\p{P}\d+]/u", '', $string );
$string = aioseo()->helpers->encodeOutputHtml( $string );
// Trim both internal and external whitespace.
return $keepSpaces ? $string : preg_replace( '/\s\s+/u', ' ', trim( $string ) );
}
/**
* Returns the string after it is encoded with htmlspecialchars().
*
* @since 4.0.0
*
* @param string $string The string to encode.
* @return string The encoded string.
*/
public function encodeOutputHtml( $string ) {
if ( ! is_string( $string ) ) {
return '';
}
return htmlspecialchars( $string, ENT_COMPAT | ENT_HTML401, $this->getCharset(), false );
}
/**
* Returns the string after all HTML entities have been decoded.
*
* @since 4.0.0
*
* @param string $string The string to decode.
* @return string The decoded string.
*/
public function decodeHtmlEntities( $string ) {
static $decodeHtmlEntities = [];
if ( isset( $decodeHtmlEntities[ $string ] ) ) {
return $decodeHtmlEntities[ $string ];
}
// We must manually decode non-breaking spaces since html_entity_decode doesn't do this.
$string = $this->pregReplace( '/ /', ' ', $string );
$decodeHtmlEntities[ $string ] = html_entity_decode( (string) $string, ENT_QUOTES );
return $decodeHtmlEntities[ $string ];
}
/**
* Returns the string with script tags stripped.
*
* @since 4.0.0
*
* @param string $string The string.
* @return string The modified string.
*/
public function stripScriptTags( $string ) {
static $stripScriptTags = [];
if ( isset( $stripScriptTags[ $string ] ) ) {
return $stripScriptTags[ $string ];
}
$stripScriptTags[ $string ] = $this->pregReplace( '/<script(.*?)>(.*?)<\/script>/is', '', $string );
return $stripScriptTags[ $string ];
}
/**
* Returns the string with incomplete HTML tags stripped.
* Incomplete tags are not unopened/unclosed pairs but rather single tags that aren't properly formed.
* e.g. <a href='something'
* e.g. href='something' >
*
* @since 4.1.6
*
* @param string $string The string.
* @return string The modified string.
*/
public function stripIncompleteHtmlTags( $string ) {
static $stripIncompleteHtmlTags = [];
if ( isset( $stripIncompleteHtmlTags[ $string ] ) ) {
return $stripIncompleteHtmlTags[ $string ];
}
$stripIncompleteHtmlTags[ $string ] = $this->pregReplace( '/(^(?!<).*?(\/>)|<[^>]*?(?!\/>)$)/is', '', $string );
return $stripIncompleteHtmlTags[ $string ];
}
/**
* Returns the given JSON formatted data tags as a comma separated list with their values instead.
*
* @since 4.1.0
*
* @param string|array $tags The Array or JSON formatted data tags.
* @return string The comma separated values.
*/
public function jsonTagsToCommaSeparatedList( $tags ) {
$tags = is_string( $tags ) ? json_decode( $tags ) : $tags;
$values = [];
foreach ( $tags as $k => $tag ) {
$values[ $k ] = is_object( $tag ) ? $tag->value : $tag['value'];
}
return implode( ',', $values );
}
/**
* Returns the character length of the given string.
*
* @since 4.1.6
*
* @param string $string The string.
* @return int The string length.
*/
public function stringLength( $string ) {
static $stringLength = [];
if ( isset( $stringLength[ $string ] ) ) {
return $stringLength[ $string ];
}
$stringLength[ $string ] = function_exists( 'mb_strlen' ) ? mb_strlen( $string, $this->getCharset() ) : strlen( $string );
return $stringLength[ $string ];
}
/**
* Returns the word count of the given string.
*
* @since 4.1.6
*
* @param string $string The string.
* @return int The word count.
*/
public function stringWordCount( $string ) {
static $stringWordCount = [];
if ( isset( $stringWordCount[ $string ] ) ) {
return $stringWordCount[ $string ];
}
$stringWordCount[ $string ] = str_word_count( $string );
return $stringWordCount[ $string ];
}
/**
* Explodes the given string into an array.
*
* @since 4.1.6
*
* @param string $delimiter The delimiter.
* @param string $string The string.
* @return array The exploded words.
*/
public function explode( $delimiter, $string ) {
$key = $delimiter . $string;
static $exploded = [];
if ( isset( $exploded[ $key ] ) ) {
return $exploded[ $key ];
}
$exploded[ $key ] = explode( $delimiter, $string );
return $exploded[ $key ];
}
/**
* Implodes an array into a WHEREIN clause useable string.
*
* @since 4.1.6
*
* @param array $array The array.
* @param bool $outerQuotes Whether outer quotes should be added.
* @return string The imploded array.
*/
public function implodeWhereIn( $array, $outerQuotes = false ) {
// Reset the keys first in case there is no 0 index.
$array = array_values( $array );
if ( ! isset( $array[0] ) ) {
return '';
}
if ( is_numeric( $array[0] ) ) {
return implode( ', ', $array );
}
return $outerQuotes ? "'" . implode( "', '", $array ) . "'" : implode( "', '", $array );
}
/**
* Returns an imploded string of placeholders for usage in a WPDB prepare statement.
*
* @since 4.1.9
*
* @param array $array The array.
* @param string $placeholder The placeholder (e.g. "%s" or "%d").
* @return string The imploded string with placeholders.
*/
public function implodePlaceholders( $array, $placeholder = '%s' ) {
return implode( ', ', array_fill( 0, count( $array ), $placeholder ) );
}
/**
* Verifies that a string is indeed a valid regular expression.
*
* @since 4.2.1
*
* @return boolean True if the string is a valid regular expression.
*/
public function isValidRegex( $pattern ) {
// Set a custom error handler to prevent throwing errors on a bad Regular Expression.
set_error_handler( function() {}, E_WARNING ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_set_error_handler
$isValid = true;
if ( false === preg_match( $pattern, '' ) ) {
$isValid = false;
}
// Restore the error handler.
restore_error_handler();
return $isValid;
}
/**
* Removes the leading slash(es) from a string.
*
* @since 4.2.3
*
* @param string $string The string.
* @return string The modified string.
*/
public function unleadingSlashIt( $string ) {
return ltrim( $string, '/' );
}
/**
* Convert the case of the given string.
*
* @since 4.2.4
*
* @param string $string The string.
* @param string $type The casing ("lower", "title", "sentence").
* @return string The converted string.
*/
public function convertCase( $string, $type ) {
switch ( $type ) {
case 'lower':
return strtolower( $string );
case 'title':
return $this->toTitleCase( $string );
case 'sentence':
return $this->toSentenceCase( $string );
default:
return $string;
}
}
/**
* Converts the given string to title case.
*
* @since 4.2.4
*
* @param string $string The string.
* @return string The converted string.
*/
public function toTitleCase( $string ) {
// List of common English words that aren't typically modified.
$exceptions = apply_filters( 'aioseo_title_case_exceptions', [
'of',
'a',
'the',
'and',
'an',
'or',
'nor',
'but',
'is',
'if',
'then',
'else',
'when',
'at',
'from',
'by',
'on',
'off',
'for',
'in',
'out',
'over',
'to',
'into',
'with'
] );
$words = explode( ' ', strtolower( $string ) );
foreach ( $words as $k => $word ) {
if ( ! in_array( $word, $exceptions, true ) ) {
$words[ $k ] = ucfirst( $word );
}
}
$string = implode( ' ', $words );
return $string;
}
/**
* Converts the given string to sentence case.
*
* @since 4.2.4
*
* @param string $string The string.
* @return string The converted string.
*/
public function toSentenceCase( $string ) {
$phrases = preg_split( '/([.?!]+)/', (string) $string, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE );
$convertedString = '';
foreach ( $phrases as $index => $sentence ) {
$convertedString .= ( $index & 1 ) === 0 ? ucfirst( strtolower( trim( $sentence ) ) ) : $sentence . ' ';
}
return trim( $convertedString );
}
/**
* Returns the substring with a given start index and length.
*
* @since 4.2.5
*
* @param string $string The string.
* @param int $startIndex The start index.
* @param int $length The length.
* @return string The substring.
*/
public function substring( $string, $startIndex, $length ) {
return function_exists( 'mb_substr' ) ? mb_substr( $string, $startIndex, $length, $this->getCharset() ) : substr( $string, $startIndex, $length );
}
/**
* Strips emoji characters from a given string.
*
* @since 4.7.3
*
* @param string $string The string.
* @return string The string without emoji characters.
*/
public function stripEmoji( $string ) {
// First, decode HTML entities to convert them to actual Unicode characters.
$string = $this->decodeHtmlEntities( $string );
// Pattern to match emoji characters.
$emojiPattern = '/[\x{1F600}-\x{1F64F}' . // Emoticons
'\x{1F300}-\x{1F5FF}' . // Misc Symbols and Pictographs
'\x{1F680}-\x{1F6FF}' . // Transport and Map Symbols
'\x{1F1E0}-\x{1F1FF}' . // Flags (iOS)
'\x{2600}-\x{26FF}' . // Misc symbols
'\x{2700}-\x{27BF}' . // Dingbats
'\x{FE00}-\x{FE0F}' . // Variation Selectors
'\x{1F900}-\x{1F9FF}' . // Supplemental Symbols and Pictographs
']/u';
$filteredString = preg_replace( $emojiPattern, '', (string) $string );
// Re-encode special characters to HTML entities.
return $this->encodeOutputHtml( $filteredString );
}
/**
* Creates a sha1 hash from the given arguments.
*
* @since 4.7.8
*
* @param mixed ...$args The arguments to create a sha1 hash from.
* @return string The sha1 hash.
*/
public function createHash( ...$args ) {
return sha1( wp_json_encode( $args ) );
}
/**
* Extracts URLs from a given string.
*
* @since 4.8.1
*
* @param string $string The string.
* @return array The extracted URLs.
*/
public function extractUrls( $string ) {
$urls = wp_extract_urls( $string );
if ( empty( $urls ) ) {
return [];
}
$allUrls = [];
// Attempt to split multiple URLs. Elementor does not always separate them properly.
foreach ( $urls as $url ) {
$splitUrls = preg_split( '/(?=https?:\/\/)/', $url, - 1, PREG_SPLIT_NO_EMPTY );
$allUrls = array_merge( $allUrls, $splitUrls );
}
return $allUrls;
}
/**
* Determines if a text string contains an emoji or not.
*
* @since 4.8.0
*
* @param string $string The text string to detect emoji in.
* @return bool
*/
public function hasEmojis( $string ) {
$emojisRegexPattern = '/[\x{1F600}-\x{1F64F}' . // Emoticons
'\x{1F300}-\x{1F5FF}' . // Misc Symbols and Pictographs
'\x{1F680}-\x{1F6FF}' . // Transport and Map Symbols
'\x{1F1E0}-\x{1F1FF}' . // Flags (iOS)
'\x{2600}-\x{26FF}' . // Misc symbols
'\x{2700}-\x{27BF}' . // Dingbats
'\x{FE00}-\x{FE0F}' . // Variation Selectors
'\x{1F900}-\x{1F9FF}' . // Supplemental Symbols and Pictographs
'\x{1F018}-\x{1F270}' . // Various Asian characters
'\x{238C}-\x{2454}' . // Misc items
'\x{20D0}-\x{20FF}' . // Combining Diacritical Marks for Symbols
']/u';
return preg_match( $emojisRegexPattern, $string );
}
} xbodynamge/namtation/wp-content/plugins/all-in-one-seo-pack/app/Common/Traits/Helpers/Strings.php 0000644 00000046236 15114444230 0030011 0 ustar 00 home <?php
namespace AIOSEO\Plugin\Common\Traits\Helpers;
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Contains string specific helper methods.
*
* @since 4.0.13
*/
trait Strings {
/**
* Convert to snake case.
*
* @since 4.0.0
*
* @param string $string The string to convert.
* @return string The converted string.
*/
public function toSnakeCase( $string ) {
$string[0] = strtolower( $string[0] );
return preg_replace_callback( '/([A-Z])/', function ( $value ) {
return '_' . strtolower( $value[1] );
}, $string );
}
/**
* Convert to camel case.
*
* @since 4.0.0
*
* @param string $string The string to convert.
* @param bool $capitalize Whether or not to capitalize the first letter.
* @return string The converted string.
*/
public function toCamelCase( $string, $capitalize = false ) {
$string[0] = strtolower( $string[0] );
if ( $capitalize ) {
$string[0] = strtoupper( $string[0] );
}
return preg_replace_callback( '/_([a-z0-9])/', function ( $value ) {
return strtoupper( $value[1] );
}, $string );
}
/**
* Converts kebab case to camel case.
*
* @since 4.0.0
*
* @param string $string The string to convert.
* @param bool $capitalizeFirstCharacter Whether to capitalize the first letter.
* @return string The converted string.
*/
public function dashesToCamelCase( $string, $capitalizeFirstCharacter = false ) {
$string = str_replace( ' ', '', ucwords( str_replace( '-', ' ', $string ) ) );
if ( ! $capitalizeFirstCharacter ) {
$string[0] = strtolower( $string[0] );
}
return $string;
}
/**
* Truncates a given string.
*
* @since 4.0.0
*
* @param string $string The string.
* @param int $maxCharacters The max. amount of characters.
* @param boolean $shouldHaveEllipsis Whether the string should have a trailing ellipsis (defaults to true).
* @return string The string.
*/
public function truncate( $string, $maxCharacters, $shouldHaveEllipsis = true ) {
$length = strlen( $string );
$excessLength = $length - $maxCharacters;
if ( 0 < $excessLength ) {
// If the string is longer than 65535 characters, we first need to shorten it due to the character limit of the regex pattern quantifier.
if ( 65535 < $length ) {
$string = substr( $string, 0, 65534 );
}
$string = preg_replace( "#[^\pZ\pP]*.{{$excessLength}}$#", '', (string) $string );
if ( $shouldHaveEllipsis ) {
$string = $string . ' ...';
}
}
return $string;
}
/**
* Escapes special regex characters.
*
* @since 4.0.5
*
* @param string $string The string.
* @param string $delimiter The delimiter character.
* @return string The escaped string.
*/
public function escapeRegex( $string, $delimiter = '/' ) {
static $escapeRegex = [];
if ( isset( $escapeRegex[ $string ] ) ) {
return $escapeRegex[ $string ];
}
$escapeRegex[ $string ] = preg_quote( (string) $string, $delimiter );
return $escapeRegex[ $string ];
}
/**
* Escapes special regex characters inside the replacement string.
*
* @since 4.0.7
*
* @param string $string The string.
* @return string The escaped string.
*/
public function escapeRegexReplacement( $string ) {
static $escapeRegexReplacement = [];
if ( isset( $escapeRegexReplacement[ $string ] ) ) {
return $escapeRegexReplacement[ $string ];
}
$escapeRegexReplacement[ $string ] = str_replace( '$', '\$', $string );
return $escapeRegexReplacement[ $string ];
}
/**
* preg_replace but with the replacement escaped.
*
* @since 4.0.10
*
* @param string $pattern The pattern to search for.
* @param string $replacement The replacement string.
* @param string $subject The subject to search in.
* @return string The subject with matches replaced.
*/
public function pregReplace( $pattern, $replacement, $subject ) {
if ( ! $subject ) {
return $subject;
}
$key = $pattern . $replacement . $subject;
static $pregReplace = [];
if ( isset( $pregReplace[ $key ] ) ) {
return $pregReplace[ $key ];
}
// TODO: In the future, we should consider escaping the search pattern as well.
// We can use the following pattern for this - (?<!\\)([\/.^$*+?|()[{}\]]{1})
// The pattern above will only escape special characters if they're not escaped yet, which makes it compatible with all our patterns that are already escaped.
// The caveat is that we'd need to first trim off slash delimiters and add them back later - otherwise they'd be escaped as well.
$replacement = $this->escapeRegexReplacement( $replacement );
$pregReplace[ $key ] = preg_replace( $pattern, $replacement, (string) $subject );
return $pregReplace[ $key ];
}
/**
* Returns string after converting it to lowercase.
*
* @since 4.0.13
*
* @param string $string The original string.
* @return string The string converted to lowercase.
*/
public function toLowerCase( $string ) {
static $lowerCased = [];
if ( isset( $lowerCased[ $string ] ) ) {
return $lowerCased[ $string ];
}
$lowerCased[ $string ] = function_exists( 'mb_strtolower' ) ? mb_strtolower( $string, $this->getCharset() ) : strtolower( $string );
return $lowerCased[ $string ];
}
/**
* Returns the index of a substring in a string.
*
* @since 4.1.6
*
* @param string $stack The stack.
* @param string $needle The needle.
* @param int $offset The offset.
* @return int|bool The index where the string starts or false if it does not exist.
*/
public function stringIndex( $stack, $needle, $offset = 0 ) {
$key = $stack . $needle . $offset;
static $stringIndex = [];
if ( isset( $stringIndex[ $key ] ) ) {
return $stringIndex[ $key ];
}
$stringIndex[ $key ] = function_exists( 'mb_strpos' ) ? mb_strpos( $stack, $needle, $offset, $this->getCharset() ) : strpos( $stack, $needle, $offset );
return $stringIndex[ $key ];
}
/**
* Checks if the given string contains the given substring.
*
* @since 4.1.0.2
*
* @param string $stack The stack.
* @param string $needle The needle.
* @param int $offset The offset.
* @return bool Whether the substring occurs in the main string.
*/
public function stringContains( $stack, $needle, $offset = 0 ) {
$key = $stack . $needle . $offset;
static $stringContains = [];
if ( isset( $stringContains[ $key ] ) ) {
return $stringContains[ $key ];
}
$stringContains[ $key ] = false !== $this->stringIndex( $stack, $needle, $offset );
return $stringContains[ $key ];
}
/**
* Check if a string is JSON encoded or not.
*
* @since 4.1.2
*
* @param mixed $string The string to check.
* @return bool True if it is JSON or false if not.
*/
public function isJsonString( $string ) {
if ( ! is_string( $string ) ) {
return false;
}
json_decode( $string );
// Return a boolean whether or not the last error matches.
return json_last_error() === JSON_ERROR_NONE;
}
/**
* Strips punctuation from a given string.
*
* @since 4.0.0
* @version 4.7.9 Added the $keepSpaces parameter.
*
* @param string $string The string.
* @param array $charactersToKeep The characters that can't be stripped (optional).
* @param bool $keepSpaces Whether to keep spaces.
* @return string The string without punctuation.
*/
public function stripPunctuation( $string, $charactersToKeep = [], $keepSpaces = false ) {
$characterRegexPattern = '';
if ( ! empty( $charactersToKeep ) ) {
$characterString = implode( '', $charactersToKeep );
$characterRegexPattern = "(?![$characterString])";
}
$string = aioseo()->helpers->decodeHtmlEntities( (string) $string );
$string = preg_replace( "/{$characterRegexPattern}[\p{P}\d+]/u", '', $string );
$string = aioseo()->helpers->encodeOutputHtml( $string );
// Trim both internal and external whitespace.
return $keepSpaces ? $string : preg_replace( '/\s\s+/u', ' ', trim( $string ) );
}
/**
* Returns the string after it is encoded with htmlspecialchars().
*
* @since 4.0.0
*
* @param string $string The string to encode.
* @return string The encoded string.
*/
public function encodeOutputHtml( $string ) {
if ( ! is_string( $string ) ) {
return '';
}
return htmlspecialchars( $string, ENT_COMPAT | ENT_HTML401, $this->getCharset(), false );
}
/**
* Returns the string after all HTML entities have been decoded.
*
* @since 4.0.0
*
* @param string $string The string to decode.
* @return string The decoded string.
*/
public function decodeHtmlEntities( $string ) {
static $decodeHtmlEntities = [];
if ( isset( $decodeHtmlEntities[ $string ] ) ) {
return $decodeHtmlEntities[ $string ];
}
// We must manually decode non-breaking spaces since html_entity_decode doesn't do this.
$string = $this->pregReplace( '/ /', ' ', $string );
$decodeHtmlEntities[ $string ] = html_entity_decode( (string) $string, ENT_QUOTES );
return $decodeHtmlEntities[ $string ];
}
/**
* Returns the string with script tags stripped.
*
* @since 4.0.0
*
* @param string $string The string.
* @return string The modified string.
*/
public function stripScriptTags( $string ) {
static $stripScriptTags = [];
if ( isset( $stripScriptTags[ $string ] ) ) {
return $stripScriptTags[ $string ];
}
$stripScriptTags[ $string ] = $this->pregReplace( '/<script(.*?)>(.*?)<\/script>/is', '', $string );
return $stripScriptTags[ $string ];
}
/**
* Returns the string with incomplete HTML tags stripped.
* Incomplete tags are not unopened/unclosed pairs but rather single tags that aren't properly formed.
* e.g. <a href='something'
* e.g. href='something' >
*
* @since 4.1.6
*
* @param string $string The string.
* @return string The modified string.
*/
public function stripIncompleteHtmlTags( $string ) {
static $stripIncompleteHtmlTags = [];
if ( isset( $stripIncompleteHtmlTags[ $string ] ) ) {
return $stripIncompleteHtmlTags[ $string ];
}
$stripIncompleteHtmlTags[ $string ] = $this->pregReplace( '/(^(?!<).*?(\/>)|<[^>]*?(?!\/>)$)/is', '', $string );
return $stripIncompleteHtmlTags[ $string ];
}
/**
* Returns the given JSON formatted data tags as a comma separated list with their values instead.
*
* @since 4.1.0
*
* @param string|array $tags The Array or JSON formatted data tags.
* @return string The comma separated values.
*/
public function jsonTagsToCommaSeparatedList( $tags ) {
$tags = is_string( $tags ) ? json_decode( $tags ) : $tags;
$values = [];
foreach ( $tags as $k => $tag ) {
$values[ $k ] = is_object( $tag ) ? $tag->value : $tag['value'];
}
return implode( ',', $values );
}
/**
* Returns the character length of the given string.
*
* @since 4.1.6
*
* @param string $string The string.
* @return int The string length.
*/
public function stringLength( $string ) {
static $stringLength = [];
if ( isset( $stringLength[ $string ] ) ) {
return $stringLength[ $string ];
}
$stringLength[ $string ] = function_exists( 'mb_strlen' ) ? mb_strlen( $string, $this->getCharset() ) : strlen( $string );
return $stringLength[ $string ];
}
/**
* Returns the word count of the given string.
*
* @since 4.1.6
*
* @param string $string The string.
* @return int The word count.
*/
public function stringWordCount( $string ) {
static $stringWordCount = [];
if ( isset( $stringWordCount[ $string ] ) ) {
return $stringWordCount[ $string ];
}
$stringWordCount[ $string ] = str_word_count( $string );
return $stringWordCount[ $string ];
}
/**
* Explodes the given string into an array.
*
* @since 4.1.6
*
* @param string $delimiter The delimiter.
* @param string $string The string.
* @return array The exploded words.
*/
public function explode( $delimiter, $string ) {
$key = $delimiter . $string;
static $exploded = [];
if ( isset( $exploded[ $key ] ) ) {
return $exploded[ $key ];
}
$exploded[ $key ] = explode( $delimiter, $string );
return $exploded[ $key ];
}
/**
* Implodes an array into a WHEREIN clause useable string.
*
* @since 4.1.6
*
* @param array $array The array.
* @param bool $outerQuotes Whether outer quotes should be added.
* @return string The imploded array.
*/
public function implodeWhereIn( $array, $outerQuotes = false ) {
// Reset the keys first in case there is no 0 index.
$array = array_values( $array );
if ( ! isset( $array[0] ) ) {
return '';
}
if ( is_numeric( $array[0] ) ) {
return implode( ', ', $array );
}
return $outerQuotes ? "'" . implode( "', '", $array ) . "'" : implode( "', '", $array );
}
/**
* Returns an imploded string of placeholders for usage in a WPDB prepare statement.
*
* @since 4.1.9
*
* @param array $array The array.
* @param string $placeholder The placeholder (e.g. "%s" or "%d").
* @return string The imploded string with placeholders.
*/
public function implodePlaceholders( $array, $placeholder = '%s' ) {
return implode( ', ', array_fill( 0, count( $array ), $placeholder ) );
}
/**
* Verifies that a string is indeed a valid regular expression.
*
* @since 4.2.1
*
* @return boolean True if the string is a valid regular expression.
*/
public function isValidRegex( $pattern ) {
// Set a custom error handler to prevent throwing errors on a bad Regular Expression.
set_error_handler( function() {}, E_WARNING ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_set_error_handler
$isValid = true;
if ( false === preg_match( $pattern, '' ) ) {
$isValid = false;
}
// Restore the error handler.
restore_error_handler();
return $isValid;
}
/**
* Removes the leading slash(es) from a string.
*
* @since 4.2.3
*
* @param string $string The string.
* @return string The modified string.
*/
public function unleadingSlashIt( $string ) {
return ltrim( $string, '/' );
}
/**
* Convert the case of the given string.
*
* @since 4.2.4
*
* @param string $string The string.
* @param string $type The casing ("lower", "title", "sentence").
* @return string The converted string.
*/
public function convertCase( $string, $type ) {
switch ( $type ) {
case 'lower':
return strtolower( $string );
case 'title':
return $this->toTitleCase( $string );
case 'sentence':
return $this->toSentenceCase( $string );
default:
return $string;
}
}
/**
* Converts the given string to title case.
*
* @since 4.2.4
*
* @param string $string The string.
* @return string The converted string.
*/
public function toTitleCase( $string ) {
// List of common English words that aren't typically modified.
$exceptions = apply_filters( 'aioseo_title_case_exceptions', [
'of',
'a',
'the',
'and',
'an',
'or',
'nor',
'but',
'is',
'if',
'then',
'else',
'when',
'at',
'from',
'by',
'on',
'off',
'for',
'in',
'out',
'over',
'to',
'into',
'with'
] );
$words = explode( ' ', strtolower( $string ) );
foreach ( $words as $k => $word ) {
if ( ! in_array( $word, $exceptions, true ) ) {
$words[ $k ] = ucfirst( $word );
}
}
$string = implode( ' ', $words );
return $string;
}
/**
* Converts the given string to sentence case.
*
* @since 4.2.4
*
* @param string $string The string.
* @return string The converted string.
*/
public function toSentenceCase( $string ) {
$phrases = preg_split( '/([.?!]+)/', (string) $string, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE );
$convertedString = '';
foreach ( $phrases as $index => $sentence ) {
$convertedString .= ( $index & 1 ) === 0 ? ucfirst( strtolower( trim( $sentence ) ) ) : $sentence . ' ';
}
return trim( $convertedString );
}
/**
* Returns the substring with a given start index and length.
*
* @since 4.2.5
*
* @param string $string The string.
* @param int $startIndex The start index.
* @param int $length The length.
* @return string The substring.
*/
public function substring( $string, $startIndex, $length ) {
return function_exists( 'mb_substr' ) ? mb_substr( $string, $startIndex, $length, $this->getCharset() ) : substr( $string, $startIndex, $length );
}
/**
* Strips emoji characters from a given string.
*
* @since 4.7.3
*
* @param string $string The string.
* @return string The string without emoji characters.
*/
public function stripEmoji( $string ) {
// First, decode HTML entities to convert them to actual Unicode characters.
$string = $this->decodeHtmlEntities( $string );
// Pattern to match emoji characters.
$emojiPattern = '/[\x{1F600}-\x{1F64F}' . // Emoticons
'\x{1F300}-\x{1F5FF}' . // Misc Symbols and Pictographs
'\x{1F680}-\x{1F6FF}' . // Transport and Map Symbols
'\x{1F1E0}-\x{1F1FF}' . // Flags (iOS)
'\x{2600}-\x{26FF}' . // Misc symbols
'\x{2700}-\x{27BF}' . // Dingbats
'\x{FE00}-\x{FE0F}' . // Variation Selectors
'\x{1F900}-\x{1F9FF}' . // Supplemental Symbols and Pictographs
']/u';
$filteredString = preg_replace( $emojiPattern, '', (string) $string );
// Re-encode special characters to HTML entities.
return $this->encodeOutputHtml( $filteredString );
}
/**
* Creates a sha1 hash from the given arguments.
*
* @since 4.7.8
*
* @param mixed ...$args The arguments to create a sha1 hash from.
* @return string The sha1 hash.
*/
public function createHash( ...$args ) {
return sha1( wp_json_encode( $args ) );
}
/**
* Extracts URLs from a given string.
*
* @since 4.8.1
*
* @param string $string The string.
* @return array The extracted URLs.
*/
public function extractUrls( $string ) {
$urls = wp_extract_urls( $string );
if ( empty( $urls ) ) {
return [];
}
$allUrls = [];
// Attempt to split multiple URLs. Elementor does not always separate them properly.
foreach ( $urls as $url ) {
$splitUrls = preg_split( '/(?=https?:\/\/)/', $url, - 1, PREG_SPLIT_NO_EMPTY );
$allUrls = array_merge( $allUrls, $splitUrls );
}
return $allUrls;
}
/**
* Determines if a text string contains an emoji or not.
*
* @since 4.8.0
*
* @param string $string The text string to detect emoji in.
* @return bool
*/
public function hasEmojis( $string ) {
$emojisRegexPattern = '/[\x{1F600}-\x{1F64F}' . // Emoticons
'\x{1F300}-\x{1F5FF}' . // Misc Symbols and Pictographs
'\x{1F680}-\x{1F6FF}' . // Transport and Map Symbols
'\x{1F1E0}-\x{1F1FF}' . // Flags (iOS)
'\x{2600}-\x{26FF}' . // Misc symbols
'\x{2700}-\x{27BF}' . // Dingbats
'\x{FE00}-\x{FE0F}' . // Variation Selectors
'\x{1F900}-\x{1F9FF}' . // Supplemental Symbols and Pictographs
'\x{1F018}-\x{1F270}' . // Various Asian characters
'\x{238C}-\x{2454}' . // Misc items
'\x{20D0}-\x{20FF}' . // Combining Diacritical Marks for Symbols
']/u';
return preg_match( $emojisRegexPattern, $string );
}
}