[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

/wp-includes/ -> shortcodes.php (source)

   1  <?php
   2  /**
   3   * WordPress API for creating bbcode-like tags or what WordPress calls
   4   * "shortcodes". The tag and attribute parsing or regular expression code is
   5   * based on the Textpattern tag parser.
   6   *
   7   * A few examples are below:
   8   *
   9   * [shortcode /]
  10   * [shortcode foo="bar" baz="bing" /]
  11   * [shortcode foo="bar"]content[/shortcode]
  12   *
  13   * Shortcode tags support attributes and enclosed content, but does not entirely
  14   * support inline shortcodes in other shortcodes. You will have to call the
  15   * shortcode parser in your function to account for that.
  16   *
  17   * {@internal
  18   * Please be aware that the above note was made during the beta of WordPress 2.6
  19   * and in the future may not be accurate. Please update the note when it is no
  20   * longer the case.}}
  21   *
  22   * To apply shortcode tags to content:
  23   *
  24   *     $out = do_shortcode( $content );
  25   *
  26   * @link https://developer.wordpress.org/plugins/shortcodes/
  27   *
  28   * @package WordPress
  29   * @subpackage Shortcodes
  30   * @since 2.5.0
  31   */
  32  
  33  /**
  34   * Container for storing shortcode tags and their hook to call for the shortcode
  35   *
  36   * @since 2.5.0
  37   *
  38   * @name $shortcode_tags
  39   * @var array
  40   * @global array $shortcode_tags
  41   */
  42  $shortcode_tags = array();
  43  
  44  /**
  45   * Adds a new shortcode.
  46   *
  47   * Care should be taken through prefixing or other means to ensure that the
  48   * shortcode tag being added is unique and will not conflict with other,
  49   * already-added shortcode tags. In the event of a duplicated tag, the tag
  50   * loaded last will take precedence.
  51   *
  52   * @since 2.5.0
  53   *
  54   * @global array $shortcode_tags
  55   *
  56   * @param string   $tag      Shortcode tag to be searched in post content.
  57   * @param callable $callback The callback function to run when the shortcode is found.
  58   *                           Every shortcode callback is passed three parameters by default,
  59   *                           including an array of attributes (`$atts`), the shortcode content
  60   *                           or null if not set (`$content`), and finally the shortcode tag
  61   *                           itself (`$shortcode_tag`), in that order.
  62   */
  63  function add_shortcode( $tag, $callback ) {
  64      global $shortcode_tags;
  65  
  66      if ( '' === trim( $tag ) ) {
  67          _doing_it_wrong(
  68              __FUNCTION__,
  69              __( 'Invalid shortcode name: Empty name given.' ),
  70              '4.4.0'
  71          );
  72          return;
  73      }
  74  
  75      if ( 0 !== preg_match( '@[<>&/\[\]\x00-\x20=]@', $tag ) ) {
  76          _doing_it_wrong(
  77              __FUNCTION__,
  78              sprintf(
  79                  /* translators: 1: Shortcode name, 2: Space-separated list of reserved characters. */
  80                  __( 'Invalid shortcode name: %1$s. Do not use spaces or reserved characters: %2$s' ),
  81                  $tag,
  82                  '& / < > [ ] ='
  83              ),
  84              '4.4.0'
  85          );
  86          return;
  87      }
  88  
  89      $shortcode_tags[ $tag ] = $callback;
  90  }
  91  
  92  /**
  93   * Removes hook for shortcode.
  94   *
  95   * @since 2.5.0
  96   *
  97   * @global array $shortcode_tags
  98   *
  99   * @param string $tag Shortcode tag to remove hook for.
 100   */
 101  function remove_shortcode( $tag ) {
 102      global $shortcode_tags;
 103  
 104      unset( $shortcode_tags[ $tag ] );
 105  }
 106  
 107  /**
 108   * Clear all shortcodes.
 109   *
 110   * This function is simple, it clears all of the shortcode tags by replacing the
 111   * shortcodes global by a empty array. This is actually a very efficient method
 112   * for removing all shortcodes.
 113   *
 114   * @since 2.5.0
 115   *
 116   * @global array $shortcode_tags
 117   */
 118  function remove_all_shortcodes() {
 119      global $shortcode_tags;
 120  
 121      $shortcode_tags = array();
 122  }
 123  
 124  /**
 125   * Whether a registered shortcode exists named $tag
 126   *
 127   * @since 3.6.0
 128   *
 129   * @global array $shortcode_tags List of shortcode tags and their callback hooks.
 130   *
 131   * @param string $tag Shortcode tag to check.
 132   * @return bool Whether the given shortcode exists.
 133   */
 134  function shortcode_exists( $tag ) {
 135      global $shortcode_tags;
 136      return array_key_exists( $tag, $shortcode_tags );
 137  }
 138  
 139  /**
 140   * Whether the passed content contains the specified shortcode
 141   *
 142   * @since 3.6.0
 143   *
 144   * @global array $shortcode_tags
 145   *
 146   * @param string $content Content to search for shortcodes.
 147   * @param string $tag     Shortcode tag to check.
 148   * @return bool Whether the passed content contains the given shortcode.
 149   */
 150  function has_shortcode( $content, $tag ) {
 151      if ( false === strpos( $content, '[' ) ) {
 152          return false;
 153      }
 154  
 155      if ( shortcode_exists( $tag ) ) {
 156          preg_match_all( '/' . get_shortcode_regex() . '/', $content, $matches, PREG_SET_ORDER );
 157          if ( empty( $matches ) ) {
 158              return false;
 159          }
 160  
 161          foreach ( $matches as $shortcode ) {
 162              if ( $tag === $shortcode[2] ) {
 163                  return true;
 164              } elseif ( ! empty( $shortcode[5] ) && has_shortcode( $shortcode[5], $tag ) ) {
 165                  return true;
 166              }
 167          }
 168      }
 169      return false;
 170  }
 171  
 172  /**
 173   * Search content for shortcodes and filter shortcodes through their hooks.
 174   *
 175   * This function is an alias for do_shortcode().
 176   *
 177   * @since 5.4.0
 178   *
 179   * @see do_shortcode()
 180   *
 181   * @param string $content     Content to search for shortcodes.
 182   * @param bool   $ignore_html When true, shortcodes inside HTML elements will be skipped.
 183   *                            Default false.
 184   * @return string Content with shortcodes filtered out.
 185   */
 186  function apply_shortcodes( $content, $ignore_html = false ) {
 187      return do_shortcode( $content, $ignore_html );
 188  }
 189  
 190  /**
 191   * Search content for shortcodes and filter shortcodes through their hooks.
 192   *
 193   * If there are no shortcode tags defined, then the content will be returned
 194   * without any filtering. This might cause issues when plugins are disabled but
 195   * the shortcode will still show up in the post or content.
 196   *
 197   * @since 2.5.0
 198   *
 199   * @global array $shortcode_tags List of shortcode tags and their callback hooks.
 200   *
 201   * @param string $content     Content to search for shortcodes.
 202   * @param bool   $ignore_html When true, shortcodes inside HTML elements will be skipped.
 203   *                            Default false.
 204   * @return string Content with shortcodes filtered out.
 205   */
 206  function do_shortcode( $content, $ignore_html = false ) {
 207      global $shortcode_tags;
 208  
 209      if ( false === strpos( $content, '[' ) ) {
 210          return $content;
 211      }
 212  
 213      if ( empty( $shortcode_tags ) || ! is_array( $shortcode_tags ) ) {
 214          return $content;
 215      }
 216  
 217      // Find all registered tag names in $content.
 218      preg_match_all( '@\[([^<>&/\[\]\x00-\x20=]++)@', $content, $matches );
 219      $tagnames = array_intersect( array_keys( $shortcode_tags ), $matches[1] );
 220  
 221      if ( empty( $tagnames ) ) {
 222          return $content;
 223      }
 224  
 225      $content = do_shortcodes_in_html_tags( $content, $ignore_html, $tagnames );
 226  
 227      $pattern = get_shortcode_regex( $tagnames );
 228      $content = preg_replace_callback( "/$pattern/", 'do_shortcode_tag', $content );
 229  
 230      // Always restore square braces so we don't break things like <!--[if IE ]>.
 231      $content = unescape_invalid_shortcodes( $content );
 232  
 233      return $content;
 234  }
 235  
 236  /**
 237   * Retrieve the shortcode regular expression for searching.
 238   *
 239   * The regular expression combines the shortcode tags in the regular expression
 240   * in a regex class.
 241   *
 242   * The regular expression contains 6 different sub matches to help with parsing.
 243   *
 244   * 1 - An extra [ to allow for escaping shortcodes with double [[]]
 245   * 2 - The shortcode name
 246   * 3 - The shortcode argument list
 247   * 4 - The self closing /
 248   * 5 - The content of a shortcode when it wraps some content.
 249   * 6 - An extra ] to allow for escaping shortcodes with double [[]]
 250   *
 251   * @since 2.5.0
 252   * @since 4.4.0 Added the `$tagnames` parameter.
 253   *
 254   * @global array $shortcode_tags
 255   *
 256   * @param array $tagnames Optional. List of shortcodes to find. Defaults to all registered shortcodes.
 257   * @return string The shortcode search regular expression
 258   */
 259  function get_shortcode_regex( $tagnames = null ) {
 260      global $shortcode_tags;
 261  
 262      if ( empty( $tagnames ) ) {
 263          $tagnames = array_keys( $shortcode_tags );
 264      }
 265      $tagregexp = implode( '|', array_map( 'preg_quote', $tagnames ) );
 266  
 267      // WARNING! Do not change this regex without changing do_shortcode_tag() and strip_shortcode_tag().
 268      // Also, see shortcode_unautop() and shortcode.js.
 269  
 270      // phpcs:disable Squiz.Strings.ConcatenationSpacing.PaddingFound -- don't remove regex indentation
 271      return '\\['                             // Opening bracket.
 272          . '(\\[?)'                           // 1: Optional second opening bracket for escaping shortcodes: [[tag]].
 273          . "($tagregexp)"                     // 2: Shortcode name.
 274          . '(?![\\w-])'                       // Not followed by word character or hyphen.
 275          . '('                                // 3: Unroll the loop: Inside the opening shortcode tag.
 276          .     '[^\\]\\/]*'                   // Not a closing bracket or forward slash.
 277          .     '(?:'
 278          .         '\\/(?!\\])'               // A forward slash not followed by a closing bracket.
 279          .         '[^\\]\\/]*'               // Not a closing bracket or forward slash.
 280          .     ')*?'
 281          . ')'
 282          . '(?:'
 283          .     '(\\/)'                        // 4: Self closing tag...
 284          .     '\\]'                          // ...and closing bracket.
 285          . '|'
 286          .     '\\]'                          // Closing bracket.
 287          .     '(?:'
 288          .         '('                        // 5: Unroll the loop: Optionally, anything between the opening and closing shortcode tags.
 289          .             '[^\\[]*+'             // Not an opening bracket.
 290          .             '(?:'
 291          .                 '\\[(?!\\/\\2\\])' // An opening bracket not followed by the closing shortcode tag.
 292          .                 '[^\\[]*+'         // Not an opening bracket.
 293          .             ')*+'
 294          .         ')'
 295          .         '\\[\\/\\2\\]'             // Closing shortcode tag.
 296          .     ')?'
 297          . ')'
 298          . '(\\]?)';                          // 6: Optional second closing brocket for escaping shortcodes: [[tag]].
 299      // phpcs:enable
 300  }
 301  
 302  /**
 303   * Regular Expression callable for do_shortcode() for calling shortcode hook.
 304   *
 305   * @see get_shortcode_regex() for details of the match array contents.
 306   *
 307   * @since 2.5.0
 308   * @access private
 309   *
 310   * @global array $shortcode_tags
 311   *
 312   * @param array $m Regular expression match array.
 313   * @return string|false Shortcode output on success, false on failure.
 314   */
 315  function do_shortcode_tag( $m ) {
 316      global $shortcode_tags;
 317  
 318      // Allow [[foo]] syntax for escaping a tag.
 319      if ( '[' === $m[1] && ']' === $m[6] ) {
 320          return substr( $m[0], 1, -1 );
 321      }
 322  
 323      $tag  = $m[2];
 324      $attr = shortcode_parse_atts( $m[3] );
 325  
 326      if ( ! is_callable( $shortcode_tags[ $tag ] ) ) {
 327          _doing_it_wrong(
 328              __FUNCTION__,
 329              /* translators: %s: Shortcode tag. */
 330              sprintf( __( 'Attempting to parse a shortcode without a valid callback: %s' ), $tag ),
 331              '4.3.0'
 332          );
 333          return $m[0];
 334      }
 335  
 336      /**
 337       * Filters whether to call a shortcode callback.
 338       *
 339       * Returning a non-false value from filter will short-circuit the
 340       * shortcode generation process, returning that value instead.
 341       *
 342       * @since 4.7.0
 343       *
 344       * @param false|string $return      Short-circuit return value. Either false or the value to replace the shortcode with.
 345       * @param string       $tag         Shortcode name.
 346       * @param array|string $attr        Shortcode attributes array or empty string.
 347       * @param array        $m           Regular expression match array.
 348       */
 349      $return = apply_filters( 'pre_do_shortcode_tag', false, $tag, $attr, $m );
 350      if ( false !== $return ) {
 351          return $return;
 352      }
 353  
 354      $content = isset( $m[5] ) ? $m[5] : null;
 355  
 356      $output = $m[1] . call_user_func( $shortcode_tags[ $tag ], $attr, $content, $tag ) . $m[6];
 357  
 358      /**
 359       * Filters the output created by a shortcode callback.
 360       *
 361       * @since 4.7.0
 362       *
 363       * @param string       $output Shortcode output.
 364       * @param string       $tag    Shortcode name.
 365       * @param array|string $attr   Shortcode attributes array or empty string.
 366       * @param array        $m      Regular expression match array.
 367       */
 368      return apply_filters( 'do_shortcode_tag', $output, $tag, $attr, $m );
 369  }
 370  
 371  /**
 372   * Search only inside HTML elements for shortcodes and process them.
 373   *
 374   * Any [ or ] characters remaining inside elements will be HTML encoded
 375   * to prevent interference with shortcodes that are outside the elements.
 376   * Assumes $content processed by KSES already.  Users with unfiltered_html
 377   * capability may get unexpected output if angle braces are nested in tags.
 378   *
 379   * @since 4.2.3
 380   *
 381   * @param string $content     Content to search for shortcodes.
 382   * @param bool   $ignore_html When true, all square braces inside elements will be encoded.
 383   * @param array  $tagnames    List of shortcodes to find.
 384   * @return string Content with shortcodes filtered out.
 385   */
 386  function do_shortcodes_in_html_tags( $content, $ignore_html, $tagnames ) {
 387      // Normalize entities in unfiltered HTML before adding placeholders.
 388      $trans   = array(
 389          '&#91;' => '&#091;',
 390          '&#93;' => '&#093;',
 391      );
 392      $content = strtr( $content, $trans );
 393      $trans   = array(
 394          '[' => '&#91;',
 395          ']' => '&#93;',
 396      );
 397  
 398      $pattern = get_shortcode_regex( $tagnames );
 399      $textarr = wp_html_split( $content );
 400  
 401      foreach ( $textarr as &$element ) {
 402          if ( '' === $element || '<' !== $element[0] ) {
 403              continue;
 404          }
 405  
 406          $noopen  = false === strpos( $element, '[' );
 407          $noclose = false === strpos( $element, ']' );
 408          if ( $noopen || $noclose ) {
 409              // This element does not contain shortcodes.
 410              if ( $noopen xor $noclose ) {
 411                  // Need to encode stray '[' or ']' chars.
 412                  $element = strtr( $element, $trans );
 413              }
 414              continue;
 415          }
 416  
 417          if ( $ignore_html || '<!--' === substr( $element, 0, 4 ) || '<![CDATA[' === substr( $element, 0, 9 ) ) {
 418              // Encode all '[' and ']' chars.
 419              $element = strtr( $element, $trans );
 420              continue;
 421          }
 422  
 423          $attributes = wp_kses_attr_parse( $element );
 424          if ( false === $attributes ) {
 425              // Some plugins are doing things like [name] <[email]>.
 426              if ( 1 === preg_match( '%^<\s*\[\[?[^\[\]]+\]%', $element ) ) {
 427                  $element = preg_replace_callback( "/$pattern/", 'do_shortcode_tag', $element );
 428              }
 429  
 430              // Looks like we found some crazy unfiltered HTML. Skipping it for sanity.
 431              $element = strtr( $element, $trans );
 432              continue;
 433          }
 434  
 435          // Get element name.
 436          $front   = array_shift( $attributes );
 437          $back    = array_pop( $attributes );
 438          $matches = array();
 439          preg_match( '%[a-zA-Z0-9]+%', $front, $matches );
 440          $elname = $matches[0];
 441  
 442          // Look for shortcodes in each attribute separately.
 443          foreach ( $attributes as &$attr ) {
 444              $open  = strpos( $attr, '[' );
 445              $close = strpos( $attr, ']' );
 446              if ( false === $open || false === $close ) {
 447                  continue; // Go to next attribute. Square braces will be escaped at end of loop.
 448              }
 449              $double = strpos( $attr, '"' );
 450              $single = strpos( $attr, "'" );
 451              if ( ( false === $single || $open < $single ) && ( false === $double || $open < $double ) ) {
 452                  /*
 453                   * $attr like '[shortcode]' or 'name = [shortcode]' implies unfiltered_html.
 454                   * In this specific situation we assume KSES did not run because the input
 455                   * was written by an administrator, so we should avoid changing the output
 456                   * and we do not need to run KSES here.
 457                   */
 458                  $attr = preg_replace_callback( "/$pattern/", 'do_shortcode_tag', $attr );
 459              } else {
 460                  // $attr like 'name = "[shortcode]"' or "name = '[shortcode]'".
 461                  // We do not know if $content was unfiltered. Assume KSES ran before shortcodes.
 462                  $count    = 0;
 463                  $new_attr = preg_replace_callback( "/$pattern/", 'do_shortcode_tag', $attr, -1, $count );
 464                  if ( $count > 0 ) {
 465                      // Sanitize the shortcode output using KSES.
 466                      $new_attr = wp_kses_one_attr( $new_attr, $elname );
 467                      if ( '' !== trim( $new_attr ) ) {
 468                          // The shortcode is safe to use now.
 469                          $attr = $new_attr;
 470                      }
 471                  }
 472              }
 473          }
 474          $element = $front . implode( '', $attributes ) . $back;
 475  
 476          // Now encode any remaining '[' or ']' chars.
 477          $element = strtr( $element, $trans );
 478      }
 479  
 480      $content = implode( '', $textarr );
 481  
 482      return $content;
 483  }
 484  
 485  /**
 486   * Remove placeholders added by do_shortcodes_in_html_tags().
 487   *
 488   * @since 4.2.3
 489   *
 490   * @param string $content Content to search for placeholders.
 491   * @return string Content with placeholders removed.
 492   */
 493  function unescape_invalid_shortcodes( $content ) {
 494      // Clean up entire string, avoids re-parsing HTML.
 495      $trans = array(
 496          '&#91;' => '[',
 497          '&#93;' => ']',
 498      );
 499  
 500      $content = strtr( $content, $trans );
 501  
 502      return $content;
 503  }
 504  
 505  /**
 506   * Retrieve the shortcode attributes regex.
 507   *
 508   * @since 4.4.0
 509   *
 510   * @return string The shortcode attribute regular expression
 511   */
 512  function get_shortcode_atts_regex() {
 513      return '/([\w-]+)\s*=\s*"([^"]*)"(?:\s|$)|([\w-]+)\s*=\s*\'([^\']*)\'(?:\s|$)|([\w-]+)\s*=\s*([^\s\'"]+)(?:\s|$)|"([^"]*)"(?:\s|$)|\'([^\']*)\'(?:\s|$)|(\S+)(?:\s|$)/';
 514  }
 515  
 516  /**
 517   * Retrieve all attributes from the shortcodes tag.
 518   *
 519   * The attributes list has the attribute name as the key and the value of the
 520   * attribute as the value in the key/value pair. This allows for easier
 521   * retrieval of the attributes, since all attributes have to be known.
 522   *
 523   * @since 2.5.0
 524   *
 525   * @param string $text
 526   * @return array|string List of attribute values.
 527   *                      Returns empty array if '""' === trim( $text ).
 528   *                      Returns empty string if '' === trim( $text ).
 529   *                      All other matches are checked for not empty().
 530   */
 531  function shortcode_parse_atts( $text ) {
 532      $atts    = array();
 533      $pattern = get_shortcode_atts_regex();
 534      $text    = preg_replace( "/[\x{00a0}\x{200b}]+/u", ' ', $text );
 535      if ( preg_match_all( $pattern, $text, $match, PREG_SET_ORDER ) ) {
 536          foreach ( $match as $m ) {
 537              if ( ! empty( $m[1] ) ) {
 538                  $atts[ strtolower( $m[1] ) ] = stripcslashes( $m[2] );
 539              } elseif ( ! empty( $m[3] ) ) {
 540                  $atts[ strtolower( $m[3] ) ] = stripcslashes( $m[4] );
 541              } elseif ( ! empty( $m[5] ) ) {
 542                  $atts[ strtolower( $m[5] ) ] = stripcslashes( $m[6] );
 543              } elseif ( isset( $m[7] ) && strlen( $m[7] ) ) {
 544                  $atts[] = stripcslashes( $m[7] );
 545              } elseif ( isset( $m[8] ) && strlen( $m[8] ) ) {
 546                  $atts[] = stripcslashes( $m[8] );
 547              } elseif ( isset( $m[9] ) ) {
 548                  $atts[] = stripcslashes( $m[9] );
 549              }
 550          }
 551  
 552          // Reject any unclosed HTML elements.
 553          foreach ( $atts as &$value ) {
 554              if ( false !== strpos( $value, '<' ) ) {
 555                  if ( 1 !== preg_match( '/^[^<]*+(?:<[^>]*+>[^<]*+)*+$/', $value ) ) {
 556                      $value = '';
 557                  }
 558              }
 559          }
 560      } else {
 561          $atts = ltrim( $text );
 562      }
 563  
 564      return $atts;
 565  }
 566  
 567  /**
 568   * Combine user attributes with known attributes and fill in defaults when needed.
 569   *
 570   * The pairs should be considered to be all of the attributes which are
 571   * supported by the caller and given as a list. The returned attributes will
 572   * only contain the attributes in the $pairs list.
 573   *
 574   * If the $atts list has unsupported attributes, then they will be ignored and
 575   * removed from the final returned list.
 576   *
 577   * @since 2.5.0
 578   *
 579   * @param array  $pairs     Entire list of supported attributes and their defaults.
 580   * @param array  $atts      User defined attributes in shortcode tag.
 581   * @param string $shortcode Optional. The name of the shortcode, provided for context to enable filtering
 582   * @return array Combined and filtered attribute list.
 583   */
 584  function shortcode_atts( $pairs, $atts, $shortcode = '' ) {
 585      $atts = (array) $atts;
 586      $out  = array();
 587      foreach ( $pairs as $name => $default ) {
 588          if ( array_key_exists( $name, $atts ) ) {
 589              $out[ $name ] = $atts[ $name ];
 590          } else {
 591              $out[ $name ] = $default;
 592          }
 593      }
 594  
 595      if ( $shortcode ) {
 596          /**
 597           * Filters shortcode attributes.
 598           *
 599           * If the third parameter of the shortcode_atts() function is present then this filter is available.
 600           * The third parameter, $shortcode, is the name of the shortcode.
 601           *
 602           * @since 3.6.0
 603           * @since 4.4.0 Added the `$shortcode` parameter.
 604           *
 605           * @param array  $out       The output array of shortcode attributes.
 606           * @param array  $pairs     The supported attributes and their defaults.
 607           * @param array  $atts      The user defined shortcode attributes.
 608           * @param string $shortcode The shortcode name.
 609           */
 610          $out = apply_filters( "shortcode_atts_{$shortcode}", $out, $pairs, $atts, $shortcode );
 611      }
 612  
 613      return $out;
 614  }
 615  
 616  /**
 617   * Remove all shortcode tags from the given content.
 618   *
 619   * @since 2.5.0
 620   *
 621   * @global array $shortcode_tags
 622   *
 623   * @param string $content Content to remove shortcode tags.
 624   * @return string Content without shortcode tags.
 625   */
 626  function strip_shortcodes( $content ) {
 627      global $shortcode_tags;
 628  
 629      if ( false === strpos( $content, '[' ) ) {
 630          return $content;
 631      }
 632  
 633      if ( empty( $shortcode_tags ) || ! is_array( $shortcode_tags ) ) {
 634          return $content;
 635      }
 636  
 637      // Find all registered tag names in $content.
 638      preg_match_all( '@\[([^<>&/\[\]\x00-\x20=]++)@', $content, $matches );
 639  
 640      $tags_to_remove = array_keys( $shortcode_tags );
 641  
 642      /**
 643       * Filters the list of shortcode tags to remove from the content.
 644       *
 645       * @since 4.7.0
 646       *
 647       * @param array  $tags_to_remove Array of shortcode tags to remove.
 648       * @param string $content        Content shortcodes are being removed from.
 649       */
 650      $tags_to_remove = apply_filters( 'strip_shortcodes_tagnames', $tags_to_remove, $content );
 651  
 652      $tagnames = array_intersect( $tags_to_remove, $matches[1] );
 653  
 654      if ( empty( $tagnames ) ) {
 655          return $content;
 656      }
 657  
 658      $content = do_shortcodes_in_html_tags( $content, true, $tagnames );
 659  
 660      $pattern = get_shortcode_regex( $tagnames );
 661      $content = preg_replace_callback( "/$pattern/", 'strip_shortcode_tag', $content );
 662  
 663      // Always restore square braces so we don't break things like <!--[if IE ]>.
 664      $content = unescape_invalid_shortcodes( $content );
 665  
 666      return $content;
 667  }
 668  
 669  /**
 670   * Strips a shortcode tag based on RegEx matches against post content.
 671   *
 672   * @since 3.3.0
 673   *
 674   * @param array $m RegEx matches against post content.
 675   * @return string|false The content stripped of the tag, otherwise false.
 676   */
 677  function strip_shortcode_tag( $m ) {
 678      // Allow [[foo]] syntax for escaping a tag.
 679      if ( '[' === $m[1] && ']' === $m[6] ) {
 680          return substr( $m[0], 1, -1 );
 681      }
 682  
 683      return $m[1] . $m[6];
 684  }


Generated: Thu Nov 21 01:00:03 2024 Cross-referenced by PHPXref 0.7.1