PluginProbe
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) / 1.6.28
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) v1.6.28
1.8.12.3 1.8.12.2 1.8.12.1 1.8.12 1.8.11.3 1.8.11.2 1.8.11.1 1.8.11 1.6.6 1.6.60 1.6.7 1.6.8 1.6.9 1.7.0 1.7.0.1 1.7.0.11 1.7.0.12 1.7.0.14 1.7.0.2 1.7.0.3 1.7.0.5 1.7.0.6 1.7.0.7 1.7.0.9 1.8.0 All 210 releases
charitable / includes / utilities / class-charitable-data-processor.php

class-charitable-data-processor.php in Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) 1.6.28, at includes/utilities/class-charitable-data-processor.php

374 lines 9.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Responsible for accepting a set of raw data, such as form submission data,
4 * and sanitizing and normalizing that data, depending on its data type and
5 * the type of data (text, checkbox, etc.).
6 *
7 * @package Charitable/Classes/Charitable_Data_Processor
8 * @author Eric Daams
9 * @copyright Copyright (c) 2019, Studio 164a
10 * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
11 * @since 1.5.9
12 * @version 1.5.9
13 */
14
15 // Exit if accessed directly.
16 if ( ! defined( 'ABSPATH' ) ) {
17 exit;
18 }
19
20
21 if ( ! class_exists( 'Charitable_Data_Processor' ) ) :
22
23 /**
24 * Data processor class.
25 *
26 * @since 1.5.9
27 */
28 class Charitable_Data_Processor {
29 /**
30 * The raw input data.
31 *
32 * @since 1.5.9
33 *
34 * @var array
35 */
36 protected $data;
37
38 /**
39 * The map of fields.
40 *
41 * @since 1.5.9
42 *
43 * @var array
44 */
45 protected $fields;
46
47 /**
48 * This is the output data. It has the same structure
49 * as the map of fields, but has the sanitized &
50 * normalized values from the input data.
51 *
52 * @since 1.5.9
53 *
54 * @var array
55 */
56 protected $output;
57
58 /**
59 * Instantiate the formatter with a dataset and array of fields.
60 *
61 * @since 1.5.9
62 *
63 * @param array $data The raw input data.
64 * @param array $fields The map of fields.
65 */
66 public function __construct( $data, $fields ) {
67 $this->data = $data;
68 $this->fields = $fields;
69 $this->output = array();
70 $this->invalid = false;
71
72 $this->process_data( $this->fields );
73 }
74
75 /**
76 * Returns whether the data is valid.
77 *
78 * @since 1.5.9
79 *
80 * @return boolean
81 */
82 public function is_valid() {
83 return false == $this->invalid;
84 }
85
86 /**
87 * Return a single field's output data.
88 *
89 * @since 1.5.9
90 *
91 * @param string $key The field key.
92 * @param string|false $data_type Optional. The data type.
93 * @return mixed|null
94 */
95 public function get( $key, $data_type = false ) {
96 if ( $data_type ) {
97 return $this->get_from_data_type( $key, $data_type );
98 }
99
100 return isset( $this->output[ $key ] ) ? $this->output[ $key ] : null;
101 }
102
103 /**
104 * Return a single field's output data, from a data type.
105 *
106 * @since 1.5.9
107 *
108 * @param string $key The field key.
109 * @param string $data_type The data type.
110 * @return mixed|null
111 */
112 public function get_from_data_type( $key, $data_type ) {
113 return isset( $this->output[ $data_type ][ $key ] ) ? $this->output[ $data_type ][ $key ] : null;
114 }
115
116 /**
117 * Returns the full output array.
118 *
119 * @since 1.5.9
120 *
121 * @return array
122 */
123 public function output() {
124 return $this->output;
125 }
126
127 /**
128 * Process an array of fields.
129 *
130 * @since 1.5.9
131 *
132 * @param array $fields Map of fields.
133 * @param false|string $data_type Optional. Data type.
134 * @return void
135 */
136 protected function process_data( $fields, $data_type = false ) {
137 $data = array();
138
139 foreach ( $fields as $key => $type ) {
140 if ( is_array( $type ) ) {
141 $this->process_data( $type, $key );
142 continue;
143 }
144
145 $data[ $key ] = $this->process_field( $key, $type, $data_type );
146 }
147
148 if ( ! empty( $data ) ) {
149 $this->set_output( $data, $data_type );
150 }
151 }
152
153 /**
154 * Add a set of data to the output array.
155 *
156 * @since 1.5.9
157 *
158 * @param array $data The processed data.
159 * @param false|string $data_type Optional. Data type.
160 * @return void
161 */
162 protected function set_output( $data, $data_type = false ) {
163 if ( $data_type ) {
164 $this->output[ $data_type ] = $data;
165 } else {
166 $this->output = $data;
167 }
168 }
169
170 /**
171 * Apply the correct function to a field, based on the type of function
172 * and the key, type and data type of the field.
173 *
174 * @since 1.5.9
175 *
176 * @param array $functions Stack of functions, in order of priority, with $args
177 * passed as the value of the function.
178 * @param mixed $default The default value to return if none of the functions exist.
179 * @return mixed|null
180 */
181 protected function apply_function_to_field( $functions, $default = '' ) {
182 foreach ( $functions as $function => $args ) {
183 if ( method_exists( $this, $function ) ) {
184 return call_user_func_array( array( $this, $function ), $args );
185 }
186 }
187
188 return $default;
189 }
190
191 /**
192 * Process a single field, returning the set value or null.
193 *
194 * @since 1.5.9
195 *
196 * @param string $key The field key.
197 * @param string $type The type of field.
198 * @param string|false $data_type Optional. The data type.
199 * @return mixed|null The set value of the field, or NULL if the
200 * field was not contained in the data.
201 */
202 protected function process_field( $key, $type, $data_type = false ) {
203 /* Retrieve the value. */
204 $value = $this->apply_function_to_field(
205 array(
206 'process_' . $key => array( $type, $data_type ),
207 'process_' . $data_type => array( $key, $type ),
208 'process_' . $type => array( $key, $data_type ),
209 'process_generic_field' => array( $key ),
210 )
211 );
212
213 /* Return the value after it is sanitized. */
214 return $this->apply_function_to_field(
215 array(
216 'sanitize_' . $key => array( $value, $type, $data_type ),
217 'sanitize_' . $data_type => array( $value, $key, $type ),
218 'sanitize_' . $type => array( $value, $key, $data_type ),
219 ),
220 $value
221 );
222 }
223
224 /**
225 * Process a generic field. i.e. One that hasn't been processed
226 * by any of the other processors.
227 *
228 * @since 1.5.9
229 *
230 * @param string $key The field key.
231 * @return mixed|null The set value of the field, or NULL if the
232 * field was not contained in the data.
233 */
234 public function process_generic_field( $key ) {
235 return array_key_exists( $key, $this->data ) ? $this->data[ $key ] : null;
236 }
237
238 /**
239 * Process a checkbox field.
240 *
241 * @since 1.5.9
242 *
243 * @param string $key The field key.
244 * @return int|string Returns 0 if the checkbox was not checked, or the
245 * value of the checkbox if checked.
246 */
247 protected function process_checkbox( $key ) {
248 return array_key_exists( $key, $this->data ) ? $this->data[ $key ] : 0;
249 }
250
251 /**
252 * Process a picture field.
253 *
254 * @since 1.5.9
255 *
256 * @param string $key The key of the picture field.
257 * @return int|false
258 */
259 protected function process_picture( $key ) {
260 $value = array_key_exists( $key, $this->data ) ? $this->data[ $key ] : '';
261
262 /**
263 * If Javascript is enabled, we do not expect to have a $_FILES array with the
264 * picture, as the upload was already handled client-side.
265 */
266 if ( ! $this->picture_file_exists( $key ) ) {
267 return $value;
268 }
269
270 $value = $this->upload_attachment( $key );
271
272 if ( is_wp_error( $value ) ) {
273 charitable_get_notices()->add_errors_from_wp_error( $value );
274 $value = '';
275 $this->invalid = true;
276 }
277
278 return $value;
279 }
280
281 /**
282 * Sanitize a number.
283 *
284 * @since 1.5.9
285 *
286 * @param string|int $value The number to be sanitized.
287 * @return int
288 */
289 protected function sanitize_number( $value ) {
290 return intval( $value );
291 }
292
293 /**
294 * Sanitize a value received from a datepicker.
295 *
296 * @since 1.5.9
297 *
298 * @param string $value The datepicker value.
299 * @return string|int If a date was chosen, returns the date in YYYY-MM-DD format.
300 * Otherwise, returns 0.
301 */
302 protected function sanitize_datepicker( $value ) {
303 if ( empty( $value ) ) {
304 return 0;
305 }
306
307 return charitable_sanitize_date( $value, 'Y-m-d' );
308 }
309
310 /**
311 * Returns true if a file was found for the picture in the $_FILES array.
312 *
313 * @since 1.5.9
314 *
315 * @param string $key The picture file key.
316 * @return boolean
317 */
318 protected function picture_file_exists( $key ) {
319 return isset( $_FILES ) && isset( $_FILES[ $key ] );
320 }
321
322 /**
323 * Uploads a file and attaches it to the given post.
324 *
325 * @since 1.5.9
326 *
327 * @param string $file_key Key of the file input.
328 * @param int $post_id Post ID.
329 * @return int|WP_Error ID of the attachment or a WP_Error object on failure.
330 */
331 public function upload_attachment( $file_key, $post_id = 0 ) {
332 require_once( ABSPATH . 'wp-admin/includes/image.php' );
333 require_once( ABSPATH . 'wp-admin/includes/file.php' );
334 require_once( ABSPATH . 'wp-admin/includes/media.php' );
335
336 $overrides = $this->get_file_overrides( $file_key, $overrides );
337
338 return media_handle_upload( $file_key, $post_id, array(), $overrides );
339 }
340
341 /**
342 * Return overrides array for use with upload_attachment() methods.
343 *
344 * @since 1.0.0
345 *
346 * @param string $file_key Reference to a single element of `$_FILES`. Call the
347 * function once for each uploaded file.
348 * @param array $overrides Optional. An associative array of names=>values to
349 * override default variables. Default false.
350 * @return array
351 */
352 protected function get_file_overrides( $file_key, $overrides = array() ) {
353 $allowed_mimes = array(
354 'jpg|jpeg|jpe' => 'image/jpeg',
355 'gif' => 'image/gif',
356 'png' => 'image/png',
357 'bmp' => 'image/bmp',
358 'tif|tiff' => 'image/tiff',
359 'ico' => 'image/x-icon',
360 );
361
362 $defaults = array(
363 'test_form' => false,
364 'mimes' => apply_filters( 'charitable_file_' . $file_key . '_allowed_mimes', $allowed_mimes ),
365 );
366
367 $overrides = wp_parse_args( $overrides, $defaults );
368
369 return $overrides;
370 }
371 }
372
373 endif;
374