Edit File by line
/home/barbar84/www/wp-inclu...
File: shortcodes.php
<?php
[0] Fix | Delete
/**
[1] Fix | Delete
* WordPress API for creating bbcode-like tags or what WordPress calls
[2] Fix | Delete
* "shortcodes". The tag and attribute parsing or regular expression code is
[3] Fix | Delete
* based on the Textpattern tag parser.
[4] Fix | Delete
*
[5] Fix | Delete
* A few examples are below:
[6] Fix | Delete
*
[7] Fix | Delete
* [shortcode /]
[8] Fix | Delete
* [shortcode foo="bar" baz="bing" /]
[9] Fix | Delete
* [shortcode foo="bar"]content[/shortcode]
[10] Fix | Delete
*
[11] Fix | Delete
* Shortcode tags support attributes and enclosed content, but does not entirely
[12] Fix | Delete
* support inline shortcodes in other shortcodes. You will have to call the
[13] Fix | Delete
* shortcode parser in your function to account for that.
[14] Fix | Delete
*
[15] Fix | Delete
* {@internal
[16] Fix | Delete
* Please be aware that the above note was made during the beta of WordPress 2.6
[17] Fix | Delete
* and in the future may not be accurate. Please update the note when it is no
[18] Fix | Delete
* longer the case.}}
[19] Fix | Delete
*
[20] Fix | Delete
* To apply shortcode tags to content:
[21] Fix | Delete
*
[22] Fix | Delete
* $out = do_shortcode( $content );
[23] Fix | Delete
*
[24] Fix | Delete
* @link https://developer.wordpress.org/plugins/shortcodes/
[25] Fix | Delete
*
[26] Fix | Delete
* @package WordPress
[27] Fix | Delete
* @subpackage Shortcodes
[28] Fix | Delete
* @since 2.5.0
[29] Fix | Delete
*/
[30] Fix | Delete
[31] Fix | Delete
/**
[32] Fix | Delete
* Container for storing shortcode tags and their hook to call for the shortcode
[33] Fix | Delete
*
[34] Fix | Delete
* @since 2.5.0
[35] Fix | Delete
*
[36] Fix | Delete
* @name $shortcode_tags
[37] Fix | Delete
* @var array
[38] Fix | Delete
* @global array $shortcode_tags
[39] Fix | Delete
*/
[40] Fix | Delete
$shortcode_tags = array();
[41] Fix | Delete
[42] Fix | Delete
/**
[43] Fix | Delete
* Adds a new shortcode.
[44] Fix | Delete
*
[45] Fix | Delete
* Care should be taken through prefixing or other means to ensure that the
[46] Fix | Delete
* shortcode tag being added is unique and will not conflict with other,
[47] Fix | Delete
* already-added shortcode tags. In the event of a duplicated tag, the tag
[48] Fix | Delete
* loaded last will take precedence.
[49] Fix | Delete
*
[50] Fix | Delete
* @since 2.5.0
[51] Fix | Delete
*
[52] Fix | Delete
* @global array $shortcode_tags
[53] Fix | Delete
*
[54] Fix | Delete
* @param string $tag Shortcode tag to be searched in post content.
[55] Fix | Delete
* @param callable $callback The callback function to run when the shortcode is found.
[56] Fix | Delete
* Every shortcode callback is passed three parameters by default,
[57] Fix | Delete
* including an array of attributes (`$atts`), the shortcode content
[58] Fix | Delete
* or null if not set (`$content`), and finally the shortcode tag
[59] Fix | Delete
* itself (`$shortcode_tag`), in that order.
[60] Fix | Delete
*/
[61] Fix | Delete
function add_shortcode( $tag, $callback ) {
[62] Fix | Delete
global $shortcode_tags;
[63] Fix | Delete
[64] Fix | Delete
if ( '' === trim( $tag ) ) {
[65] Fix | Delete
$message = __( 'Invalid shortcode name: Empty name given.' );
[66] Fix | Delete
_doing_it_wrong( __FUNCTION__, $message, '4.4.0' );
[67] Fix | Delete
return;
[68] Fix | Delete
}
[69] Fix | Delete
[70] Fix | Delete
if ( 0 !== preg_match( '@[<>&/\[\]\x00-\x20=]@', $tag ) ) {
[71] Fix | Delete
/* translators: 1: Shortcode name, 2: Space-separated list of reserved characters. */
[72] Fix | Delete
$message = sprintf( __( 'Invalid shortcode name: %1$s. Do not use spaces or reserved characters: %2$s' ), $tag, '& / < > [ ] =' );
[73] Fix | Delete
_doing_it_wrong( __FUNCTION__, $message, '4.4.0' );
[74] Fix | Delete
return;
[75] Fix | Delete
}
[76] Fix | Delete
[77] Fix | Delete
$shortcode_tags[ $tag ] = $callback;
[78] Fix | Delete
}
[79] Fix | Delete
[80] Fix | Delete
/**
[81] Fix | Delete
* Removes hook for shortcode.
[82] Fix | Delete
*
[83] Fix | Delete
* @since 2.5.0
[84] Fix | Delete
*
[85] Fix | Delete
* @global array $shortcode_tags
[86] Fix | Delete
*
[87] Fix | Delete
* @param string $tag Shortcode tag to remove hook for.
[88] Fix | Delete
*/
[89] Fix | Delete
function remove_shortcode( $tag ) {
[90] Fix | Delete
global $shortcode_tags;
[91] Fix | Delete
[92] Fix | Delete
unset( $shortcode_tags[ $tag ] );
[93] Fix | Delete
}
[94] Fix | Delete
[95] Fix | Delete
/**
[96] Fix | Delete
* Clear all shortcodes.
[97] Fix | Delete
*
[98] Fix | Delete
* This function is simple, it clears all of the shortcode tags by replacing the
[99] Fix | Delete
* shortcodes global by a empty array. This is actually a very efficient method
[100] Fix | Delete
* for removing all shortcodes.
[101] Fix | Delete
*
[102] Fix | Delete
* @since 2.5.0
[103] Fix | Delete
*
[104] Fix | Delete
* @global array $shortcode_tags
[105] Fix | Delete
*/
[106] Fix | Delete
function remove_all_shortcodes() {
[107] Fix | Delete
global $shortcode_tags;
[108] Fix | Delete
[109] Fix | Delete
$shortcode_tags = array();
[110] Fix | Delete
}
[111] Fix | Delete
[112] Fix | Delete
/**
[113] Fix | Delete
* Whether a registered shortcode exists named $tag
[114] Fix | Delete
*
[115] Fix | Delete
* @since 3.6.0
[116] Fix | Delete
*
[117] Fix | Delete
* @global array $shortcode_tags List of shortcode tags and their callback hooks.
[118] Fix | Delete
*
[119] Fix | Delete
* @param string $tag Shortcode tag to check.
[120] Fix | Delete
* @return bool Whether the given shortcode exists.
[121] Fix | Delete
*/
[122] Fix | Delete
function shortcode_exists( $tag ) {
[123] Fix | Delete
global $shortcode_tags;
[124] Fix | Delete
return array_key_exists( $tag, $shortcode_tags );
[125] Fix | Delete
}
[126] Fix | Delete
[127] Fix | Delete
/**
[128] Fix | Delete
* Whether the passed content contains the specified shortcode
[129] Fix | Delete
*
[130] Fix | Delete
* @since 3.6.0
[131] Fix | Delete
*
[132] Fix | Delete
* @global array $shortcode_tags
[133] Fix | Delete
*
[134] Fix | Delete
* @param string $content Content to search for shortcodes.
[135] Fix | Delete
* @param string $tag Shortcode tag to check.
[136] Fix | Delete
* @return bool Whether the passed content contains the given shortcode.
[137] Fix | Delete
*/
[138] Fix | Delete
function has_shortcode( $content, $tag ) {
[139] Fix | Delete
if ( false === strpos( $content, '[' ) ) {
[140] Fix | Delete
return false;
[141] Fix | Delete
}
[142] Fix | Delete
[143] Fix | Delete
if ( shortcode_exists( $tag ) ) {
[144] Fix | Delete
preg_match_all( '/' . get_shortcode_regex() . '/', $content, $matches, PREG_SET_ORDER );
[145] Fix | Delete
if ( empty( $matches ) ) {
[146] Fix | Delete
return false;
[147] Fix | Delete
}
[148] Fix | Delete
[149] Fix | Delete
foreach ( $matches as $shortcode ) {
[150] Fix | Delete
if ( $tag === $shortcode[2] ) {
[151] Fix | Delete
return true;
[152] Fix | Delete
} elseif ( ! empty( $shortcode[5] ) && has_shortcode( $shortcode[5], $tag ) ) {
[153] Fix | Delete
return true;
[154] Fix | Delete
}
[155] Fix | Delete
}
[156] Fix | Delete
}
[157] Fix | Delete
return false;
[158] Fix | Delete
}
[159] Fix | Delete
[160] Fix | Delete
/**
[161] Fix | Delete
* Returns a list of registered shortcode names found in the given content.
[162] Fix | Delete
*
[163] Fix | Delete
* Example usage:
[164] Fix | Delete
*
[165] Fix | Delete
* get_shortcode_tags_in_content( '[audio src="file.mp3"][/audio] [foo] [gallery ids="1,2,3"]' );
[166] Fix | Delete
* // array( 'audio', 'gallery' )
[167] Fix | Delete
*
[168] Fix | Delete
* @since 6.3.2
[169] Fix | Delete
*
[170] Fix | Delete
* @param string $content The content to check.
[171] Fix | Delete
* @return string[] An array of registered shortcode names found in the content.
[172] Fix | Delete
*/
[173] Fix | Delete
function get_shortcode_tags_in_content( $content ) {
[174] Fix | Delete
if ( false === strpos( $content, '[' ) ) {
[175] Fix | Delete
return array();
[176] Fix | Delete
}
[177] Fix | Delete
[178] Fix | Delete
preg_match_all( '/' . get_shortcode_regex() . '/', $content, $matches, PREG_SET_ORDER );
[179] Fix | Delete
if ( empty( $matches ) ) {
[180] Fix | Delete
return array();
[181] Fix | Delete
}
[182] Fix | Delete
[183] Fix | Delete
$tags = array();
[184] Fix | Delete
foreach ( $matches as $shortcode ) {
[185] Fix | Delete
$tags[] = $shortcode[2];
[186] Fix | Delete
[187] Fix | Delete
if ( ! empty( $shortcode[5] ) ) {
[188] Fix | Delete
$deep_tags = get_shortcode_tags_in_content( $shortcode[5] );
[189] Fix | Delete
if ( ! empty( $deep_tags ) ) {
[190] Fix | Delete
$tags = array_merge( $tags, $deep_tags );
[191] Fix | Delete
}
[192] Fix | Delete
}
[193] Fix | Delete
}
[194] Fix | Delete
[195] Fix | Delete
return $tags;
[196] Fix | Delete
}
[197] Fix | Delete
[198] Fix | Delete
/**
[199] Fix | Delete
* Searches content for shortcodes and filter shortcodes through their hooks.
[200] Fix | Delete
*
[201] Fix | Delete
* This function is an alias for do_shortcode().
[202] Fix | Delete
*
[203] Fix | Delete
* @since 5.4.0
[204] Fix | Delete
*
[205] Fix | Delete
* @see do_shortcode()
[206] Fix | Delete
*
[207] Fix | Delete
* @param string $content Content to search for shortcodes.
[208] Fix | Delete
* @param bool $ignore_html When true, shortcodes inside HTML elements will be skipped.
[209] Fix | Delete
* Default false.
[210] Fix | Delete
* @return string Content with shortcodes filtered out.
[211] Fix | Delete
*/
[212] Fix | Delete
function apply_shortcodes( $content, $ignore_html = false ) {
[213] Fix | Delete
return do_shortcode( $content, $ignore_html );
[214] Fix | Delete
}
[215] Fix | Delete
[216] Fix | Delete
/**
[217] Fix | Delete
* Search content for shortcodes and filter shortcodes through their hooks.
[218] Fix | Delete
*
[219] Fix | Delete
* If there are no shortcode tags defined, then the content will be returned
[220] Fix | Delete
* without any filtering. This might cause issues when plugins are disabled but
[221] Fix | Delete
* the shortcode will still show up in the post or content.
[222] Fix | Delete
*
[223] Fix | Delete
* @since 2.5.0
[224] Fix | Delete
*
[225] Fix | Delete
* @global array $shortcode_tags List of shortcode tags and their callback hooks.
[226] Fix | Delete
*
[227] Fix | Delete
* @param string $content Content to search for shortcodes.
[228] Fix | Delete
* @param bool $ignore_html When true, shortcodes inside HTML elements will be skipped.
[229] Fix | Delete
* Default false.
[230] Fix | Delete
* @return string Content with shortcodes filtered out.
[231] Fix | Delete
*/
[232] Fix | Delete
function do_shortcode( $content, $ignore_html = false ) {
[233] Fix | Delete
global $shortcode_tags;
[234] Fix | Delete
[235] Fix | Delete
if ( false === strpos( $content, '[' ) ) {
[236] Fix | Delete
return $content;
[237] Fix | Delete
}
[238] Fix | Delete
[239] Fix | Delete
if ( empty( $shortcode_tags ) || ! is_array( $shortcode_tags ) ) {
[240] Fix | Delete
return $content;
[241] Fix | Delete
}
[242] Fix | Delete
[243] Fix | Delete
// Find all registered tag names in $content.
[244] Fix | Delete
preg_match_all( '@\[([^<>&/\[\]\x00-\x20=]++)@', $content, $matches );
[245] Fix | Delete
$tagnames = array_intersect( array_keys( $shortcode_tags ), $matches[1] );
[246] Fix | Delete
[247] Fix | Delete
if ( empty( $tagnames ) ) {
[248] Fix | Delete
return $content;
[249] Fix | Delete
}
[250] Fix | Delete
[251] Fix | Delete
$content = do_shortcodes_in_html_tags( $content, $ignore_html, $tagnames );
[252] Fix | Delete
[253] Fix | Delete
$pattern = get_shortcode_regex( $tagnames );
[254] Fix | Delete
$content = preg_replace_callback( "/$pattern/", 'do_shortcode_tag', $content );
[255] Fix | Delete
[256] Fix | Delete
// Always restore square braces so we don't break things like <!--[if IE ]>.
[257] Fix | Delete
$content = unescape_invalid_shortcodes( $content );
[258] Fix | Delete
[259] Fix | Delete
return $content;
[260] Fix | Delete
}
[261] Fix | Delete
[262] Fix | Delete
/**
[263] Fix | Delete
* Retrieve the shortcode regular expression for searching.
[264] Fix | Delete
*
[265] Fix | Delete
* The regular expression combines the shortcode tags in the regular expression
[266] Fix | Delete
* in a regex class.
[267] Fix | Delete
*
[268] Fix | Delete
* The regular expression contains 6 different sub matches to help with parsing.
[269] Fix | Delete
*
[270] Fix | Delete
* 1 - An extra [ to allow for escaping shortcodes with double [[]]
[271] Fix | Delete
* 2 - The shortcode name
[272] Fix | Delete
* 3 - The shortcode argument list
[273] Fix | Delete
* 4 - The self closing /
[274] Fix | Delete
* 5 - The content of a shortcode when it wraps some content.
[275] Fix | Delete
* 6 - An extra ] to allow for escaping shortcodes with double [[]]
[276] Fix | Delete
*
[277] Fix | Delete
* @since 2.5.0
[278] Fix | Delete
* @since 4.4.0 Added the `$tagnames` parameter.
[279] Fix | Delete
*
[280] Fix | Delete
* @global array $shortcode_tags
[281] Fix | Delete
*
[282] Fix | Delete
* @param array $tagnames Optional. List of shortcodes to find. Defaults to all registered shortcodes.
[283] Fix | Delete
* @return string The shortcode search regular expression
[284] Fix | Delete
*/
[285] Fix | Delete
function get_shortcode_regex( $tagnames = null ) {
[286] Fix | Delete
global $shortcode_tags;
[287] Fix | Delete
[288] Fix | Delete
if ( empty( $tagnames ) ) {
[289] Fix | Delete
$tagnames = array_keys( $shortcode_tags );
[290] Fix | Delete
}
[291] Fix | Delete
$tagregexp = implode( '|', array_map( 'preg_quote', $tagnames ) );
[292] Fix | Delete
[293] Fix | Delete
// WARNING! Do not change this regex without changing do_shortcode_tag() and strip_shortcode_tag().
[294] Fix | Delete
// Also, see shortcode_unautop() and shortcode.js.
[295] Fix | Delete
[296] Fix | Delete
// phpcs:disable Squiz.Strings.ConcatenationSpacing.PaddingFound -- don't remove regex indentation
[297] Fix | Delete
return '\\[' // Opening bracket.
[298] Fix | Delete
. '(\\[?)' // 1: Optional second opening bracket for escaping shortcodes: [[tag]].
[299] Fix | Delete
. "($tagregexp)" // 2: Shortcode name.
[300] Fix | Delete
. '(?![\\w-])' // Not followed by word character or hyphen.
[301] Fix | Delete
. '(' // 3: Unroll the loop: Inside the opening shortcode tag.
[302] Fix | Delete
. '[^\\]\\/]*' // Not a closing bracket or forward slash.
[303] Fix | Delete
. '(?:'
[304] Fix | Delete
. '\\/(?!\\])' // A forward slash not followed by a closing bracket.
[305] Fix | Delete
. '[^\\]\\/]*' // Not a closing bracket or forward slash.
[306] Fix | Delete
. ')*?'
[307] Fix | Delete
. ')'
[308] Fix | Delete
. '(?:'
[309] Fix | Delete
. '(\\/)' // 4: Self closing tag...
[310] Fix | Delete
. '\\]' // ...and closing bracket.
[311] Fix | Delete
. '|'
[312] Fix | Delete
. '\\]' // Closing bracket.
[313] Fix | Delete
. '(?:'
[314] Fix | Delete
. '(' // 5: Unroll the loop: Optionally, anything between the opening and closing shortcode tags.
[315] Fix | Delete
. '[^\\[]*+' // Not an opening bracket.
[316] Fix | Delete
. '(?:'
[317] Fix | Delete
. '\\[(?!\\/\\2\\])' // An opening bracket not followed by the closing shortcode tag.
[318] Fix | Delete
. '[^\\[]*+' // Not an opening bracket.
[319] Fix | Delete
. ')*+'
[320] Fix | Delete
. ')'
[321] Fix | Delete
. '\\[\\/\\2\\]' // Closing shortcode tag.
[322] Fix | Delete
. ')?'
[323] Fix | Delete
. ')'
[324] Fix | Delete
. '(\\]?)'; // 6: Optional second closing brocket for escaping shortcodes: [[tag]].
[325] Fix | Delete
// phpcs:enable
[326] Fix | Delete
}
[327] Fix | Delete
[328] Fix | Delete
/**
[329] Fix | Delete
* Regular Expression callable for do_shortcode() for calling shortcode hook.
[330] Fix | Delete
*
[331] Fix | Delete
* @see get_shortcode_regex() for details of the match array contents.
[332] Fix | Delete
*
[333] Fix | Delete
* @since 2.5.0
[334] Fix | Delete
* @access private
[335] Fix | Delete
*
[336] Fix | Delete
* @global array $shortcode_tags
[337] Fix | Delete
*
[338] Fix | Delete
* @param array $m Regular expression match array.
[339] Fix | Delete
* @return string|false Shortcode output on success, false on failure.
[340] Fix | Delete
*/
[341] Fix | Delete
function do_shortcode_tag( $m ) {
[342] Fix | Delete
global $shortcode_tags;
[343] Fix | Delete
[344] Fix | Delete
// Allow [[foo]] syntax for escaping a tag.
[345] Fix | Delete
if ( '[' === $m[1] && ']' === $m[6] ) {
[346] Fix | Delete
return substr( $m[0], 1, -1 );
[347] Fix | Delete
}
[348] Fix | Delete
[349] Fix | Delete
$tag = $m[2];
[350] Fix | Delete
$attr = shortcode_parse_atts( $m[3] );
[351] Fix | Delete
[352] Fix | Delete
if ( ! is_callable( $shortcode_tags[ $tag ] ) ) {
[353] Fix | Delete
/* translators: %s: Shortcode tag. */
[354] Fix | Delete
$message = sprintf( __( 'Attempting to parse a shortcode without a valid callback: %s' ), $tag );
[355] Fix | Delete
_doing_it_wrong( __FUNCTION__, $message, '4.3.0' );
[356] Fix | Delete
return $m[0];
[357] Fix | Delete
}
[358] Fix | Delete
[359] Fix | Delete
/**
[360] Fix | Delete
* Filters whether to call a shortcode callback.
[361] Fix | Delete
*
[362] Fix | Delete
* Returning a non-false value from filter will short-circuit the
[363] Fix | Delete
* shortcode generation process, returning that value instead.
[364] Fix | Delete
*
[365] Fix | Delete
* @since 4.7.0
[366] Fix | Delete
*
[367] Fix | Delete
* @param false|string $return Short-circuit return value. Either false or the value to replace the shortcode with.
[368] Fix | Delete
* @param string $tag Shortcode name.
[369] Fix | Delete
* @param array|string $attr Shortcode attributes array or empty string.
[370] Fix | Delete
* @param array $m Regular expression match array.
[371] Fix | Delete
*/
[372] Fix | Delete
$return = apply_filters( 'pre_do_shortcode_tag', false, $tag, $attr, $m );
[373] Fix | Delete
if ( false !== $return ) {
[374] Fix | Delete
return $return;
[375] Fix | Delete
}
[376] Fix | Delete
[377] Fix | Delete
$content = isset( $m[5] ) ? $m[5] : null;
[378] Fix | Delete
[379] Fix | Delete
$output = $m[1] . call_user_func( $shortcode_tags[ $tag ], $attr, $content, $tag ) . $m[6];
[380] Fix | Delete
[381] Fix | Delete
/**
[382] Fix | Delete
* Filters the output created by a shortcode callback.
[383] Fix | Delete
*
[384] Fix | Delete
* @since 4.7.0
[385] Fix | Delete
*
[386] Fix | Delete
* @param string $output Shortcode output.
[387] Fix | Delete
* @param string $tag Shortcode name.
[388] Fix | Delete
* @param array|string $attr Shortcode attributes array or empty string.
[389] Fix | Delete
* @param array $m Regular expression match array.
[390] Fix | Delete
*/
[391] Fix | Delete
return apply_filters( 'do_shortcode_tag', $output, $tag, $attr, $m );
[392] Fix | Delete
}
[393] Fix | Delete
[394] Fix | Delete
/**
[395] Fix | Delete
* Search only inside HTML elements for shortcodes and process them.
[396] Fix | Delete
*
[397] Fix | Delete
* Any [ or ] characters remaining inside elements will be HTML encoded
[398] Fix | Delete
* to prevent interference with shortcodes that are outside the elements.
[399] Fix | Delete
* Assumes $content processed by KSES already. Users with unfiltered_html
[400] Fix | Delete
* capability may get unexpected output if angle braces are nested in tags.
[401] Fix | Delete
*
[402] Fix | Delete
* @since 4.2.3
[403] Fix | Delete
*
[404] Fix | Delete
* @param string $content Content to search for shortcodes.
[405] Fix | Delete
* @param bool $ignore_html When true, all square braces inside elements will be encoded.
[406] Fix | Delete
* @param array $tagnames List of shortcodes to find.
[407] Fix | Delete
* @return string Content with shortcodes filtered out.
[408] Fix | Delete
*/
[409] Fix | Delete
function do_shortcodes_in_html_tags( $content, $ignore_html, $tagnames ) {
[410] Fix | Delete
// Normalize entities in unfiltered HTML before adding placeholders.
[411] Fix | Delete
$trans = array(
[412] Fix | Delete
'&#91;' => '&#091;',
[413] Fix | Delete
'&#93;' => '&#093;',
[414] Fix | Delete
);
[415] Fix | Delete
$content = strtr( $content, $trans );
[416] Fix | Delete
$trans = array(
[417] Fix | Delete
'[' => '&#91;',
[418] Fix | Delete
']' => '&#93;',
[419] Fix | Delete
);
[420] Fix | Delete
[421] Fix | Delete
$pattern = get_shortcode_regex( $tagnames );
[422] Fix | Delete
$textarr = wp_html_split( $content );
[423] Fix | Delete
[424] Fix | Delete
foreach ( $textarr as &$element ) {
[425] Fix | Delete
if ( '' === $element || '<' !== $element[0] ) {
[426] Fix | Delete
continue;
[427] Fix | Delete
}
[428] Fix | Delete
[429] Fix | Delete
$noopen = false === strpos( $element, '[' );
[430] Fix | Delete
$noclose = false === strpos( $element, ']' );
[431] Fix | Delete
if ( $noopen || $noclose ) {
[432] Fix | Delete
// This element does not contain shortcodes.
[433] Fix | Delete
if ( $noopen xor $noclose ) {
[434] Fix | Delete
// Need to encode stray '[' or ']' chars.
[435] Fix | Delete
$element = strtr( $element, $trans );
[436] Fix | Delete
}
[437] Fix | Delete
continue;
[438] Fix | Delete
}
[439] Fix | Delete
[440] Fix | Delete
if ( $ignore_html || '<!--' === substr( $element, 0, 4 ) || '<![CDATA[' === substr( $element, 0, 9 ) ) {
[441] Fix | Delete
// Encode all '[' and ']' chars.
[442] Fix | Delete
$element = strtr( $element, $trans );
[443] Fix | Delete
continue;
[444] Fix | Delete
}
[445] Fix | Delete
[446] Fix | Delete
$attributes = wp_kses_attr_parse( $element );
[447] Fix | Delete
if ( false === $attributes ) {
[448] Fix | Delete
// Some plugins are doing things like [name] <[email]>.
[449] Fix | Delete
if ( 1 === preg_match( '%^<\s*\[\[?[^\[\]]+\]%', $element ) ) {
[450] Fix | Delete
$element = preg_replace_callback( "/$pattern/", 'do_shortcode_tag', $element );
[451] Fix | Delete
}
[452] Fix | Delete
[453] Fix | Delete
// Looks like we found some crazy unfiltered HTML. Skipping it for sanity.
[454] Fix | Delete
$element = strtr( $element, $trans );
[455] Fix | Delete
continue;
[456] Fix | Delete
}
[457] Fix | Delete
[458] Fix | Delete
// Get element name.
[459] Fix | Delete
$front = array_shift( $attributes );
[460] Fix | Delete
$back = array_pop( $attributes );
[461] Fix | Delete
$matches = array();
[462] Fix | Delete
preg_match( '%[a-zA-Z0-9]+%', $front, $matches );
[463] Fix | Delete
$elname = $matches[0];
[464] Fix | Delete
[465] Fix | Delete
// Look for shortcodes in each attribute separately.
[466] Fix | Delete
foreach ( $attributes as &$attr ) {
[467] Fix | Delete
$open = strpos( $attr, '[' );
[468] Fix | Delete
$close = strpos( $attr, ']' );
[469] Fix | Delete
if ( false === $open || false === $close ) {
[470] Fix | Delete
continue; // Go to next attribute. Square braces will be escaped at end of loop.
[471] Fix | Delete
}
[472] Fix | Delete
$double = strpos( $attr, '"' );
[473] Fix | Delete
$single = strpos( $attr, "'" );
[474] Fix | Delete
if ( ( false === $single || $open < $single ) && ( false === $double || $open < $double ) ) {
[475] Fix | Delete
/*
[476] Fix | Delete
* $attr like '[shortcode]' or 'name = [shortcode]' implies unfiltered_html.
[477] Fix | Delete
* In this specific situation we assume KSES did not run because the input
[478] Fix | Delete
* was written by an administrator, so we should avoid changing the output
[479] Fix | Delete
* and we do not need to run KSES here.
[480] Fix | Delete
*/
[481] Fix | Delete
$attr = preg_replace_callback( "/$pattern/", 'do_shortcode_tag', $attr );
[482] Fix | Delete
} else {
[483] Fix | Delete
// $attr like 'name = "[shortcode]"' or "name = '[shortcode]'".
[484] Fix | Delete
// We do not know if $content was unfiltered. Assume KSES ran before shortcodes.
[485] Fix | Delete
$count = 0;
[486] Fix | Delete
$new_attr = preg_replace_callback( "/$pattern/", 'do_shortcode_tag', $attr, -1, $count );
[487] Fix | Delete
if ( $count > 0 ) {
[488] Fix | Delete
// Sanitize the shortcode output using KSES.
[489] Fix | Delete
$new_attr = wp_kses_one_attr( $new_attr, $elname );
[490] Fix | Delete
if ( '' !== trim( $new_attr ) ) {
[491] Fix | Delete
// The shortcode is safe to use now.
[492] Fix | Delete
$attr = $new_attr;
[493] Fix | Delete
}
[494] Fix | Delete
}
[495] Fix | Delete
}
[496] Fix | Delete
}
[497] Fix | Delete
$element = $front . implode( '', $attributes ) . $back;
[498] Fix | Delete
[499] Fix | Delete
12
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function