PluginProbe
Code Snippets / 2.13.1
Code Snippets v2.13.1
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.1, at php/class-snippet.php

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