Issues (2873)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

classes/fields/file.php (18 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/**
4
 * @package Pods\Fields
5
 */
6
class PodsField_File extends PodsField {
7
8
	/**
9
	 * {@inheritdoc}
10
	 */
11
	public static $group = 'Relationships / Media';
12
13
	/**
14
	 * {@inheritdoc}
15
	 */
16
	public static $type = 'file';
17
18
	/**
19
	 * {@inheritdoc}
20
	 */
21
	public static $label = 'File / Image / Video';
22
23
	/**
24
	 * {@inheritdoc}
25
	 */
26
	protected static $api = false;
27
28
	/**
29
	 * {@inheritdoc}
30
	 */
31
	public function setup() {
32
33
		self::$label = __( 'File / Image / Video', 'pods' );
34
35
	}
36
37
	/**
38
	 * {@inheritdoc}
39
	 */
40
	public function admin_init() {
41
42
		// Hook into AJAX for Uploads.
43
		add_action( 'wp_ajax_pods_upload', array( $this, 'admin_ajax_upload' ) );
44
		add_action( 'wp_ajax_nopriv_pods_upload', array( $this, 'admin_ajax_upload' ) );
45
46
	}
47
48
	/**
49
	 * {@inheritdoc}
50
	 */
51
	public function options() {
52
53
		$sizes = get_intermediate_image_sizes();
54
55
		$image_sizes = array();
56
57
		foreach ( $sizes as $size ) {
58
			$image_sizes[ $size ] = ucwords( str_replace( '-', ' ', $size ) );
59
		}
60
61
		$options = array(
62
			static::$type . '_format_type'            => array(
63
				'label'      => __( 'Upload Limit', 'pods' ),
64
				'default'    => 'single',
65
				'type'       => 'pick',
66
				'data'       => array(
67
					'single' => __( 'Single File', 'pods' ),
68
					'multi'  => __( 'Multiple Files', 'pods' ),
69
				),
70
				'dependency' => true,
71
			),
72
			static::$type . '_uploader'               => array(
73
				'label'      => __( 'File Uploader', 'pods' ),
74
				'default'    => 'attachment',
75
				'type'       => 'pick',
76
				'data'       => apply_filters(
77
					'pods_form_ui_field_' . static::$type . '_uploader_options', array(
78
						'attachment' => __( 'Upload and/or Select (Media Library)', 'pods' ),
79
						'plupload'   => __( 'Upload only (Plupload)', 'pods' ),
80
					)
81
				),
82
				'dependency' => true,
83
			),
84
			static::$type . '_attachment_tab'         => array(
85
				'label'      => __( 'Attachments Default Tab', 'pods' ),
86
				'depends-on' => array( static::$type . '_uploader' => 'attachment' ),
87
				'default'    => 'upload',
88
				'type'       => 'pick',
89
				'data'       => array(
90
					// These keys must match WP media modal router names.
91
					'upload' => __( 'Upload File', 'pods' ),
92
					'browse' => __( 'Media Library', 'pods' ),
93
				),
94
			),
95
			static::$type . '_edit_title'             => array(
96
				'label'   => __( 'Editable Title', 'pods' ),
97
				'default' => 1,
98
				'type'    => 'boolean',
99
			),
100
			static::$type . '_show_edit_link'         => array(
101
				'label'   => __( 'Show Edit Link', 'pods' ),
102
				'default' => 0,
103
				'type'    => 'boolean',
104
			),
105
			static::$type . '_linked'                 => array(
106
				'label'   => __( 'Show Download Link', 'pods' ),
107
				'default' => 0,
108
				'type'    => 'boolean',
109
			),
110
			static::$type . '_limit'                  => array(
111
				'label'      => __( 'Max Number of Files', 'pods' ),
112
				'depends-on' => array( static::$type . '_format_type' => 'multi' ),
113
				'default'    => 0,
114
				'type'       => 'number',
115
			),
116
			static::$type . '_restrict_filesize'      => array(
117
				'label'      => __( 'Restrict File Size', 'pods' ),
118
				'help'       => __( 'Valid size suffixes are: GB (gigabytes), MB (megabytes), KB (kilobytes), or B (bytes).  Defaults to the <a href="https://developer.wordpress.org/reference/functions/wp_max_upload_size/">wp_max_upload_size</a> setting.', 'pods' ),
119
				'depends-on' => array( static::$type . '_uploader' => 'plupload' ),
120
				'default'    => '10MB',
121
				'type'       => 'text',
122
			),
123
			static::$type . '_type'                   => array(
124
				'label'      => __( 'Restrict File Types', 'pods' ),
125
				'default'    => apply_filters( 'pods_form_ui_field_' . static::$type . '_type_default', 'images' ),
126
				'type'       => 'pick',
127
				'data'       => apply_filters(
128
					'pods_form_ui_field_' . static::$type . '_type_options', array(
129
						'images' => __( 'Images (jpg, jpeg, png, gif)', 'pods' ),
130
						'video'  => __( 'Video (mpg, mov, flv, mp4, etc..)', 'pods' ),
131
						'audio'  => __( 'Audio (mp3, m4a, wav, wma, etc..)', 'pods' ),
132
						'text'   => __( 'Text (txt, csv, tsv, rtx, etc..)', 'pods' ),
133
						'any'    => __( 'Any Type (no restriction)', 'pods' ),
134
						'other'  => __( 'Other (customize allowed extensions)', 'pods' ),
135
					)
136
				),
137
				'dependency' => true,
138
			),
139
			static::$type . '_allowed_extensions'     => array(
140
				'label'       => __( 'Allowed File Extensions', 'pods' ),
141
				'description' => __( 'Separate file extensions with a comma (ex. jpg,png,mp4,mov)', 'pods' ),
142
				'depends-on'  => array( static::$type . '_type' => 'other' ),
143
				'default'     => apply_filters( 'pods_form_ui_field_' . static::$type . '_extensions_default', '' ),
144
				'type'        => 'text',
145
			),
146
			static::$type . '_field_template'         => array(
147
				'label'      => __( 'List Style', 'pods' ),
148
				'help'       => __( 'You can choose which style you would like the files to appear within the form.', 'pods' ),
149
				'depends-on' => array( static::$type . '_type' => 'images' ),
150
				'default'    => apply_filters( 'pods_form_ui_field_' . static::$type . '_template_default', 'rows' ),
151
				'type'       => 'pick',
152
				'data'       => apply_filters(
153
					'pods_form_ui_field_' . static::$type . '_type_templates', array(
154
						'rows'  => __( 'Rows', 'pods' ),
155
						'tiles' => __( 'Tiles', 'pods' ),
156
					)
157
				),
158
			),
159
			static::$type . '_add_button'             => array(
160
				'label'   => __( 'Add Button Text', 'pods' ),
161
				'default' => __( 'Add File', 'pods' ),
162
				'type'    => 'text',
163
			),
164
			static::$type . '_modal_title'            => array(
165
				'label'      => __( 'Modal Title', 'pods' ),
166
				'depends-on' => array( static::$type . '_uploader' => 'attachment' ),
167
				'default'    => __( 'Attach a file', 'pods' ),
168
				'type'       => 'text',
169
			),
170
			static::$type . '_modal_add_button'       => array(
171
				'label'      => __( 'Modal Add Button Text', 'pods' ),
172
				'depends-on' => array( static::$type . '_uploader' => 'attachment' ),
173
				'default'    => __( 'Add File', 'pods' ),
174
				'type'       => 'text',
175
			),
176
177
			/* WP GALLERY OUTPUT */
178
			static::$type . '_wp_gallery_output'      => array(
179
				'label'      => __( 'Output as a WP Gallery', 'pods' ),
180
				'help'       => sprintf( __( '<a href="%s" target="_blank">Click here for more info</a>', 'pods' ), 'https://codex.wordpress.org/The_WordPress_Gallery' ),
181
				'depends-on' => array( static::$type . '_type' => 'images' ),
182
				'dependency' => true,
183
				'type'       => 'boolean',
184
			),
185
			static::$type . '_wp_gallery_link'        => array(
186
				'label'      => __( 'Gallery image links', 'pods' ),
187
				'depends-on' => array( static::$type . '_wp_gallery_output' => 1 ),
188
				'type'       => 'pick',
189
				'data'       => array(
190
					'post' => __( 'Attachment Page', 'pods' ),
191
					'file' => __( 'Media File', 'pods' ),
192
					'none' => __( 'None', 'pods' ),
193
				),
194
			),
195
			static::$type . '_wp_gallery_columns'     => array(
196
				'label'      => __( 'Gallery image columns', 'pods' ),
197
				'depends-on' => array( static::$type . '_wp_gallery_output' => 1 ),
198
				'type'       => 'pick',
199
				'data'       => array(
200
					'1' => 1,
201
					'2' => 2,
202
					'3' => 3,
203
					'4' => 4,
204
					'5' => 5,
205
					'6' => 6,
206
					'7' => 7,
207
					'8' => 8,
208
					'9' => 9,
209
				),
210
			),
211
			static::$type . '_wp_gallery_random_sort' => array(
212
				'label'      => __( 'Gallery randomized order', 'pods' ),
213
				'depends-on' => array( static::$type . '_wp_gallery_output' => 1 ),
214
				'type'       => 'boolean',
215
			),
216
			static::$type . '_wp_gallery_size'        => array(
217
				'label'      => __( 'Gallery image size', 'pods' ),
218
				'depends-on' => array( static::$type . '_wp_gallery_output' => 1 ),
219
				'type'       => 'pick',
220
				'data'       => $this->data_image_sizes(),
221
			),
222
		);
223
224
		return $options;
225
226
	}
227
228
	/**
229
	 * {@inheritdoc}
230
	 */
231
	public function schema( $options = null ) {
232
233
		return false;
234
235
	}
236
237
	/**
238
	 * {@inheritdoc}
239
	 */
240
	public function display( $value = null, $name = null, $options = null, $pod = null, $id = null ) {
0 ignored issues
show
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
241
242
		if ( ! empty( $options[ static::$type . '_wp_gallery_output' ] ) ) {
243
			return $this->do_wp_gallery( $value, $options );
244
		}
245
246
		if ( is_array( $value ) && ! empty( $value ) ) {
247
			if ( isset( $value['ID'] ) ) {
248
				$value = wp_get_attachment_url( $value['ID'] );
249
			} else {
250
				$attachments = $value;
251
				$value       = array();
252
253
				foreach ( $attachments as $v ) {
254
					if ( ! is_array( $v ) ) {
255
						$value[] = $v;
256
					} elseif ( isset( $v['ID'] ) ) {
257
						$value[] = wp_get_attachment_url( $v['ID'] );
258
					}
259
				}
260
261
				$value = implode( ' ', $value );
262
			}
263
		}
264
265
		return $value;
266
267
	}
268
269
	/**
270
	 * {@inheritdoc}
271
	 */
272
	public function input( $name, $value = null, $options = null, $pod = null, $id = null ) {
273
274
		$options = (array) $options;
275
276
		$type = pods_v( 'type', $options, static::$type );
277
278
		$args = compact( array_keys( get_defined_vars() ) );
279
		$args = (object) $args;
280
281
		/**
282
		 * Access Checking
283
		 */
284
		$is_user_logged_in = is_user_logged_in();
285
286
		$file_upload_requirements = array(
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $file_upload_requirements exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
287
			'disabled'          => ( defined( 'PODS_DISABLE_FILE_UPLOAD' ) && true === PODS_DISABLE_FILE_UPLOAD ),
288
			'require_login'     => ( defined( 'PODS_UPLOAD_REQUIRE_LOGIN' ) && true === PODS_UPLOAD_REQUIRE_LOGIN && ! $is_user_logged_in ),
289
			'require_login_cap' => ( defined( 'PODS_UPLOAD_REQUIRE_LOGIN' ) && is_string( PODS_UPLOAD_REQUIRE_LOGIN ) && ( ! $is_user_logged_in || ! current_user_can( PODS_UPLOAD_REQUIRE_LOGIN ) ) ),
290
		);
291
292
		$file_browser_requirements = array(
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $file_browser_requirements exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
293
			'disabled'          => ( defined( 'PODS_DISABLE_FILE_BROWSER' ) && true === PODS_DISABLE_FILE_BROWSER ),
294
			'require_login'     => ( defined( 'PODS_FILES_REQUIRE_LOGIN' ) && true === PODS_FILES_REQUIRE_LOGIN && ! $is_user_logged_in ),
295
			'require_login_cap' => ( defined( 'PODS_FILES_REQUIRE_LOGIN' ) && is_string( PODS_FILES_REQUIRE_LOGIN ) && ( ! $is_user_logged_in || ! current_user_can( PODS_FILES_REQUIRE_LOGIN ) ) ),
296
		);
297
298
		$file_upload_requirements  = array_filter( $file_upload_requirements );
299
		$file_browser_requirements = array_filter( $file_browser_requirements );
300
301
		if ( ! empty( $file_upload_requirements ) && ! empty( $file_browser_requirements ) ) {
302
			?>
303
			<p><?php esc_html_e( 'You do not have access to upload / browse files. Contact your website admin to resolve.', 'pods' ); ?></p>
304
			<?php
305
306
			return;
307
		}
308
309
		wp_enqueue_script( 'pods-dfv' );
310
		wp_enqueue_media();
311
312
		// Ensure the media library is initialized
313
		$this->render_input_script( $args );
314
315
		// @todo: we're short-circuiting for prototyping above. The actions below will need to be woven in somehow.
316
		/**
317
		 * $form_field_type . '_uploader' != attachment, plupload, media
318
		 * Run this action 'pods_form_ui_field_' . static::$type . '_uploader_' . static::$type . '_uploader'
319
		 * Run this action 'pods_form_ui_field_' . static::$type . '_uploader', static::$type . '_uploader'
320
		 * Pass these args $name, $value, $options, $pod, $id
321
		 */
322
	}
323
324
	/**
325
	 * {@inheritdoc}
326
	 */
327
	public function build_dfv_field_options( $options, $args ) {
328
329
		if ( ! is_admin() ) {
330
			include_once ABSPATH . '/wp-admin/includes/template.php';
331
332
			if ( is_multisite() ) {
333
				include_once ABSPATH . '/wp-admin/includes/ms.php';
334
			}
335
		}
336
337
		// Handle default template setting.
338
		$file_field_template = pods_v( $args->type . '_field_template', $options, 'rows', true );
339
340
		// Get which file types the field is limited to.
341
		$limit_file_type = pods_v( $args->type . '_type', $options, 'images' );
342
343
		// Non-image file types are forced to rows template right now.
344
		if ( 'images' !== $limit_file_type ) {
345
			$file_field_template = 'rows';
346
		}
347
348
		$options[ $args->type . '_field_template' ] = $file_field_template;
349
350
		// Enforce limit.
351
		$file_limit = 1;
352
353
		if ( 'multi' === pods_v( $args->type . '_format_type', $options, 'single' ) ) {
354
			$file_limit = (int) pods_v( $args->type . '_limit', $options, 0 );
355
356
			if ( $file_limit < 0 ) {
357
				$file_limit = 0;
358
			}
359
		}
360
361
		$options[ $args->type . '_limit' ] = $file_limit;
362
363
		// Build types and extensions to limit by.
364
		if ( 'images' === $limit_file_type ) {
365
			$limit_types      = 'image';
366
			$limit_extensions = 'jpg,jpeg,png,gif';
367
		} elseif ( 'video' === $limit_file_type ) {
368
			$limit_types      = 'video';
369
			$limit_extensions = 'mpg,mov,flv,mp4';
370
		} elseif ( 'audio' === $limit_file_type ) {
371
			$limit_types      = 'audio';
372
			$limit_extensions = 'mp3,m4a,wav,wma';
373
		} elseif ( 'text' === $limit_file_type ) {
374
			$limit_types      = 'text';
375
			$limit_extensions = 'txt,rtx,csv,tsv';
376
		} elseif ( 'any' === $limit_file_type ) {
377
			$limit_types      = '';
378
			$limit_extensions = '*';
379
		} else {
380
			$limit_types = pods_v( $args->type . '_allowed_extensions', $options, '', true );
381
382
			$limit_extensions = $limit_types;
383
		}
384
385
		// Find and replace certain characters to properly split by commas.
386
		$find = array(
387
			' ',
388
			'.',
389
			"\n",
390
			"\t",
391
			';',
392
		);
393
394
		$replace = array(
395
			'',
396
			',',
397
			',',
398
			',',
399
		);
400
401
		$limit_types      = trim( str_replace( $find, $replace, $limit_types ), ',' );
402
		$limit_extensions = trim( str_replace( $find, $replace, $limit_extensions ), ',' );
403
		$mime_types       = wp_get_mime_types();
404
405
		if ( ! in_array( $limit_file_type, array( 'images', 'video', 'audio', 'text', 'any' ), true ) ) {
406
			$new_limit_types = array();
407
408
			$limit_types = explode( ',', $limit_types );
409
410
			foreach ( $limit_types as $k => $limit_type ) {
411
				if ( isset( $mime_types[ $limit_type ] ) ) {
412
					$mime = explode( '/', $mime_types[ $limit_type ] );
413
					$mime = $mime[0];
414
415
					if ( ! in_array( $mime, $new_limit_types, true ) ) {
416
						$new_limit_types[] = $mime;
417
					}
418
				} else {
419
					$found = false;
420
421
					foreach ( $mime_types as $type => $mime ) {
422
						if ( false !== strpos( $type, $limit_type ) ) {
423
							$mime = explode( '/', $mime );
424
							$mime = $mime[0];
425
426
							if ( ! in_array( $mime, $new_limit_types, true ) ) {
427
								$new_limit_types[] = $mime;
428
							}
429
430
							$found = true;
431
						}
432
					}
433
434
					if ( ! $found ) {
435
						$new_limit_types[] = $limit_type;
436
					}
437
				}//end if
438
			}//end foreach
439
440
			if ( ! empty( $new_limit_types ) ) {
441
				$limit_types = implode( ',', $new_limit_types );
442
			}
443
		}//end if
444
445
		$options['limit_types']      = $limit_types;
446
		$options['limit_extensions'] = $limit_extensions;
447
448
		$is_user_logged_in = is_user_logged_in();
449
450
		// @todo test frontend media modal
451
		if ( empty( $options[ static::$type . '_uploader' ] ) || ! is_admin() || ! $is_user_logged_in || ( ! current_user_can( 'upload_files' ) && ! current_user_can( 'edit_files' ) ) ) {
452
			$options[ static::$type . '_uploader' ] = 'plupload';
453
		}
454
455
		// @todo: plupload specific options need accommodation
456
		if ( 'plupload' === $options[ static::$type . '_uploader' ] ) {
457
			wp_enqueue_script( 'plupload-all' );
458
459
			if ( $is_user_logged_in ) {
460
				$uid = 'user_' . get_current_user_id();
461
			} else {
462
				// @codingStandardsIgnoreLine
463
				$uid = @session_id();
464
			}
465
466
			$pod_id = '0';
467
468
			if ( is_object( $args->pod ) ) {
469
				$pod_id = $args->pod->pod_id;
470
			}
471
472
			$uri_hash    = wp_create_nonce( 'pods_uri_' . $_SERVER['REQUEST_URI'] );
473
			$field_nonce = wp_create_nonce( 'pods_upload_' . $pod_id . '_' . $uid . '_' . $uri_hash . '_' . $options['id'] );
474
475
			$options['plupload_init'] = array(
476
				'runtimes'            => 'html5,silverlight,flash,html4',
477
				'url'                 => admin_url( 'admin-ajax.php?pods_ajax=1', 'relative' ),
478
				'file_data_name'      => 'Filedata',
479
				'multiple_queues'     => false,
480
				'max_file_size'       => wp_max_upload_size() . 'b',
481
				'flash_swf_url'       => includes_url( 'js/plupload/plupload.flash.swf' ),
482
				'silverlight_xap_url' => includes_url( 'js/plupload/plupload.silverlight.xap' ),
483
				'filters'             => array(
484
					array(
485
						'title'      => __( 'Allowed Files', 'pods' ),
486
						'extensions' => '*',
487
					),
488
				),
489
				'multipart'           => true,
490
				'urlstream_upload'    => true,
491
				'multipart_params'    => array(
492
					'_wpnonce' => $field_nonce,
493
					'action'   => 'pods_upload',
494
					'method'   => 'upload',
495
					'pod'      => $pod_id,
496
					'field'    => $options['id'],
497
					'uri'      => $uri_hash,
498
				),
499
			);
500
		}//end if
501
502
		return $options;
503
504
	}
505
506
	/**
507
	 * {@inheritdoc}
508
	 */
509
	public function build_dfv_field_attributes( $attributes, $args ) {
510
511
		// Add template class.
512
		$attributes['class'] .= ' pods-field-template-' . $args->options[ $args->type . '_field_template' ];
513
514
		return $attributes;
515
516
	}
517
518
	/**
519
	 * {@inheritdoc}
520
	 */
521
	public function build_dfv_field_item_data( $args ) {
522
523
		$data = array();
524
525
		$title_editable = (int) pods_v( $args->type . '_edit_title', $args->options, 0 );
526
527
		$value = $args->value;
528
529
		if ( empty( $value ) ) {
530
			$value = array();
531
		} else {
532
			$value = (array) $value;
533
		}
534
535
		foreach ( $value as $id ) {
536
			$attachment = get_post( $id );
537
538
			if ( empty( $attachment ) ) {
539
				continue;
540
			}
541
542
			$icon = '';
543
544
			// @todo Add access check
545
			$edit_link = get_edit_post_link( $attachment->ID, 'raw' );
546
547
			$link     = get_permalink( $attachment->ID );
548
			$download = wp_get_attachment_url( $attachment->ID );
549
550
			$thumb = wp_get_attachment_image_src( $id, 'thumbnail', true );
551
552
			if ( ! empty( $thumb[0] ) ) {
553
				$icon = $thumb[0];
554
			}
555
556
			$title = $attachment->post_title;
557
558
			if ( 0 === $title_editable ) {
559
				$title = basename( $attachment->guid );
560
			}
561
562
			$data[] = array(
563
				'id'        => $id,
564
				'icon'      => $icon,
565
				'name'      => $title,
566
				'edit_link' => $edit_link,
567
				'link'      => $link,
568
				'download'  => $download,
569
			);
570
		}//end foreach
571
572
		return $data;
573
574
	}
575
576
	/**
577
	 * {@inheritdoc}
578
	 */
579
	public function validate( $value, $name = null, $options = null, $fields = null, $pod = null, $id = null, $params = null ) {
580
581
		// @todo Check file size
582
		// @todo Check file extensions
583
		return true;
584
585
	}
586
587
	/**
588
	 * {@inheritdoc}
589
	 */
590
	public function save( $value, $id = null, $name = null, $options = null, $fields = null, $pod = null, $params = null ) {
591
592
		if ( empty( self::$api ) ) {
593
			self::$api = pods_api();
594
		}
595
596
		// Handle File title saving.
597
		foreach ( $value as $id ) {
598
			$title = false;
599
600
			if ( is_array( $id ) ) {
601
				if ( isset( $id['title'] ) && 0 < strlen( trim( $id['title'] ) ) ) {
602
					$title = trim( $id['title'] );
603
				}
604
605
				if ( isset( $id['id'] ) ) {
606
					$id = (int) $id['id'];
607
				} else {
608
					$id = 0;
609
				}
610
			}
611
612
			if ( empty( $id ) ) {
613
				continue;
614
			}
615
616
			$attachment_data = array();
617
618
			// Update the title if set.
619
			if ( false !== $title && 1 === (int) pods_v( static::$type . '_edit_title', $options, 0 ) ) {
620
				$attachment_data['post_title'] = $title;
621
			}
622
623
			// Update attachment parent if it's not set yet and we're updating a post.
624
			if ( ! empty( $params->id ) && ! empty( $pod['type'] ) && 'post_type' === $pod['type'] ) {
625
				$attachment = get_post( $id );
626
627
				if ( isset( $attachment->post_parent ) && 0 === (int) $attachment->post_parent ) {
628
					$attachment_data['post_parent'] = (int) $params->id;
629
				}
630
			}
631
632
			// Update the attachment if it the data array is not still empty.
633
			if ( ! empty( $attachment_data ) ) {
634
				$attachment_data['ID'] = $id;
635
636
				self::$api->save_wp_object( 'media', $attachment_data );
637
			}
638
		}//end foreach
639
640
	}
641
642
	/**
643
	 * {@inheritdoc}
644
	 */
645
	public function ui( $id, $value, $name = null, $options = null, $fields = null, $pod = null ) {
0 ignored issues
show
This method's name is shorter than the configured minimum length of 3 characters.

Even though PHP does not care about the name of your methods, it is generally a good practice to choose method names which can be easily understood by other human readers.

Loading history...
646
647
		if ( empty( $value ) ) {
648
			return;
649
		}
650
651
		if ( ! empty( $value ) && isset( $value['ID'] ) ) {
652
			$value = array( $value );
653
		}
654
655
		$image_size = apply_filters( 'pods_form_ui_field_' . static::$type . '_ui_image_size', 'thumbnail', $id, $value, $name, $options, $pod );
656
657
		return $this->images( $id, $value, $name, $options, $pod, $image_size );
658
659
	}
660
661
	/**
662
	 * Return image(s) markup.
663
	 *
664
	 * @param int    $id         Item ID.
665
	 * @param mixed  $value      Field value.
666
	 * @param string $name       Field name.
0 ignored issues
show
Should the type for parameter $name not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
667
	 * @param array  $options    Field options.
0 ignored issues
show
Should the type for parameter $options not be array|null? Also, consider making the array more specific, something like array<String>, or String[].

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive. In addition it looks for parameters that have the generic type array and suggests a stricter type like array<String>.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
668
	 * @param array  $pod        Pod options.
0 ignored issues
show
Should the type for parameter $pod not be array|null? Also, consider making the array more specific, something like array<String>, or String[].

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive. In addition it looks for parameters that have the generic type array and suggests a stricter type like array<String>.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
669
	 * @param string $image_size Image size.
0 ignored issues
show
Should the type for parameter $image_size not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
670
	 *
671
	 * @return string
672
	 * @since 2.3
673
	 */
674
	public function images( $id, $value, $name = null, $options = null, $pod = null, $image_size = null ) {
675
676
		$images = '';
677
678
		if ( empty( $value ) || ! is_array( $value ) ) {
679
			return $images;
680
		}
681
682
		foreach ( $value as $v ) {
683
			$images .= pods_image( $v, $image_size );
684
		}
685
686
		return $images;
687
688
	}
689
690
	/**
691
	 * Data callback for Image Sizes.
692
	 *
693
	 * @param string       $name    The name of the field.
0 ignored issues
show
Should the type for parameter $name not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
694
	 * @param string|array $value   The value of the field.
0 ignored issues
show
Should the type for parameter $value not be string|array|null? Also, consider making the array more specific, something like array<String>, or String[].

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive. In addition it looks for parameters that have the generic type array and suggests a stricter type like array<String>.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
695
	 * @param array        $options Field options.
0 ignored issues
show
Should the type for parameter $options not be array|null? Also, consider making the array more specific, something like array<String>, or String[].

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive. In addition it looks for parameters that have the generic type array and suggests a stricter type like array<String>.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
696
	 * @param array        $pod     Pod data.
0 ignored issues
show
Should the type for parameter $pod not be array|null? Also, consider making the array more specific, something like array<String>, or String[].

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive. In addition it looks for parameters that have the generic type array and suggests a stricter type like array<String>.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
697
	 * @param int          $id      Item ID.
0 ignored issues
show
Should the type for parameter $id not be integer|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
698
	 *
699
	 * @return array
700
	 *
701
	 * @since 2.3
702
	 */
703
	public function data_image_sizes( $name = null, $value = null, $options = null, $pod = null, $id = null ) {
704
705
		$data = array();
706
707
		$image_sizes = get_intermediate_image_sizes();
708
709
		foreach ( $image_sizes as $image_size ) {
710
			$data[ $image_size ] = ucwords( str_replace( '-', ' ', $image_size ) );
711
		}
712
713
		return apply_filters( 'pods_form_ui_field_pick_' . __FUNCTION__, $data, $name, $value, $options, $pod, $id );
714
715
	}
716
717
	/**
718
	 * Create a WP Gallery from the passed values (need to be attachments)
719
	 *
720
	 * @since  2.7
721
	 *
722
	 * @param  string|array $value   The value(s).
723
	 * @param  array        $options The field options.
724
	 *
725
	 * @return string
726
	 */
727
	public function do_wp_gallery( $value, $options ) {
728
729
		$shortcode_args = array();
730
731
		if ( ! empty( $options[ static::$type . '_wp_gallery_columns' ] ) ) {
732
			$shortcode_args['columns'] = absint( $options[ static::$type . '_wp_gallery_columns' ] );
733
		}
734
735
		if ( ! empty( $options[ static::$type . '_wp_gallery_random_sort' ] ) ) {
736
			$shortcode_args['orderby'] = 'rand';
737
		}
738
739
		if ( ! empty( $options[ static::$type . '_wp_gallery_link' ] ) ) {
740
			$shortcode_args['link'] = $options[ static::$type . '_wp_gallery_link' ];
741
		}
742
743
		if ( ! empty( $options[ static::$type . '_wp_gallery_size' ] ) ) {
744
			$shortcode_args['size'] = $options[ static::$type . '_wp_gallery_size' ];
745
		}
746
747
		if ( isset( $value['ID'] ) ) {
748
			$shortcode_args['ids'] = $value['ID'];
749
		} else {
750
			$images = array();
751
752
			foreach ( $value as $v ) {
0 ignored issues
show
The expression $value of type string|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
753
				if ( ! is_array( $v ) ) {
754
					$images[] = (int) $v;
755
				} elseif ( isset( $v['ID'] ) ) {
756
					$images[] = (int) $v['ID'];
757
				}
758
			}
759
760
			$shortcode_args['ids'] = implode( ',', $images );
761
		}
762
763
		if ( is_callable( 'gallery_shortcode' ) ) {
764
			return gallery_shortcode( $shortcode_args );
765
		} else {
766
			$shortcode = '[gallery';
767
768
			foreach ( $shortcode_args as $key => $shortcode_arg ) {
769
				$shortcode .= ' ' . esc_attr( $key ) . '="' . esc_attr( $shortcode_arg ) . '"';
770
			}
771
772
			$shortcode .= ']';
773
774
			return do_shortcode( $shortcode );
775
		}
776
777
	}
778
779
	/**
780
	 * Handle file row output for uploaders
781
	 *
782
	 * @param array           $attributes Field options.
783
	 * @param int             $limit      List limit.
784
	 * @param bool            $editable   Whether the items should be editable.
785
	 * @param null|int|string $id         Item ID.
786
	 * @param null|string     $icon       Icon URL.
787
	 * @param null|string     $name       File name.
788
	 * @param bool            $linked     Whether the items should be linked.
789
	 * @param null|string     $link       Link URL.
790
	 *
791
	 * @return string
792
	 * @since      2.0
793
	 *
794
	 * @deprecated 2.7
795
	 */
796
	public function markup( $attributes, $limit = 1, $editable = true, $id = null, $icon = null, $name = null, $linked = false, $link = null ) {
797
798
		_doing_it_wrong( 'PodsField_File::markup', esc_html__( 'This method has been deprecated and will be removed from Pods 3.0', 'pods' ), '2.7' );
799
800
		// Preserve current file type.
801
		$field_type = PodsForm::$field_type;
802
803
		ob_start();
804
805
		if ( empty( $id ) ) {
806
			$id = '{{id}}';
807
		}
808
809
		if ( empty( $icon ) ) {
810
			$icon = '{{icon}}';
811
		}
812
813
		if ( empty( $name ) ) {
814
			$name = '{{name}}';
815
		}
816
817
		if ( empty( $link ) ) {
818
			$link = '{{link}}';
819
		}
820
821
		$editable = (boolean) $editable;
822
		$linked   = (boolean) $linked;
823
		?>
824
		<li class="pods-file hidden" id="pods-file-<?php echo esc_attr( $id ); ?>">
825
			<?php
826
				// @codingStandardsIgnoreLine
827
				echo PodsForm::field( $attributes['name'] . '[' . $id . '][id]', $id, 'hidden' );
828
			?>
829
830
			<ul class="pods-file-meta media-item">
831
				<?php if ( 1 !== (int) $limit ) { ?>
832
					<li class="pods-file-col pods-file-handle">Handle</li>
833
				<?php } ?>
834
835
				<li class="pods-file-col pods-file-icon">
836
					<img class="pinkynail" src="<?php echo esc_url( $icon ); ?>" alt="Icon" />
837
				</li>
838
839
				<li class="pods-file-col pods-file-name">
840
					<?php
841
					if ( $editable ) {
842
						// @codingStandardsIgnoreLine
843
						echo PodsForm::field( $attributes['name'] . '[' . $id . '][title]', $name, 'text' );
844
					} else {
845
						echo esc_html( $name );
846
					}
847
					?>
848
				</li>
849
850
				<li class="pods-file-col pods-file-actions">
851
					<ul>
852
						<li class="pods-file-col pods-file-delete"><a href="#delete">Delete</a></li>
853
						<?php
854
						if ( $linked ) {
855
							?>
856
							<li class="pods-file-col pods-file-download">
857
								<a href="<?php echo esc_url( $link ); ?>" target="_blank">Download</a></li>
858
							<?php
859
						}
860
						?>
861
					</ul>
862
				</li>
863
			</ul>
864
		</li>
865
		<?php
866
		PodsForm::$field_type = $field_type;
867
868
		return ob_get_clean();
869
870
	}
871
872
	/**
873
	 * Handle AJAX plupload calls.
874
	 *
875
	 * @since 2.3
876
	 */
877
	public function admin_ajax_upload() {
878
879
		pods_session_start();
880
881
		// Sanitize input @codingStandardsIgnoreLine
882
		$params = pods_unslash( (array) $_POST );
883
884
		foreach ( $params as $key => $value ) {
885
			if ( 'action' === $key ) {
886
				continue;
887
			}
888
889
			unset( $params[ $key ] );
890
891
			$params[ str_replace( '_podsfix_', '', $key ) ] = $value;
892
		}
893
894
		$params = (object) $params;
895
896
		$methods = array(
897
			'upload',
898
		);
899
900
		if ( ! isset( $params->method ) || ! in_array( $params->method, $methods, true ) || ! isset( $params->pod ) || ! isset( $params->field ) || ! isset( $params->uri ) || empty( $params->uri ) ) {
901
			pods_error( 'Invalid AJAX request', PodsInit::$admin );
902
		} elseif ( ! empty( $params->pod ) && empty( $params->field ) ) {
903
			pods_error( 'Invalid AJAX request', PodsInit::$admin );
904
		} elseif ( empty( $params->pod ) && ! current_user_can( 'upload_files' ) ) {
905
			pods_error( 'Invalid AJAX request', PodsInit::$admin );
906
		}
907
908
		// Flash often fails to send cookies with the POST or upload, so we need to pass it in GET or POST instead
909
		// @codingStandardsIgnoreLine
910
		if ( is_ssl() && empty( $_COOKIE[ SECURE_AUTH_COOKIE ] ) && ! empty( $_REQUEST['auth_cookie'] ) ) {
911
			// @codingStandardsIgnoreLine
912
			$_COOKIE[ SECURE_AUTH_COOKIE ] = $_REQUEST['auth_cookie'];
913
			// @codingStandardsIgnoreLine
914
		} elseif ( empty( $_COOKIE[ AUTH_COOKIE ] ) && ! empty( $_REQUEST['auth_cookie'] ) ) {
915
			// @codingStandardsIgnoreLine
916
			$_COOKIE[ AUTH_COOKIE ] = $_REQUEST['auth_cookie'];
917
		}
918
919
		// @codingStandardsIgnoreLine
920
		if ( empty( $_COOKIE[ LOGGED_IN_COOKIE ] ) && ! empty( $_REQUEST['logged_in_cookie'] ) ) {
921
			// @codingStandardsIgnoreLine
922
			$_COOKIE[ LOGGED_IN_COOKIE ] = $_REQUEST['logged_in_cookie'];
923
		}
924
925
		global $current_user;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
926
		unset( $current_user );
927
928
		/**
929
		 * Access Checking
930
		 */
931
		$upload_disabled   = false;
932
		$is_user_logged_in = is_user_logged_in();
933
934
		if ( defined( 'PODS_DISABLE_FILE_UPLOAD' ) && true === PODS_DISABLE_FILE_UPLOAD ) {
935
			$upload_disabled = true;
936
		} elseif ( ! $is_user_logged_in && defined( 'PODS_UPLOAD_REQUIRE_LOGIN' ) ) {
937
			if ( true === PODS_UPLOAD_REQUIRE_LOGIN ) {
938
				$upload_disabled = true;
939
			} elseif ( is_string( PODS_UPLOAD_REQUIRE_LOGIN ) && ! current_user_can( PODS_UPLOAD_REQUIRE_LOGIN ) ) {
940
				$upload_disabled = true;
941
			}
942
		}
943
944
		$uid = @session_id();
0 ignored issues
show
Silencing errors is discouraged
Loading history...
The use of PHP session function session_id() is prohibited.
Loading history...
945
946
		if ( $is_user_logged_in ) {
947
			$uid = 'user_' . get_current_user_id();
948
		}
949
950
		$nonce_check = 'pods_upload_' . (int) $params->pod . '_' . $uid . '_' . $params->uri . '_' . (int) $params->field;
951
952
		if ( true === $upload_disabled || ! isset( $params->_wpnonce ) || false === wp_verify_nonce( $params->_wpnonce, $nonce_check ) ) {
953
			pods_error( __( 'Unauthorized request', 'pods' ), PodsInit::$admin );
954
		}
955
956
		$pod   = array();
957
		$field = array(
958
			'type'    => 'file',
959
			'options' => array(),
960
		);
961
962
		if ( empty( self::$api ) ) {
963
			self::$api = pods_api();
964
		}
965
966
		self::$api->display_errors = false;
967
968
		if ( ! empty( $params->pod ) ) {
969
			$pod   = self::$api->load_pod( array( 'id' => (int) $params->pod ) );
970
			$field = self::$api->load_field( array( 'id' => (int) $params->field ) );
971
972
			if ( empty( $pod ) || empty( $field ) || (int) $pod['id'] !== (int) $field['pod_id'] || ! isset( $pod['fields'][ $field['name'] ] ) ) {
973
				pods_error( __( 'Invalid field request', 'pods' ), PodsInit::$admin );
974
			}
975
976
			if ( ! in_array( $field['type'], PodsForm::file_field_types(), true ) ) {
977
				pods_error( __( 'Invalid field', 'pods' ), PodsInit::$admin );
978
			}
979
		}
980
981
		$method = $params->method;
982
983
		// Cleaning up $params
984
		unset( $params->action, $params->method, $params->_wpnonce );
985
986
		$params->post_id = (int) pods_v( 'post_id', $params, 0 );
987
988
		/**
989
		 * Upload a new file (advanced - returns URL and ID)
990
		 */
991
		if ( 'upload' === $method ) {
992
			$file = $_FILES['Filedata'];
993
994
			$limit_size = pods_v( $field['type'] . '_restrict_filesize', $field['options'] );
995
996
			if ( ! empty( $limit_size ) ) {
997
				if ( false !== stripos( $limit_size, 'GB' ) ) {
998
					$limit_size = (float) trim( str_ireplace( 'GB', '', $limit_size ) );
999
					$limit_size = $limit_size * 1025 * 1025 * 1025;
1000
					// convert to MB to KB to B
1001
				} elseif ( false !== stripos( $limit_size, 'MB' ) ) {
1002
					$limit_size = (float) trim( str_ireplace( 'MB', '', $limit_size ) );
1003
					$limit_size = $limit_size * 1025 * 1025;
1004
					// convert to KB to B
1005
				} elseif ( false !== stripos( $limit_size, 'KB' ) ) {
1006
					$limit_size  = (float) trim( str_ireplace( 'KB', '', $limit_size ) );
1007
					$limit_size *= 1025;
1008
					// convert to B
1009
				} elseif ( false !== stripos( $limit_size, 'B' ) ) {
1010
					$limit_size = (float) trim( str_ireplace( 'B', '', $limit_size ) );
1011
				} else {
1012
					$limit_size = wp_max_upload_size();
1013
				}
1014
1015
				if ( 0 < $limit_size && $limit_size < $file['size'] ) {
1016
					$error = __( 'File size too large, max size is %s', 'pods' );
1017
					$error = sprintf( $error, pods_v( $field['type'] . '_restrict_filesize', $field['options'] ) );
1018
1019
					pods_error( '<div style="color:#FF0000">Error: ' . $error . '</div>' );
1020
				}
1021
			}//end if
1022
1023
			$limit_file_type = pods_v( $field['type'] . '_type', $field['options'], 'images' );
1024
1025
			if ( 'images' === $limit_file_type ) {
1026
				$limit_types = 'jpg,jpeg,png,gif';
1027
			} elseif ( 'video' === $limit_file_type ) {
1028
				$limit_types = 'mpg,mov,flv,mp4';
1029
			} elseif ( 'audio' === $limit_file_type ) {
1030
				$limit_types = 'mp3,m4a,wav,wma';
1031
			} elseif ( 'text' === $limit_file_type ) {
1032
				$limit_types = 'txt,rtx,csv,tsv';
1033
			} elseif ( 'any' === $limit_file_type ) {
1034
				$limit_types = '';
1035
			} else {
1036
				$limit_types = pods_v( $field['type'] . '_allowed_extensions', $field['options'], '', true );
1037
			}
1038
1039
			$limit_types = trim(
1040
				str_replace(
1041
					array( ' ', '.', "\n", "\t", ';' ), array(
1042
						'',
1043
						',',
1044
						',',
1045
						',',
1046
					), $limit_types
1047
				), ','
1048
			);
1049
1050
			$mime_types = wp_get_mime_types();
1051
1052
			if ( in_array( $limit_file_type, array( 'images', 'audio', 'video' ), true ) ) {
1053
				$new_limit_types = array();
1054
1055
				foreach ( $mime_types as $type => $mime ) {
1056
					if ( 0 === strpos( $mime, $limit_file_type ) ) {
1057
						$type = explode( '|', $type );
1058
1059
						$new_limit_types = array_merge( $new_limit_types, $type );
1060
					}
1061
				}
1062
1063
				if ( ! empty( $new_limit_types ) ) {
1064
					$limit_types = implode( ',', $new_limit_types );
1065
				}
1066
			} elseif ( 'any' !== $limit_file_type ) {
1067
				$new_limit_types = array();
1068
1069
				$limit_types = explode( ',', $limit_types );
1070
1071
				foreach ( $limit_types as $k => $limit_type ) {
1072
					$found = false;
1073
1074
					foreach ( $mime_types as $type => $mime ) {
1075
						if ( 0 === strpos( $mime, $limit_type ) ) {
1076
							$type = explode( '|', $type );
1077
1078
							foreach ( $type as $t ) {
1079
								if ( ! in_array( $t, $new_limit_types, true ) ) {
1080
									$new_limit_types[] = $t;
1081
								}
1082
							}
1083
1084
							$found = true;
1085
						}
1086
					}
1087
1088
					if ( ! $found ) {
1089
						$new_limit_types[] = $limit_type;
1090
					}
1091
				}//end foreach
1092
1093
				if ( ! empty( $new_limit_types ) ) {
1094
					$limit_types = implode( ',', $new_limit_types );
1095
				}
1096
			}//end if
1097
1098
			$limit_types = explode( ',', $limit_types );
1099
1100
			$limit_types = array_filter( array_unique( $limit_types ) );
1101
1102
			if ( ! empty( $limit_types ) ) {
1103
				$ok = false;
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $ok. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
1104
1105
				foreach ( $limit_types as $limit_type ) {
1106
					$limit_type = '.' . trim( $limit_type, ' .' );
1107
1108
					$pos = ( strlen( $file['name'] ) - strlen( $limit_type ) );
1109
1110
					if ( stripos( $file['name'], $limit_type ) === $pos ) {
1111
						$ok = true;
1112
1113
						break;
1114
					}
1115
				}
1116
1117
				if ( false === $ok ) {
1118
					$error = __( 'File type not allowed, please use one of the following: %s', 'pods' );
1119
					$error = sprintf( $error, '.' . implode( ', .', $limit_types ) );
1120
1121
					pods_error( '<div style="color:#FF0000">Error: ' . $error . '</div>' );
1122
				}
1123
			}//end if
1124
1125
			$custom_handler = apply_filters( 'pods_upload_handle', null, 'Filedata', $params->post_id, $params, $field );
1126
1127
			if ( null === $custom_handler ) {
1128
				$attachment_id = media_handle_upload( 'Filedata', $params->post_id );
1129
1130
				if ( is_object( $attachment_id ) ) {
1131
					$errors = array();
1132
1133
					foreach ( $attachment_id->errors['upload_error'] as $error_code => $error_message ) {
1134
						$errors[] = '[' . $error_code . '] ' . $error_message;
1135
					}
1136
1137
					pods_error( '<div style="color:#FF0000">Error: ' . implode( '</div><div>', $errors ) . '</div>' );
1138
				} else {
1139
					$attachment = get_post( $attachment_id, ARRAY_A );
1140
1141
					$attachment['filename'] = basename( $attachment['guid'] );
1142
1143
					$thumb = wp_get_attachment_image_src( $attachment['ID'], 'thumbnail', true );
1144
1145
					$attachment['thumbnail'] = '';
1146
1147
					if ( ! empty( $thumb[0] ) ) {
1148
						$attachment['thumbnail'] = $thumb[0];
1149
					}
1150
1151
					$attachment['link']      = get_permalink( $attachment['ID'] );
1152
					$attachment['edit_link'] = get_edit_post_link( $attachment['ID'] );
1153
					$attachment['download']  = wp_get_attachment_url( $attachment['ID'] );
1154
1155
					$attachment = apply_filters( 'pods_upload_attachment', $attachment, $params->post_id );
1156
1157
					wp_send_json( $attachment );
1158
				}//end if
1159
			}//end if
1160
		}//end if
1161
1162
		die();
1163
		// KBAI!
1164
	}
1165
1166
}
1167