PluginProbe
Code Snippets / 2.13.3
Code Snippets v2.13.3
4.0.0-beta.2 3.10.2 3.10.1 3.10.0 3.10.0-beta.2 3.10.0-beta.1 4.0.0-beta.1 3.9.6 trunk 2.10.0 2.10.1 2.12.0 2.12.1 2.13.0 2.13.1 2.13.2 2.13.3 2.14.0 2.14.1 2.14.2 2.14.3 2.14.4 2.14.5 2.14.6 3.0.0 All 65 releases
code-snippets / php / class-snippet.php

class-snippet.php in Code Snippets 2.13.3, at php/class-snippet.php

375 lines 8.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * A snippet object
5 *
6 * @since 2.4.0
7 * @package Code_Snippets
8 *
9 * @property int $id The database ID
10 * @property string $name The display name
11 * @property string $desc The formatted description
12 * @property string $code The executable code
13 * @property array $tags An array of the tags
14 * @property string $scope The scope name
15 * @property int $priority Execution priority
16 * @property bool $active The active status
17 * @property bool $network true if is multisite-wide snippet, false if site-wide
18 * @property bool $shared_network Whether the snippet is a shared network snippet
19 *
20 * @property-read array $tags_list The tags in string list format
21 * @property-read string $scope_icon The dashicon used to represent the current scope
22 */
23 class Code_Snippet {
24
25 /**
26 * The snippet metadata fields.
27 * Initialized with default values.
28 * @var array
29 */
30 private $fields = array(
31 'id' => 0,
32 'name' => '',
33 'desc' => '',
34 'code' => '',
35 'tags' => array(),
36 'scope' => 'global',
37 'active' => false,
38 'priority' => 10,
39 'network' => null,
40 'shared_network' => null,
41 );
42
43 /**
44 * List of field aliases
45 * @var array
46 */
47 private static $field_aliases = array(
48 'description' => 'desc',
49 );
50
51 /**
52 * Constructor function
53 *
54 * @param array|object $fields Initial snippet fields
55 */
56 public function __construct( $fields = null ) {
57 $this->set_fields( $fields );
58 }
59
60 /**
61 * Set all of the snippet fields from an array or object.
62 * Invalid fields will be ignored
63 *
64 * @param array|object $fields List of fields
65 */
66 public function set_fields( $fields ) {
67
68 /* Only accept arrays or objects */
69 if ( ! $fields || is_string( $fields ) ) {
70 return;
71 }
72
73 /* Convert objects into arrays */
74 if ( is_object( $fields ) ) {
75 $fields = get_object_vars( $fields );
76 }
77
78 /* Loop through the passed fields and set them */
79 foreach ( $fields as $field => $value ) {
80 $this->set_field( $field, $value );
81 }
82 }
83
84 /**
85 * Retrieve all snippet fields
86 * @return array
87 */
88 public function get_fields() {
89 return $this->fields;
90 }
91
92 /**
93 * Internal function for validating the name of a field
94 *
95 * @param string $field A field name
96 *
97 * @return string The validated field name
98 */
99 private function validate_field_name( $field ) {
100
101 /* If a field alias is set, remap it to the valid field name */
102 if ( isset( self::$field_aliases[ $field ] ) ) {
103 return self::$field_aliases[ $field ];
104 }
105
106 return $field;
107 }
108
109 /**
110 * Check if a field is set
111 *
112 * @param string $field The field name
113 *
114 * @return bool Whether the field is set
115 */
116 public function __isset( $field ) {
117 $field = $this->validate_field_name( $field );
118
119 return isset( $this->fields[ $field ] ) || method_exists( $this, 'get_' . $field );
120 }
121
122 /**
123 * Retrieve a field's value
124 *
125 * @param string $field The field name
126 *
127 * @return mixed The field value
128 */
129 public function __get( $field ) {
130 $field = $this->validate_field_name( $field );
131
132 if ( method_exists( $this, 'get_' . $field ) ) {
133 return call_user_func( array( $this, 'get_' . $field ) );
134 }
135
136 return $this->fields[ $field ];
137 }
138
139 /**
140 * Set the value of a field
141 *
142 * @param string $field The field name
143 * @param mixed $value The field value
144 */
145 public function __set( $field, $value ) {
146 $field = $this->validate_field_name( $field );
147
148 if ( ! $this->is_allowed_field( $field ) ) {
149
150 if ( WP_DEBUG ) {
151 trigger_error( 'Trying to set invalid property on Snippets class: ' . esc_html( $field ), E_WARNING );
152 }
153
154 return;
155 }
156
157 /* Check if the field value should be filtered */
158 if ( method_exists( $this, 'prepare_' . $field ) ) {
159 $value = call_user_func( array( $this, 'prepare_' . $field ), $value );
160 }
161
162 $this->fields[ $field ] = $value;
163 }
164
165 /**
166 * Retrieve the list of fields allowed to be written to
167 *
168 * @return array
169 */
170 public function get_allowed_fields() {
171 return array_keys( $this->fields ) + array_keys( self::$field_aliases );
172 }
173
174 /**
175 * Determine whether a field is allowed to be written to
176 *
177 * @param string $field The field name
178 *
179 * @return bool true if the is allowed, false if invalid
180 */
181 public function is_allowed_field( $field ) {
182 return array_key_exists( $field, $this->fields ) || array_key_exists( $field, self::$field_aliases );
183 }
184
185 /**
186 * Safely set the value for a field.
187 * If the field name is invalid, false will be returned instead of an error thrown
188 *
189 * @param string $field The field name
190 * @param mixed $value The field value
191 *
192 * @return bool true if the field was set successfully, false if the field name is invalid
193 */
194 public function set_field( $field, $value ) {
195 if ( ! $this->is_allowed_field( $field ) ) {
196 return false;
197 }
198
199 $this->__set( $field, $value );
200
201 return true;
202 }
203
204 /**
205 * Prepare the ID by ensuring it is an absolute integer
206 *
207 * @param int $id
208 *
209 * @return int
210 */
211 private function prepare_id( $id ) {
212 return absint( $id );
213 }
214
215 /**
216 * Prepare the code by removing php tags from beginning and end
217 *
218 * @param string $code
219 *
220 * @return string
221 */
222 private function prepare_code( $code ) {
223
224 /* Remove <?php and <? from beginning of snippet */
225 $code = preg_replace( '|^[\s]*<\?(php)?|', '', $code );
226
227 /* Remove ?> from end of snippet */
228 $code = preg_replace( '|\?>[\s]*$|', '', $code );
229
230 return $code;
231 }
232
233 /**
234 * Prepare the scope by ensuring that it is a valid choice
235 *
236 * @param int|string $scope The field as provided
237 *
238 * @return string The field in the correct format
239 */
240 private function prepare_scope( $scope ) {
241 $scopes = self::get_all_scopes();
242
243 if ( in_array( $scope, $scopes ) ) {
244 return $scope;
245 }
246
247 if ( is_numeric( $scope ) && isset( $scopes[ $scope ] ) ) {
248 return $scopes[ $scope ];
249 }
250
251 return $this->fields['scope'];
252 }
253
254 /**
255 * Prepare the snippet tags by ensuring they are in the correct format
256 *
257 * @param string|array $tags The tags as provided
258 *
259 * @return array The tags as an array
260 */
261 private function prepare_tags( $tags ) {
262 return code_snippets_build_tags_array( $tags );
263 }
264
265 /**
266 * Prepare the active field by ensuring it is the correct type
267 *
268 * @param bool|int $active The field as provided
269 *
270 * @return bool The field in the correct format
271 */
272 private function prepare_active( $active ) {
273
274 if ( is_bool( $active ) ) {
275 return $active;
276 }
277
278 return $active ? true : false;
279 }
280
281 /**
282 * Prepare the priority field by ensuring it is an integer
283 *
284 * @param int $priority
285 *
286 * @return int
287 */
288 private function prepare_priority( $priority ) {
289 return intval( $priority );
290 }
291
292 /**
293 * If $network is anything other than true, set it to false
294 *
295 * @param bool $network The provided field
296 *
297 * @return bool The filtered field
298 */
299 private function prepare_network( $network ) {
300
301 if ( null === $network && function_exists( 'is_network_admin' ) ) {
302 return is_network_admin();
303 }
304
305 return true === $network;
306 }
307
308 /**
309 * Retrieve the tags in list format
310 * @return string The tags separated by a comma and a space
311 */
312 private function get_tags_list() {
313 return implode( ', ', $this->fields['tags'] );
314 }
315
316 /**
317 * Retrieve a list of all available scopes
318 * @return array
319 */
320 public static function get_all_scopes() {
321 return array( 'global', 'admin', 'front-end', 'single-use' );
322 }
323
324 /**
325 * Retrieve a list of all scope icons
326 * @return array
327 */
328 public static function get_scope_icons() {
329 return array(
330 'global' => 'admin-site',
331 'admin' => 'admin-tools',
332 'front-end' => 'admin-appearance',
333 'single-use' => 'clock',
334 );
335 }
336
337 /**
338 * Retrieve the string representation of the scope
339 * @return string The name of the scope
340 */
341 private function get_scope_name() {
342 return $this->scope;
343 }
344
345 /**
346 * Retrieve the icon used for the current scope
347 * @return string a dashicon name
348 */
349 private function get_scope_icon() {
350 $icons = self::get_scope_icons();
351
352 return $icons[ $this->scope ];
353 }
354
355 /**
356 * Determine if the snippet is a shared network snippet
357 * @return bool
358 */
359 private function get_shared_network() {
360
361 if ( isset( $this->fields['shared_network'] ) ) {
362 return $this->fields['shared_network'];
363 }
364
365 if ( ! is_multisite() || ! $this->fields['network'] ) {
366 $this->fields['shared_network'] = false;
367 } else {
368 $shared_network_snippets = get_site_option( 'shared_network_snippets', array() );
369 $this->fields['shared_network'] = in_array( $this->fields['id'], $shared_network_snippets );
370 }
371
372 return $this->fields['shared_network'];
373 }
374 }
375