';
},
$content
);
return $content;
} else {
return '' . htmlspecialchars( $content ) . '
';
}
}
/**
* Ensures anchor tags open in a new tab when attributes are present.
*
* @param string $attrs Raw attribute string from the opening <a> tag.
*
* @return string
*/
protected function ensure_anchor_target_blank( $attrs ) {
if ( preg_match( '/\btarget\s*=\s*(["\']?)_blank\1/i', $attrs ) ) {
return $attrs;
}
if ( preg_match( '/\btarget\s*=\s*("|\')(.*?)\1/is', $attrs ) ) {
return preg_replace( '/\btarget\s*=\s*("|\')(.*?)\1/is', 'target="_blank"', $attrs, 1 );
}
if ( preg_match( '/\btarget\s*=\s*[^\s>]+/i', $attrs ) ) {
return preg_replace( '/\btarget\s*=\s*[^\s>]+/i', 'target="_blank"', $attrs, 1 );
}
return rtrim( $attrs ) . ' target="_blank"';
}
/**
* Ensures rel includes noopener and noreferrer (safe external links with target _blank).
*
* @param string $attrs Raw attribute string from the opening <a> tag.
*
* @return string
*/
protected function ensure_anchor_rel_noopener_noreferrer( $attrs ) {
$rel_quoted = '/\brel\s*=\s*(["\'])(.*?)\1/is';
if ( preg_match( $rel_quoted, $attrs, $rel_match ) ) {
$tokens = preg_split( '/\s+/', trim( $rel_match[2] ), -1, PREG_SPLIT_NO_EMPTY );
if ( $this->rel_has_noopener_and_noreferrer( $tokens ) ) {
return $attrs;
}
$tokens = $this->merge_rel_noopener_noreferrer_tokens( $tokens );
$new_rel = implode( ' ', $tokens );
return preg_replace( $rel_quoted, 'rel="' . $new_rel . '"', $attrs, 1 );
}
if ( preg_match( '/\brel\s*=\s*([^\s>]+)/i', $attrs, $rel_match ) ) {
$tokens = preg_split( '/\s+/', trim( $rel_match[1] ), -1, PREG_SPLIT_NO_EMPTY );
if ( $this->rel_has_noopener_and_noreferrer( $tokens ) ) {
return $attrs;
}
$tokens = $this->merge_rel_noopener_noreferrer_tokens( $tokens );
$new_rel = implode( ' ', $tokens );
return preg_replace( '/\brel\s*=\s*[^\s>]+/i', 'rel="' . $new_rel . '"', $attrs, 1 );
}
return rtrim( $attrs ) . ' rel="noopener noreferrer"';
}
/**
* @param array $tokens rel attribute tokens.
*
* @return bool
*/
protected function rel_has_noopener_and_noreferrer( array $tokens ) {
$lower = array_map( 'strtolower', $tokens );
return in_array( 'noopener', $lower, true ) && in_array( 'noreferrer', $lower, true );
}
/**
* @param array $tokens rel attribute tokens.
*
* @return array
*/
protected function merge_rel_noopener_noreferrer_tokens( array $tokens ) {
$lower = array_map( 'strtolower', $tokens );
if ( ! in_array( 'noopener', $lower, true ) ) {
$tokens[] = 'noopener';
}
if ( ! in_array( 'noreferrer', $lower, true ) ) {
$tokens[] = 'noreferrer';
}
return $tokens;
}
protected function validate() {
if ( ! parent::validate() ) {
return false;
}
if ( empty( $_REQUEST[ self::PARAM_EVENT_ID ] ) ) {
return false;
}
return true;
}
}