PluginProbe ʕ •ᴥ•ʔ
Advanced Ads – Ad Manager & AdSense / trunk
Advanced Ads – Ad Manager & AdSense vtrunk
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 1 day ago admin 1 day ago ads 1 day ago compatibility 1 day ago crons 1 day ago frontend 1 day ago groups 1 day ago importers 1 day ago installation 1 year ago interfaces 4 months ago license 3 months ago placements 1 day ago rest 1 year ago traits 1 day ago utilities 1 day ago cap_map.php 3 years ago class-assets-registry.php 3 weeks ago class-autoloader.php 1 day ago class-cache-invalidator.php 1 day ago class-constants.php 1 year ago class-content-injector.php 3 weeks ago class-entities.php 3 months ago class-modal.php 1 year ago class-modules.php 1 year ago class-options.php 1 year ago class-plugin.php 1 day ago class-post-data.php 10 months ago class-shortcodes.php 1 day ago class-upgrades.php 1 year ago class-widget.php 11 months ago default-hooks.php 4 months ago functions-ad.php 1 day ago functions-components.php 3 months ago functions-conditional.php 1 year ago functions-core.php 1 year ago functions-group.php 1 day ago functions-placement.php 1 day ago functions.php 1 day ago index.php 2 years ago load_modules.php 2 years 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 $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 $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 $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 $atts array with strings.
108 *
109 * @return array
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'] = wp_kses_post( $this->sanitize_shortcode_content( $result['override'] ) );
171 }
172
173 return $result;
174 }
175
176 /**
177 * Sanitize shortcode content override by stripping PHP payloads only.
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 ? $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
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 $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