PluginProbe
Post Snippets – Custom WordPress Code Snippets Customizer / trunk
Post Snippets – Custom WordPress Code Snippets Customizer vtrunk
4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.1 1.7.2 1.7.3 1.8 1.8.1 1.8.2 1.8.3 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.8.9.1 1.8.9.2 1.9 1.9.1 1.9.2 1.9.3 1.9.4 1.9.5 All 115 releases
post-snippets / src / PostSnippets / Shortcode.php

Shortcode.php in Post Snippets – Custom WordPress Code Snippets Customizer trunk, at src/PostSnippets/Shortcode.php

297 lines 9.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace PostSnippets;
3
4 if ( ! defined( 'ABSPATH' ) ) exit;
5
6 /**
7 * Shortcode Handling.
8 *
9 */
10 class Shortcode
11 {
12 public function __construct()
13 {
14 $this->create();
15 }
16
17 /**
18 * Create the functions for shortcodes dynamically and register them
19 */
20 public function create()
21 {
22 global $wpdb;
23
24 $table_name = $wpdb->prefix . \PostSnippets::TABLE_NAME;
25
26 $snippets = $wpdb->get_results($wpdb->prepare("SELECT * FROM $table_name WHERE snippet_shortcode = %d AND snippet_status = 1 AND snippet_content != ''", 1), ARRAY_A );
27
28 foreach ($snippets as $snippet) {
29 add_shortcode( $snippet['snippet_title'],
30 function ( $atts, $content = null ) use ( $snippet ){
31 return $this->evaluateSnippet($snippet, $atts, $content);
32 });
33 }
34 }
35
36 public static function evaluateSnippet($snippet, $atts = array(), $content = null){
37
38 if( !empty($snippet) ){
39
40 $default_atts = self::filterVars( $snippet['snippet_vars'] );
41 $render_raw_html = self::shouldRenderRawHtml( $snippet );
42
43 foreach ((array) $atts as $key => $val) {
44 if ( is_numeric($key) ) {
45 $attribute = explode('=', $val, 2);
46
47 if (count($attribute) < 2) {
48 continue;
49 }
50
51 $keyName = trim($attribute[0]);
52 $keyValue = trim($attribute[1], " \t\n\r\0\x0B\"'");
53
54 $atts[$keyName] = $keyValue;
55 unset($atts[$key]);
56 }
57 }
58
59 $short_atts = shortcode_atts( $default_atts, $atts );
60
61 $snippet_content = $snippet['snippet_content'];
62
63 if ( ! empty( $snippet['snippet_php'] ) && (int) $snippet['snippet_php'] === 1 ) {
64 $snippet_content = stripslashes( $snippet_content );
65 }
66
67 if ( $content != null ) {
68 $short_atts["content"] = $content;
69 }
70 $snippet_content = self::replaceSnippetVariables(
71 $snippet_content,
72 $short_atts,
73 ! empty( $snippet['snippet_php'] ) && (int) $snippet['snippet_php'] === 1,
74 $render_raw_html
75 );
76
77 // There might be the case that a snippet contains
78 // the post snippets reserved variable {content} to
79 // capture the content in enclosed shortcodes, but
80 // the shortcode is used without enclosing it. To
81 // avoid outputting {content} as part of the string
82 // lets remove possible occurences.
83 $snippet_content = str_replace( "{content}", "", $snippet_content );
84
85 // Handle PHP shortcodes
86 if ( $snippet['snippet_php'] == 1 ) {
87 $snippet_content = self::phpEval( $snippet_content );
88
89 // WPTexturize the Snippet
90 if ( ! empty( $snippet['snippet_wptexturize'] ) && ( $snippet['snippet_wptexturize'] == true ) ) {
91 $snippet_content = html_entity_decode( addslashes ( wptexturize ( htmlentities( stripslashes ( $snippet_content ), ENT_NOQUOTES ) ) ) );
92 }
93
94 } else {
95 if ( ! empty( $snippet['snippet_wptexturize'] ) && ( $snippet['snippet_wptexturize'] == true ) ) {
96 $snippet_content = addslashes( wptexturize( stripslashes( $snippet_content ) ) );
97 }
98 }
99
100 $snippet_content = do_shortcode( stripslashes( $snippet_content ) );
101
102 return $snippet_content;
103 }
104 }
105
106 /**
107 * Evaluate a snippet as PHP code.
108 *
109 * @since Post Snippets 1.9
110 * @param string $content The snippet to evaluate
111 * @return string The result of the evaluation
112 */
113 public static function phpEval($content)
114 {
115 if (defined('POST_SNIPPETS_DISABLE_PHP')) {
116 return $content;
117 }
118
119 /**Removing Initial PHP Tag */
120 $content = ltrim($content, "<?php<?PHP<?=");
121
122 ob_start();
123 eval($content);
124 $content = ob_get_clean();
125
126 return addslashes($content);
127 }
128
129 public static function replaceSnippetVariables($snippet_content, $short_atts, $php_snippet = false, $render_raw_html = true)
130 {
131 foreach ( $short_atts as $key => $val ) {
132 $short_atts[ $key ] = self::sanitizeVariableValue( $key, $val, $php_snippet, $render_raw_html );
133 }
134
135 if ( $php_snippet ) {
136 return self::replacePhpVariables( $snippet_content, $short_atts );
137 }
138
139 foreach ( $short_atts as $key => $val ) {
140 $snippet_content = str_replace( '{' . $key . '}', $val, $snippet_content );
141 }
142
143 return $snippet_content;
144 }
145
146 public static function sanitizeVariableValue($key, $val, $php_snippet = false, $render_raw_html = true)
147 {
148 $val = (string) $val;
149
150 $colon = strpos($key, ':');
151
152 if ( $colon !== false ) {
153 $text = explode(":", $key);
154
155 switch (strtolower($text[1])) {
156 case 'url':
157 $val = esc_url( $val );
158 break;
159 case 'text':
160 $val = esc_html( $val );
161 break;
162 case 'attr':
163 $val = esc_attr( $val );
164 break;
165 case 'xml':
166 $val = esc_xml( $val );
167 break;
168 case 'textarea':
169 $val = esc_textarea( $val );
170 break;
171 }
172 }
173
174 if ( $php_snippet ) {
175 return $val;
176 }
177
178 if ( $colon !== false ) {
179 return $val;
180 }
181
182 // Normalize entity-encoded HTML first, then either allow it through (raw mode) or escape it once (text mode)
183 $val = html_entity_decode( $val, ENT_QUOTES );
184
185 return $render_raw_html ? $val : esc_html( $val );
186 }
187
188 public static function shouldRenderRawHtml( $snippet )
189 {
190 if ( ! array_key_exists( 'snippet_rawhtml', $snippet ) ) {
191 return true;
192 }
193
194 return (int) $snippet['snippet_rawhtml'] === 1;
195 }
196
197 public static function replacePhpVariables($snippet_content, $short_atts)
198 {
199 $string_pattern = '/\'(?:\\\\.|[^\'\\\\])*\'|"(?:\\\\.|[^"\\\\])*"/s';
200
201 $snippet_content = preg_replace_callback(
202 $string_pattern,
203 function ( $matches ) use ( $short_atts ) {
204 $literal = $matches[0];
205 $quote = $literal[0];
206 $body = substr( $literal, 1, -1 );
207
208 foreach ( $short_atts as $key => $val ) {
209 $body = str_replace(
210 '{' . $key . '}',
211 self::escapePhpStringLiteralValue( $val, $quote ),
212 $body
213 );
214 }
215
216 return $quote . $body . $quote;
217 },
218 $snippet_content
219 );
220
221 foreach ( $short_atts as $key => $val ) {
222 $snippet_content = str_replace( '{' . $key . '}', var_export( $val, true ), $snippet_content );
223 }
224
225 return $snippet_content;
226 }
227
228 public static function escapePhpStringLiteralValue($val, $quote)
229 {
230 if ( $quote === '"' ) {
231 return str_replace(
232 array( '\\', '"', '$' ),
233 array( '\\\\', '\\"', '\\$' ),
234 $val
235 );
236 }
237
238 return str_replace(
239 array( '\\', "'" ),
240 array( '\\\\', "\\'" ),
241 $val
242 );
243 }
244
245 /**
246 * Filters Snippet Variables
247 * of Undesired Text.
248 *
249 * @since Post Snippets 3.1.4
250 * @param string $vars The snippet variable string
251 * @return array The result of the evaluation
252 */
253 public static function filterVars($vars = '')
254 {
255 if ( empty($vars) ) {
256 return array();
257 }
258
259 if ( is_string($vars) ) {
260 $vars = explode(",", $vars);
261 }
262
263 if ( is_array($vars) ) {
264 $default_atts = array();
265
266 foreach ($vars as $key => $var) {
267 if ( !is_numeric($key) ) {
268 $default_atts[$key] = is_scalar($var) ? (string)$var : '';
269 continue;
270 }
271
272 if ( !is_string($var) ) {
273 continue;
274 }
275
276 $attribute = explode('=', $var); /**This Results in array seperated by = sign */
277
278 foreach ($attribute as $attr_key => $value) { //Filtering Empty Values generated with such variable texts one,two=,,,=xx=one,,==two
279 if( empty($value) ) unset($attribute[$attr_key]);
280 }
281
282 if( empty($attribute) ) continue; /**After Unsetting Empty values above, any empty array still remains, so this line is skipping that */
283
284 $attribute = array_values($attribute); //resetting index to start with zero
285
286 $default_value = (count($attribute) > 1) ? $attribute[1] : ''; /**Default values of vars, if set any */
287
288 $default_atts[$attribute[0]] = $default_value; /**Setting Default Atts for shortcode_atts */
289 }
290
291 return $default_atts;
292 }
293
294 return array();
295 }
296 }
297