Shortcodes.php
4.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
<?php
namespace AIOSEO\Plugin\Common\Traits\Helpers;
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Contains shortcode specific helper methods.
*
* @since 4.1.2
*/
trait Shortcodes {
/**
* Shortcodes known to conflict with AIOSEO.
*
* @since 4.1.2
*
* @var array
*/
private $conflictingShortcodes = [
'WooCommerce Login' => 'woocommerce_my_account',
'WooCommerce Checkout' => 'woocommerce_checkout',
'WooCommerce Order Tracking' => 'woocommerce_order_tracking',
'WooCommerce Cart' => 'woocommerce_cart',
'WooCommerce Registration' => 'wwp_registration_form',
'WISDM Group Registration' => 'wdm_group_users',
'WISDM Quiz Reporting' => 'wdm_quiz_statistics_details',
'WISDM Course Review' => 'rrf_course_review',
'Simple Membership Login' => 'swpm_login_form',
'Simple Membership Mini Login' => 'swpm_mini_login',
'Simple Membership Payment Button' => 'swpm_payment_button',
'Simple Membership Thank You Page' => 'swpm_thank_you_page_registration',
'Simple Membership Registration' => 'swpm_registration_form',
'Simple Membership Profile' => 'swpm_profile_form',
'Simple Membership Reset' => 'swpm_reset_form',
'Simple Membership Update Level' => 'swpm_update_level_to',
'Simple Membership Member Info' => 'swpm_show_member_info',
'Revslider' => 'rev_slider'
];
/**
* Returns the content with shortcodes replaced.
*
* @since 4.0.5
*
* @param string $content The post content.
* @param array $tagsToRemove Shortcode tags that should be removed before parsing the content.
* @param bool $override Whether shortcodes should be parsed regardless of the context. Needed for ActionScheduler actions.
* @return string $content The post content with shortcodes replaced.
*/
public function doShortcodes( $content, $tagsToRemove = [], $override = false ) {
if (
! $override &&
(
( is_admin() && ! wp_doing_ajax() && ! wp_doing_cron() ) ||
apply_filters( 'aioseo_disable_shortcode_parsing', false )
)
) {
return $content;
}
global $shortcode_tags;
$conflictingShortcodes = apply_filters( 'aioseo_conflicting_shortcodes', $this->conflictingShortcodes );
foreach ( $conflictingShortcodes as $shortcode ) {
$shortcodeTag = str_replace( [ '[', ']' ], '', $shortcode );
if ( array_key_exists( $shortcodeTag, $shortcode_tags ) ) {
$tagsToRemove[ $shortcodeTag ] = $shortcode_tags[ $shortcodeTag ];
}
}
// Remove all conflicting shortcodes before parsing the content.
foreach ( $tagsToRemove as $shortcodeTag => $shortcodeCallback ) {
remove_shortcode( $shortcodeTag );
}
$content = do_shortcode( $content );
// Add back shortcodes as remove_shortcode() disables them site-wide.
foreach ( $tagsToRemove as $shortcodeTag => $shortcodeCallback ) {
add_shortcode( $shortcodeTag, $shortcodeCallback );
}
return $content;
}
/**
* Returns the content with only the allowed shortcodes and wildcards replaced.
* This function should be used in Action Scheduler action callbacks only as it runs shortcodes everywhere, regardless of the context.
*
* @since 4.1.2
*
* @param string $content The content.
* @param array $allowedTags The allowed shortcode tags.
* @param array $wildcards The wildcards.
* @return string The content with shortcodes replaced.
*/
public function doAllowedShortcodes( $content, $allowedTags = [], $wildcards = [] ) {
// Extract list of shortcodes from the post content.
$tags = $this->getShortcodeTags( $content );
if ( ! count( $tags ) ) {
return $content;
}
// Include shortcodes that match wildcards with allowed shortcodes.
foreach ( $tags as $tag ) {
foreach ( $wildcards as $wildcard ) {
if ( preg_match( "/$wildcard/", $tag ) ) {
$allowedTags[] = $tag;
}
}
}
$tagsToRemove = array_diff( $tags, $allowedTags );
return $this->doShortcodes( $content, $tagsToRemove, true );
}
/**
* Extracts the shortcode tags from the content.
*
* @since 4.1.2
*
* @param string $content The content.
* @return array $tags The shortcode tags.
*/
private function getShortcodeTags( $content ) {
$tags = [];
$pattern = '\\[(\\[?)([^\s]*)(?![\\w-])([^\\]\\/]*(?:\\/(?!\\])[^\\]\\/]*)*?)(?:(\\/)\\]|\\](?:([^\\[]*+(?:\\[(?!\\/\\2\\])[^\\[]*+)*+)\\[\\/\\2\\])?)(\\]?)';
if ( preg_match_all( "#$pattern#s", $content, $matches ) && array_key_exists( 2, $matches ) ) {
$tags = array_unique( $matches[2] );
}
if ( ! count( $tags ) ) {
return $tags;
}
// Extract nested shortcodes.
foreach ( $matches[5] as $innerContent ) {
$tags = array_merge( $tags, $this->getShortcodeTags( $innerContent ) );
}
return $tags;
}
}