PluginProbe ʕ •ᴥ•ʔ
Advanced Ads – Ad Manager & AdSense / trunk
Advanced Ads – Ad Manager & AdSense vtrunk
2.0.26 2.0.25 2.0.24 2.0.23 2.0.22 2.0.21 1.38.0 1.39.0 1.39.1 1.39.2 1.39.3 1.39.4 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.40.0 1.40.1 1.40.2 1.41.0 1.42.0 1.42.1 1.42.2 1.43.0 1.44.0 1.44.1 1.45.0 1.45.1 1.46.0 1.47.0 1.47.1 1.47.2 1.47.3 1.47.4 1.47.5 1.48.0 1.48.1 1.49.0 1.5.0 1.5.0.1 1.5.1 1.5.2 1.5.2.1 1.5.4 1.5.4.1 1.5.5 1.50.0 1.51.0 1.51.1 1.51.2 1.51.3 1.52.0 1.52.1 1.52.2 1.52.3 1.52.4 1.53.0 1.53.1 1.53.2 1.54.0 1.54.1 1.55.0 1.56.0 1.56.1 1.56.2 1.56.3 1.56.4 1.6 1.6.1 1.6.10 1.6.10.1 1.6.10.2 1.6.11 1.6.11.1 1.6.12 1.6.13 1.6.14 1.6.15 1.6.16 1.6.17 1.6.17.1 1.6.17.2 1.6.2 1.6.2.1 1.6.3 1.6.4 1.6.4.1 1.6.5 1.6.6 1.6.6.1 1.6.7 1.6.7.1 1.6.8 1.6.8.1 1.6.8.2 1.6.8.3 1.6.9 1.6.9.1 1.6.9.2 1.6.9.3 1.6.9.4 1.7 1.7.0.1 1.7.0.2 1.7.0.3 1.7.1 1.7.1.1 1.7.1.2 1.7.1.3 1.7.1.4 1.7.1.5 1.7.10 trunk 1.7.11 1.0.1 1.7.12 1.0.2 1.7.13 1.0.3 1.7.14 1.1.0 1.7.15 1.1.1 1.7.16 1.1.2 1.7.17 1.1.3 1.7.18 1.10 1.7.19 1.10.1 1.7.2 1.10.10 1.7.2.1 1.10.11 1.7.20 1.10.12 1.7.21 1.10.2 1.7.22 1.10.3 1.7.23 1.10.4 1.7.24 1.10.5 1.7.25 1.10.6 1.7.3 1.10.7 1.7.4 1.10.8 1.7.4.1 1.10.9 1.7.4.2 1.11 1.7.4.3 1.11.1 1.7.4.4 1.11.2 1.7.4.5 1.12 1.7.5 1.13 1.7.5.1 1.13.1 1.7.6 1.13.2 1.7.7 1.13.3 1.7.8 1.13.4 1.7.9 1.13.5 1.7.9.1 1.13.6 1.7.9.2 1.13.7 1.7.9.3 1.13.8 1.8 1.14 1.8.1 1.14.1 1.8.10 1.14.10 1.8.11 1.14.11 1.8.12 1.14.2 1.8.13 1.14.3 1.8.14 1.14.4 1.8.15 1.14.5 1.8.16 1.14.6 1.8.17 1.14.7 1.8.18 1.14.8 1.8.19 1.14.9 1.8.2 1.15 1.8.20 1.16 1.8.21 1.16.1 1.8.22 1.17 1.8.23 1.17.1 1.8.24 1.17.10 1.8.25 1.17.10-rc.1 1.8.26 1.17.11 1.8.27 1.17.12 1.8.28 1.17.12-rc.1 1.8.29 1.17.2 1.8.3 1.17.3 1.8.30 1.17.4 1.8.4 1.17.5 1.8.5 1.17.6 1.8.6 1.17.7 1.8.7 1.17.8 1.8.8 1.17.9 1.8.9 1.17.9-beta.1 1.9 1.18.0 2.0.0 1.19.0 2.0.1 1.19.1 2.0.10 1.2 2.0.11 1.2.1 2.0.12 1.2.2 2.0.13 1.2.3 2.0.14 1.2.4 2.0.15 1.2.5 2.0.16 1.2.6 2.0.17 1.2.7 2.0.18 1.20.0 2.0.19 1.20.0-rc.1 2.0.2 1.20.0-rc.2 2.0.20 1.20.1 2.0.3 1.20.2 2.0.4 1.20.3 2.0.5 1.21.0 2.0.6 1.21.1 2.0.7 1.22.0 2.0.8 1.22.1 2.0.9 1.22.2 1.23.0 1.23.1 1.23.2 1.24.0 1.24.1 1.24.2 1.25.0 1.25.1 1.26.0 1.27.0 1.28.0 1.29.0 1.29.1 1.3 1.3.1 1.3.10 1.3.11 1.3.12 1.3.13 1.3.14 1.3.15 1.3.16 1.3.17 1.3.18 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.30.0 1.30.1 1.30.2 1.30.2-rc.1 1.30.3 1.30.4 1.30.4-rc.1 1.30.5 1.31.0 1.31.1 1.32.0 1.32.0-rc.1 1.33.0 1.33.1 1.33.2 1.34.0 1.35.0 1.35.1 1.36.0 1.36.1 1.36.2 1.36.3 1.37.0 1.37.1 1.37.2
advanced-ads / includes / class-shortcodes.php
advanced-ads / includes Last commit date
abstracts 3 weeks ago admin 3 weeks ago ads 3 weeks ago compatibility 3 weeks ago crons 3 weeks ago frontend 3 weeks ago groups 3 weeks ago importers 3 weeks ago installation 3 weeks ago interfaces 3 weeks ago license 3 weeks ago placements 3 weeks ago rest 3 weeks ago traits 3 weeks ago utilities 3 weeks ago class-assets-registry.php 1 month ago class-autoloader.php 2 months ago class-cache-invalidator.php 3 weeks ago class-constants.php 3 weeks ago class-content-injector.php 3 weeks ago class-entities.php 5 months ago class-modal.php 3 weeks ago class-modules.php 3 weeks ago class-options.php 3 weeks ago class-plugin.php 3 weeks ago class-post-data.php 1 year ago class-shortcodes.php 3 weeks ago class-upgrades.php 3 weeks ago class-widget.php 3 weeks ago default-hooks.php 6 months ago functions-ad.php 3 weeks ago functions-components.php 3 weeks ago functions-conditional.php 1 year ago functions-core.php 1 year ago functions-group.php 3 weeks ago functions-placement.php 3 weeks ago functions.php 3 weeks ago index.php 2 years ago load_modules.php 3 weeks ago
class-shortcodes.php
226 lines
1 <?php
2 /**
3 * Shortcodes.
4 *
5 * @package AdvancedAds
6 * @author Advanced Ads <info@wpadvancedads.com>
7 * @since 1.50.0
8 */
9
10 namespace AdvancedAds;
11
12 use AdvancedAds\Framework\Interfaces\Integration_Interface;
13
14 defined( 'ABSPATH' ) || exit;
15
16 /**
17 * Shortcodes.
18 */
19 class Shortcodes implements Integration_Interface {
20
21 /**
22 * Hook into WordPress.
23 *
24 * @return void
25 */
26 public function hooks(): void {
27 add_shortcode( 'the_ad', [ $this, 'render_ad' ] );
28 add_shortcode( 'the_ad_group', [ $this, 'render_group' ] );
29 add_shortcode( 'the_ad_placement', [ $this, 'render_placement' ] );
30 }
31
32 /**
33 * Renders an ad based on the provided attributes.
34 *
35 * @param array<string, mixed> $atts The attributes for the ad.
36 *
37 * @return string The rendered ad.
38 */
39 public function render_ad( $atts ): string {
40 $ad = wp_advads_get_ad( absint( $atts['id'] ?? 0 ) );
41 // Early bail!!
42 if ( ! $ad ) {
43 return '';
44 }
45
46 $atts = is_array( $atts ) ? $atts : [];
47
48 // Check if there is an inline attribute with or without value.
49 if ( isset( $atts['inline'] ) || in_array( 'inline', $atts, true ) ) {
50 $atts['inline_wrapper_element'] = true;
51 }
52
53 $atts = $this->prepare_shortcode_atts( $atts );
54
55 $this->set_shortcode_atts( $ad, $atts );
56
57 return get_the_ad( $ad, '', $atts );
58 }
59
60 /**
61 * Renders a group based on the provided attributes.
62 *
63 * @param array<string, mixed> $atts The attributes for the group.
64 *
65 * @return string The rendered group.
66 */
67 public function render_group( $atts ): string {
68 $group = wp_advads_get_group( absint( $atts['id'] ?? 0 ) );
69 // Early bail!!
70 if ( ! $group ) {
71 return '';
72 }
73
74 $atts = is_array( $atts ) ? $atts : [];
75 $atts = $this->prepare_shortcode_atts( $atts );
76
77 $this->set_shortcode_atts( $group, $atts );
78
79 return get_the_group( $group, '', $atts );
80 }
81
82 /**
83 * Renders a placement based on the provided attributes.
84 *
85 * @param array<string, mixed> $atts The attributes for the placement.
86 *
87 * @return string The rendered placement.
88 */
89 public function render_placement( $atts ): string {
90 $placement = wp_advads_get_placement( (string) ( $atts['id'] ?? '' ) );
91 // Early bail!!
92 if ( ! $placement ) {
93 return '';
94 }
95
96 $atts = is_array( $atts ) ? $atts : [];
97 $atts = $this->prepare_shortcode_atts( $atts );
98
99 $this->set_shortcode_atts( $placement, $atts );
100
101 return get_the_placement( $placement, '', $atts );
102 }
103
104 /**
105 * Prepare shortcode attributes.
106 *
107 * @param array<string, mixed> $atts array with strings.
108 *
109 * @return array<string, mixed>
110 */
111 private function prepare_shortcode_atts( $atts ): array {
112 $result = [];
113
114 /**
115 * Prepare attributes by converting strings to multi-dimensional array
116 * Example: [ 'output__margin__top' => 1 ] => ['output']['margin']['top'] = 1
117 */
118 if ( ! defined( 'ADVANCED_ADS_DISABLE_CHANGE' ) || ! ADVANCED_ADS_DISABLE_CHANGE ) {
119 foreach ( $atts as $attr => $data ) {
120 // Remove the prefix (change-ad__, change-group__, change-placement__).
121 $attr = preg_replace( '/^(change-ad|change-group|change-placement)__/', '', $attr );
122 $levels = explode( '__', $attr );
123 $last = array_pop( $levels );
124
125 $cur_lvl = &$result;
126
127 foreach ( $levels as $lvl ) {
128 if ( ! isset( $cur_lvl[ $lvl ] ) ) {
129 $cur_lvl[ $lvl ] = [];
130 }
131
132 $cur_lvl = &$cur_lvl[ $lvl ];
133 }
134
135 $cur_lvl[ $last ] = $data;
136 }
137
138 $result = array_diff_key(
139 $result,
140 [
141 'id' => false,
142 'blog_id' => false,
143 'ad_args' => false,
144 ]
145 );
146 }
147
148 // Ad type: 'content' and a shortcode inside.
149 if ( isset( $atts['ad_args'] ) ) {
150 $result = array_merge( $result, $this->parse_shortcode_ad_args( $atts['ad_args'] ) );
151 }
152
153 // Flat output array for Ad.
154 if ( isset( $result['output'] ) && is_array( $result['output'] ) ) {
155 $result = array_merge( $result, $result['output'] );
156 unset( $result['output'] );
157 }
158
159 // Special cases.
160 if ( isset( $result['tracking']['link'] ) ) {
161 $result['url'] = $result['tracking']['link'];
162 unset( $result['tracking']['link'] );
163 }
164
165 if ( isset( $result['content'] ) && is_string( $result['content'] ) ) {
166 $result['content'] = $this->sanitize_shortcode_content( $result['content'] );
167 }
168
169 if ( isset( $result['override'] ) && is_string( $result['override'] ) ) {
170 $result['override'] = $this->sanitize_shortcode_content( $result['override'] );
171 }
172
173 return $result;
174 }
175
176 /**
177 * Sanitize shortcode content by stripping PHP payloads and running wp_kses_post().
178 *
179 * @param string $content Content override from shortcode attributes (ad_args, change-ad__, etc.).
180 *
181 * @return string
182 */
183 private function sanitize_shortcode_content( string $content ): string {
184 do {
185 $before = $content;
186 $content = preg_replace( '/<\\?(?:php|=)?[\\s\\S]*?(?:\\x3F\\x3E|$)/i', '', $content );
187 } while ( $content !== $before );
188
189 $content = str_replace( '<?', '', (string) $content );
190
191 return '' !== $content ? wp_kses_post( $content ) : '';
192 }
193
194 /**
195 * Parse ad_args payload for shortcode rendering.
196 *
197 * @param string $ad_args Raw urlencoded ad_args value.
198 *
199 * @return array<string, mixed>
200 */
201 private function parse_shortcode_ad_args( string $ad_args ): array {
202 $decoded_ad_args = json_decode( urldecode( $ad_args ), true );
203
204 return is_array( $decoded_ad_args ) ? $decoded_ad_args : [];
205 }
206
207 /**
208 * Set shortcode attributes.
209 *
210 * @param object $entity The entity object.
211 * @param array<string, mixed> $atts The attributes to set for the entity.
212 *
213 * @return void
214 */
215 private function set_shortcode_atts( $entity, $atts ): void {
216 foreach ( $atts as $key => $value ) {
217 $entity->set_prop_temp( $key, $value );
218 }
219
220 // WP Security: disable PHP for shortcode renders. prevents unauthorized PHP execution.
221 if ( isset( $atts['allow_php'] ) ) {
222 $entity->set_prop_temp( 'allow_php', false );
223 }
224 }
225 }
226