avatar.php
2 weeks ago
boolean.php
2 weeks ago
code.php
2 weeks ago
color.php
2 weeks ago
comment.php
2 weeks ago
currency.php
2 weeks ago
date.php
2 weeks ago
datetime.php
2 weeks ago
email.php
2 weeks ago
file.php
2 weeks ago
heading.php
2 weeks ago
html.php
2 weeks ago
link.php
2 weeks ago
number.php
2 weeks ago
oembed.php
2 weeks ago
paragraph.php
2 weeks ago
password.php
2 weeks ago
phone.php
2 weeks ago
pick.php
2 weeks ago
slug.php
2 weeks ago
taxonomy.php
2 weeks ago
text.php
2 weeks ago
time.php
2 weeks ago
website.php
2 weeks ago
wysiwyg.php
2 weeks ago
file.php
1392 lines
| 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 | * Temporary upload directory. |
| 30 | * @var string |
| 31 | */ |
| 32 | private static $tmp_upload_dir; |
| 33 | |
| 34 | /** |
| 35 | * {@inheritdoc} |
| 36 | */ |
| 37 | public function setup() { |
| 38 | |
| 39 | static::$group = __( 'Relationships / Media', 'pods' ); |
| 40 | static::$label = __( 'File / Image / Video', 'pods' ); |
| 41 | |
| 42 | } |
| 43 | |
| 44 | /** |
| 45 | * {@inheritdoc} |
| 46 | */ |
| 47 | public function admin_init() { |
| 48 | |
| 49 | // Hook into AJAX for Uploads. |
| 50 | add_action( 'wp_ajax_pods_upload', array( $this, 'admin_ajax_upload' ) ); |
| 51 | add_action( 'wp_ajax_nopriv_pods_upload', array( $this, 'admin_ajax_upload' ) ); |
| 52 | |
| 53 | } |
| 54 | |
| 55 | /** |
| 56 | * {@inheritdoc} |
| 57 | */ |
| 58 | public function options() { |
| 59 | |
| 60 | $sizes = get_intermediate_image_sizes(); |
| 61 | |
| 62 | $image_sizes = array(); |
| 63 | |
| 64 | foreach ( $sizes as $size ) { |
| 65 | $image_sizes[ $size ] = ucwords( str_replace( '-', ' ', $size ) ); |
| 66 | } |
| 67 | |
| 68 | $type = static::$type; |
| 69 | |
| 70 | $options = array( |
| 71 | static::$type . '_format_type' => array( |
| 72 | 'label' => __( 'Upload Limit', 'pods' ), |
| 73 | 'default' => 'single', |
| 74 | 'required' => true, |
| 75 | 'type' => 'pick', |
| 76 | 'data' => array( |
| 77 | 'single' => __( 'Single File', 'pods' ), |
| 78 | 'multi' => __( 'Multiple Files', 'pods' ), |
| 79 | ), |
| 80 | 'pick_show_select_text' => 0, |
| 81 | 'dependency' => true, |
| 82 | ), |
| 83 | static::$type . '_uploader' => array( |
| 84 | 'label' => __( 'File Uploader', 'pods' ), |
| 85 | 'default' => 'attachment', |
| 86 | 'required' => true, |
| 87 | 'type' => 'pick', |
| 88 | 'data' => apply_filters( |
| 89 | "pods_form_ui_field_{$type}_uploader_options", |
| 90 | array( |
| 91 | 'attachment' => __( 'Upload and/or Select (Media Library)', 'pods' ), |
| 92 | 'plupload' => __( 'Upload only (Plupload)', 'pods' ), |
| 93 | ) |
| 94 | ), |
| 95 | 'pick_show_select_text' => 0, |
| 96 | 'dependency' => true, |
| 97 | ), |
| 98 | static::$type . '_attachment_tab' => array( |
| 99 | 'label' => __( 'Media Library Default Tab', 'pods' ), |
| 100 | 'depends-on' => array( static::$type . '_uploader' => 'attachment' ), |
| 101 | 'default' => 'upload', |
| 102 | 'required' => true, |
| 103 | 'type' => 'pick', |
| 104 | 'data' => array( |
| 105 | // These keys must match WP media modal router names. |
| 106 | 'upload' => __( 'Upload File', 'pods' ), |
| 107 | 'browse' => __( 'Media Library', 'pods' ), |
| 108 | ), |
| 109 | 'pick_show_select_text' => 0, |
| 110 | ), |
| 111 | static::$type . '_upload_dir' => array( |
| 112 | 'label' => __( 'Upload Directory', 'pods' ), |
| 113 | 'default' => 'wp', |
| 114 | 'type' => 'pick', |
| 115 | 'required' => true, |
| 116 | 'data' => array( |
| 117 | 'wp' => __( 'WordPress Default', 'pods' ) . ' (/wp-content/uploads/yyyy/mm/)', |
| 118 | 'uploads' => __( 'Custom directory within the default uploads directory', 'pods' ), |
| 119 | ), |
| 120 | 'pick_show_select_text' => 0, |
| 121 | 'depends-on' => array( static::$type . '_uploader' => 'plupload' ), |
| 122 | 'dependency' => true, |
| 123 | ), |
| 124 | static::$type . '_upload_dir_custom' => array( |
| 125 | 'label' => __( 'Custom Upload Directory', 'pods' ), |
| 126 | 'help' => __( 'Magic tags are allowed for this field. The path is relative to the /wp-content/uploads/ folder on your site.', 'pods' ), |
| 127 | 'placeholder' => 'my-custom-folder', |
| 128 | 'required' => true, |
| 129 | 'depends-on' => array( |
| 130 | static::$type . '_uploader' => 'plupload', |
| 131 | static::$type . '_upload_dir' => 'uploads', |
| 132 | ), |
| 133 | /** |
| 134 | * Allow filtering the custom upload directory used. |
| 135 | * |
| 136 | * @since 2.7.28 |
| 137 | * |
| 138 | * @param string $default_directory The custom upload directory to use by default for new fields. |
| 139 | */ |
| 140 | 'default' => apply_filters( "pods_form_ui_field_{$type}_upload_dir_custom", '' ), |
| 141 | 'type' => 'text', |
| 142 | ), |
| 143 | static::$type . '_edit_title' => array( |
| 144 | 'label' => __( 'Editable Title', 'pods' ), |
| 145 | 'default' => 1, |
| 146 | 'type' => 'boolean', |
| 147 | ), |
| 148 | static::$type . '_show_edit_link' => array( |
| 149 | 'label' => __( 'Show Edit Link', 'pods' ), |
| 150 | 'default' => 0, |
| 151 | 'type' => 'boolean', |
| 152 | ), |
| 153 | static::$type . '_linked' => array( |
| 154 | 'label' => __( 'Show Download Link', 'pods' ), |
| 155 | 'default' => 0, |
| 156 | 'type' => 'boolean', |
| 157 | ), |
| 158 | static::$type . '_limit' => array( |
| 159 | 'label' => __( 'Max Number of Files', 'pods' ), |
| 160 | 'depends-on' => array( static::$type . '_format_type' => 'multi' ), |
| 161 | 'default' => 0, |
| 162 | 'type' => 'number', |
| 163 | ), |
| 164 | static::$type . '_restrict_filesize' => array( |
| 165 | 'label' => __( 'Restrict File Size', 'pods' ), |
| 166 | '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' ), |
| 167 | 'depends-on' => array( static::$type . '_uploader' => 'plupload' ), |
| 168 | 'default' => '', |
| 169 | 'text_placeholder' => '10MB', |
| 170 | 'type' => 'text', |
| 171 | ), |
| 172 | static::$type . '_type' => array( |
| 173 | 'label' => __( 'Restrict File Types', 'pods' ), |
| 174 | 'default' => apply_filters( "pods_form_ui_field_{$type}_type_default", 'images' ), |
| 175 | 'type' => 'pick', |
| 176 | 'data' => apply_filters( |
| 177 | "pods_form_ui_field_{$type}_type_options", |
| 178 | array( |
| 179 | 'images' => __( 'Images (jpg, jpeg, png, gif)', 'pods' ), |
| 180 | 'video' => __( 'Video (mpg, mov, flv, mp4, etc..)', 'pods' ), |
| 181 | 'audio' => __( 'Audio (mp3, m4a, wav, wma, etc..)', 'pods' ), |
| 182 | 'text' => __( 'Text (txt, csv, tsv, rtx, etc..)', 'pods' ), |
| 183 | 'any' => __( 'Any Type (no restriction)', 'pods' ), |
| 184 | 'other' => __( 'Other (customize allowed extensions)', 'pods' ), |
| 185 | ) |
| 186 | ), |
| 187 | 'pick_show_select_text' => 0, |
| 188 | 'dependency' => true, |
| 189 | ), |
| 190 | static::$type . '_allowed_extensions' => array( |
| 191 | 'label' => __( 'Allowed File Extensions', 'pods' ), |
| 192 | 'description' => __( 'Separate file extensions with a comma (ex. jpg,png,mp4,mov). This only applies to the file uploader, media library selection will continue to fallback to the mime-type group like Images, Video, etc.', 'pods' ), |
| 193 | 'depends-on' => array( static::$type . '_type' => 'other' ), |
| 194 | 'default' => apply_filters( "pods_form_ui_field_{$type}_extensions_default", '' ), |
| 195 | 'text_placeholder' => 'jpg,png,mp4,mov', |
| 196 | 'type' => 'text', |
| 197 | ), |
| 198 | static::$type . '_field_template' => array( |
| 199 | 'label' => __( 'List Style', 'pods' ), |
| 200 | 'help' => __( 'You can choose which style you would like the files to appear within the form.', 'pods' ), |
| 201 | 'depends-on' => array( static::$type . '_type' => 'images' ), |
| 202 | 'default' => apply_filters( "pods_form_ui_field_{$type}_template_default", 'rows' ), |
| 203 | 'type' => 'pick', |
| 204 | 'data' => apply_filters( |
| 205 | "pods_form_ui_field_{$type}_type_templates", |
| 206 | array( |
| 207 | 'rows' => __( 'Rows', 'pods' ), |
| 208 | 'tiles' => __( 'Tiles', 'pods' ), |
| 209 | ) |
| 210 | ), |
| 211 | 'pick_show_select_text' => 0, |
| 212 | ), |
| 213 | static::$type . '_add_button' => array( |
| 214 | 'label' => __( 'Add Button Text', 'pods' ), |
| 215 | 'default' => __( 'Add File', 'pods' ), |
| 216 | 'type' => 'text', |
| 217 | ), |
| 218 | static::$type . '_modal_title' => array( |
| 219 | 'label' => __( 'Modal Title', 'pods' ), |
| 220 | 'depends-on' => array( static::$type . '_uploader' => 'attachment' ), |
| 221 | 'default' => __( 'Attach a file', 'pods' ), |
| 222 | 'type' => 'text', |
| 223 | ), |
| 224 | static::$type . '_modal_add_button' => array( |
| 225 | 'label' => __( 'Modal Add Button Text', 'pods' ), |
| 226 | 'depends-on' => array( static::$type . '_uploader' => 'attachment' ), |
| 227 | 'default' => __( 'Add File', 'pods' ), |
| 228 | 'type' => 'text', |
| 229 | ), |
| 230 | |
| 231 | /* WP GALLERY OUTPUT */ |
| 232 | static::$type . '_wp_gallery_output' => array( |
| 233 | 'label' => __( 'Output as a WP Gallery', 'pods' ), |
| 234 | 'help' => sprintf( __( '<a href="%s" target="_blank" rel="noopener noreferrer">Click here for more info</a>', 'pods' ), 'https://wordpress.org/support/article/inserting-images-into-posts-and-pages/' ), |
| 235 | 'depends-on' => array( static::$type . '_type' => 'images' ), |
| 236 | 'dependency' => true, |
| 237 | 'type' => 'boolean', |
| 238 | ), |
| 239 | static::$type . '_wp_gallery_link' => array( |
| 240 | 'label' => __( 'Gallery Image Links', 'pods' ), |
| 241 | 'depends-on' => array( static::$type . '_wp_gallery_output' => true ), |
| 242 | 'type' => 'pick', |
| 243 | 'data' => array( |
| 244 | 'post' => __( 'Attachment Page', 'pods' ), |
| 245 | 'file' => __( 'Media File', 'pods' ), |
| 246 | 'none' => __( 'None', 'pods' ), |
| 247 | ), |
| 248 | 'pick_show_select_text' => 0, |
| 249 | ), |
| 250 | static::$type . '_wp_gallery_columns' => array( |
| 251 | 'label' => __( 'Gallery Image Columns', 'pods' ), |
| 252 | 'depends-on' => array( static::$type . '_wp_gallery_output' => true ), |
| 253 | 'type' => 'pick', |
| 254 | 'data' => array( |
| 255 | '1' => '1', |
| 256 | '2' => '2', |
| 257 | '3' => '3', |
| 258 | '4' => '4', |
| 259 | '5' => '5', |
| 260 | '6' => '6', |
| 261 | '7' => '7', |
| 262 | '8' => '8', |
| 263 | '9' => '9', |
| 264 | ), |
| 265 | 'pick_show_select_text' => 0, |
| 266 | ), |
| 267 | static::$type . '_wp_gallery_random_sort' => array( |
| 268 | 'label' => __( 'Gallery Randomized Order', 'pods' ), |
| 269 | 'depends-on' => array( static::$type . '_wp_gallery_output' => true ), |
| 270 | 'type' => 'boolean', |
| 271 | ), |
| 272 | static::$type . '_wp_gallery_size' => array( |
| 273 | 'label' => __( 'Gallery Image Size', 'pods' ), |
| 274 | 'depends-on' => array( static::$type . '_wp_gallery_output' => true ), |
| 275 | 'type' => 'pick', |
| 276 | 'data' => $this->data_image_sizes(), |
| 277 | 'pick_show_select_text' => 0, |
| 278 | ), |
| 279 | ); |
| 280 | |
| 281 | return $options; |
| 282 | |
| 283 | } |
| 284 | |
| 285 | /** |
| 286 | * {@inheritdoc} |
| 287 | */ |
| 288 | public function prepare( $options = null ) { |
| 289 | $format = static::$prepare; |
| 290 | |
| 291 | // Maybe use number format for storage if limit is one. |
| 292 | if ( $options instanceof Field && 1 === $options->get_limit() ) { |
| 293 | $format = '%d'; |
| 294 | } |
| 295 | |
| 296 | return $format; |
| 297 | } |
| 298 | |
| 299 | /** |
| 300 | * {@inheritdoc} |
| 301 | */ |
| 302 | public function schema( $options = null ) { |
| 303 | return false; |
| 304 | } |
| 305 | |
| 306 | /** |
| 307 | * {@inheritdoc} |
| 308 | */ |
| 309 | public function display( $value = null, $name = null, $options = null, $pod = null, $id = null ) { |
| 310 | |
| 311 | if ( ! empty( $options[ static::$type . '_wp_gallery_output' ] ) ) { |
| 312 | return $this->do_wp_gallery( $value, $options ); |
| 313 | } |
| 314 | |
| 315 | if ( is_array( $value ) && ! empty( $value ) ) { |
| 316 | if ( isset( $value['ID'] ) ) { |
| 317 | $value = wp_get_attachment_url( $value['ID'] ); |
| 318 | } else { |
| 319 | $attachments = $value; |
| 320 | $value = array(); |
| 321 | |
| 322 | foreach ( $attachments as $v ) { |
| 323 | if ( ! is_array( $v ) ) { |
| 324 | $value[] = $v; |
| 325 | } elseif ( isset( $v['ID'] ) ) { |
| 326 | $value[] = wp_get_attachment_url( $v['ID'] ); |
| 327 | } |
| 328 | } |
| 329 | |
| 330 | $value = implode( ' ', $value ); |
| 331 | } |
| 332 | } |
| 333 | |
| 334 | return $value; |
| 335 | |
| 336 | } |
| 337 | |
| 338 | /** |
| 339 | * Determine whether someone has access to upload/browse for a file field in general. |
| 340 | * |
| 341 | * @return bool Whether someone has access to upload/browse for a file field in general. |
| 342 | */ |
| 343 | public function has_access_to_upload_browse() { |
| 344 | /** |
| 345 | * Access Checking |
| 346 | */ |
| 347 | $is_user_logged_in = is_user_logged_in(); |
| 348 | |
| 349 | $file_upload_requirements = [ |
| 350 | 'disabled' => ( defined( 'PODS_DISABLE_FILE_UPLOAD' ) && true === PODS_DISABLE_FILE_UPLOAD ), |
| 351 | 'require_login' => ( defined( 'PODS_UPLOAD_REQUIRE_LOGIN' ) && true === PODS_UPLOAD_REQUIRE_LOGIN && ! $is_user_logged_in ), |
| 352 | '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 ) ) ), |
| 353 | ]; |
| 354 | |
| 355 | $file_browser_requirements = [ |
| 356 | 'disabled' => ( defined( 'PODS_DISABLE_FILE_BROWSER' ) && true === PODS_DISABLE_FILE_BROWSER ), |
| 357 | 'require_login' => ( defined( 'PODS_FILES_REQUIRE_LOGIN' ) && true === PODS_FILES_REQUIRE_LOGIN && ! $is_user_logged_in ), |
| 358 | '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 ) ) ), |
| 359 | ]; |
| 360 | |
| 361 | $file_upload_requirements = array_filter( $file_upload_requirements ); |
| 362 | $file_browser_requirements = array_filter( $file_browser_requirements ); |
| 363 | |
| 364 | return empty( $file_upload_requirements ) || empty( $file_browser_requirements ); |
| 365 | } |
| 366 | |
| 367 | /** |
| 368 | * {@inheritdoc} |
| 369 | */ |
| 370 | public function input( $name, $value = null, $options = null, $pod = null, $id = null ) { |
| 371 | |
| 372 | $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options; |
| 373 | |
| 374 | $type = pods_v( 'type', $options, static::$type ); |
| 375 | |
| 376 | $args = compact( array_keys( get_defined_vars() ) ); |
| 377 | $args = (object) $args; |
| 378 | |
| 379 | if ( ! $this->has_access_to_upload_browse() ) { |
| 380 | ?> |
| 381 | <p><?php esc_html_e( 'You do not have access to upload / browse files. Contact your website admin to resolve.', 'pods' ); ?></p> |
| 382 | <?php |
| 383 | |
| 384 | return; |
| 385 | } |
| 386 | |
| 387 | wp_enqueue_media(); |
| 388 | |
| 389 | wp_enqueue_script( 'pods-i18n' ); |
| 390 | |
| 391 | // Ensure the media library is initialized |
| 392 | $this->render_input_script( $args ); |
| 393 | } |
| 394 | |
| 395 | /** |
| 396 | * {@inheritdoc} |
| 397 | */ |
| 398 | public function build_dfv_field_options( $options, $args ) { |
| 399 | |
| 400 | if ( ! is_admin() ) { |
| 401 | include_once ABSPATH . '/wp-admin/includes/template.php'; |
| 402 | |
| 403 | if ( is_multisite() ) { |
| 404 | include_once ABSPATH . '/wp-admin/includes/ms.php'; |
| 405 | } |
| 406 | } |
| 407 | |
| 408 | // Enforce defaults. |
| 409 | $all_options = static::options(); |
| 410 | |
| 411 | foreach ( $all_options as $option_name => $option ) { |
| 412 | $default = pods_v( 'default', $option, '' ); |
| 413 | |
| 414 | $options[ $option_name ] = pods_v( $option_name, $options, $default ); |
| 415 | |
| 416 | if ( '' === $options[ $option_name ] ) { |
| 417 | $options[ $option_name ] = $default; |
| 418 | } |
| 419 | } |
| 420 | |
| 421 | // Handle default template setting. |
| 422 | $file_field_template = pods_v( $args->type . '_field_template', $options ); |
| 423 | |
| 424 | // Get which file types the field is limited to. |
| 425 | $limit_file_type = pods_v( $args->type . '_type', $options ); |
| 426 | |
| 427 | $options[ $args->type . '_type' ] = $limit_file_type; |
| 428 | |
| 429 | // Non-image file types are forced to rows template right now. |
| 430 | if ( 'images' !== $limit_file_type ) { |
| 431 | $file_field_template = 'rows'; |
| 432 | } |
| 433 | |
| 434 | $options[ $args->type . '_field_template' ] = $file_field_template; |
| 435 | |
| 436 | // Enforce limit. |
| 437 | $file_limit = 1; |
| 438 | |
| 439 | if ( 'multi' === pods_v( $args->type . '_format_type', $options, 'single' ) ) { |
| 440 | $file_limit = (int) pods_v( $args->type . '_limit', $options, 0 ); |
| 441 | |
| 442 | if ( $file_limit < 0 ) { |
| 443 | $file_limit = 0; |
| 444 | } |
| 445 | } |
| 446 | |
| 447 | $options[ $args->type . '_limit' ] = $file_limit; |
| 448 | |
| 449 | // Build types and extensions to limit by. |
| 450 | if ( 'images' === $limit_file_type ) { |
| 451 | $limit_types = 'image'; |
| 452 | $limit_extensions = 'jpg,jpeg,png,gif'; |
| 453 | } elseif ( 'video' === $limit_file_type ) { |
| 454 | $limit_types = 'video'; |
| 455 | $limit_extensions = 'mpg,mov,flv,mp4'; |
| 456 | } elseif ( 'audio' === $limit_file_type ) { |
| 457 | $limit_types = 'audio'; |
| 458 | $limit_extensions = 'mp3,m4a,wav,wma'; |
| 459 | } elseif ( 'text' === $limit_file_type ) { |
| 460 | $limit_types = 'text'; |
| 461 | $limit_extensions = 'txt,rtx,csv,tsv'; |
| 462 | } elseif ( 'any' === $limit_file_type ) { |
| 463 | $limit_types = ''; |
| 464 | $limit_extensions = '*'; |
| 465 | } else { |
| 466 | $limit_types = pods_v( $args->type . '_allowed_extensions', $options, '', true ); |
| 467 | |
| 468 | $limit_extensions = $limit_types; |
| 469 | } |
| 470 | |
| 471 | // Find and replace certain characters to properly split by commas. |
| 472 | $find = array( |
| 473 | ' ', |
| 474 | '.', |
| 475 | "\n", |
| 476 | "\t", |
| 477 | ';', |
| 478 | ); |
| 479 | |
| 480 | $replace = array( |
| 481 | '', |
| 482 | ',', |
| 483 | ',', |
| 484 | ',', |
| 485 | ); |
| 486 | |
| 487 | $limit_types = trim( str_replace( $find, $replace, $limit_types ), ',' ); |
| 488 | $limit_extensions = trim( str_replace( $find, $replace, $limit_extensions ), ',' ); |
| 489 | $mime_types = get_allowed_mime_types(); |
| 490 | |
| 491 | if ( ! in_array( $limit_file_type, array( 'images', 'video', 'audio', 'text', 'any' ), true ) ) { |
| 492 | $new_limit_types = array(); |
| 493 | |
| 494 | $limit_types = array_filter( explode( ',', $limit_types ) ); |
| 495 | |
| 496 | foreach ( $limit_types as $k => $limit_type ) { |
| 497 | if ( isset( $mime_types[ $limit_type ] ) ) { |
| 498 | $mime = explode( '/', $mime_types[ $limit_type ] ); |
| 499 | $mime = $mime[0]; |
| 500 | |
| 501 | if ( ! in_array( $mime, $new_limit_types, true ) ) { |
| 502 | $new_limit_types[] = $mime; |
| 503 | } |
| 504 | } else { |
| 505 | $found = false; |
| 506 | |
| 507 | foreach ( $mime_types as $type => $mime ) { |
| 508 | if ( false !== strpos( $type, $limit_type ) ) { |
| 509 | $mime = explode( '/', $mime ); |
| 510 | $mime = $mime[0]; |
| 511 | |
| 512 | if ( ! in_array( $mime, $new_limit_types, true ) ) { |
| 513 | $new_limit_types[] = $mime; |
| 514 | } |
| 515 | |
| 516 | $found = true; |
| 517 | } |
| 518 | } |
| 519 | |
| 520 | if ( ! $found ) { |
| 521 | $new_limit_types[] = $limit_type; |
| 522 | } |
| 523 | }//end if |
| 524 | }//end foreach |
| 525 | |
| 526 | if ( ! empty( $new_limit_types ) ) { |
| 527 | $limit_types = implode( ',', $new_limit_types ); |
| 528 | } |
| 529 | }//end if |
| 530 | |
| 531 | $options['limit_types'] = $limit_types; |
| 532 | $options['limit_extensions'] = $limit_extensions; |
| 533 | |
| 534 | $is_user_logged_in = is_user_logged_in(); |
| 535 | |
| 536 | // @todo: plupload specific options need accommodation |
| 537 | if ( 'plupload' === pods_v( static::$type . '_uploader', $options ) ) { |
| 538 | wp_enqueue_script( 'plupload-all' ); |
| 539 | |
| 540 | $pod_id = (int) pods_v( 'pod_id', $args->pod, 0 ); |
| 541 | $field_id = (int) pods_v( 'id', $options, 0 ); |
| 542 | $item_id = (int) pods_v( 'id', $args, 0 ); |
| 543 | |
| 544 | if ( $is_user_logged_in ) { |
| 545 | $uid = 'user_' . get_current_user_id(); |
| 546 | } else { |
| 547 | $uid = pods_session_id(); |
| 548 | } |
| 549 | |
| 550 | $uri_hash = wp_create_nonce( 'pods_uri_' . $_SERVER['REQUEST_URI'] ); |
| 551 | |
| 552 | $nonce_name = 'pods_upload:' . json_encode( compact( 'pod_name', 'field_name', 'uid', 'uri_hash', 'id' ) ); |
| 553 | $field_nonce = wp_create_nonce( $nonce_name ); |
| 554 | |
| 555 | $plupload_init = [ |
| 556 | 'runtimes' => 'html5,silverlight,flash,html4', |
| 557 | 'url' => admin_url( 'admin-ajax.php?pods_ajax=1', 'relative' ), |
| 558 | 'file_data_name' => 'Filedata', |
| 559 | 'multiple_queues' => false, |
| 560 | 'max_file_size' => wp_max_upload_size() . 'b', |
| 561 | 'flash_swf_url' => includes_url( 'js/plupload/plupload.flash.swf' ), |
| 562 | 'silverlight_xap_url' => includes_url( 'js/plupload/plupload.silverlight.xap' ), |
| 563 | 'filters' => [ |
| 564 | [ |
| 565 | 'title' => __( 'Allowed Files', 'pods' ), |
| 566 | 'extensions' => '*', |
| 567 | ], |
| 568 | ], |
| 569 | 'multipart' => true, |
| 570 | 'urlstream_upload' => true, |
| 571 | 'multipart_params' => [ |
| 572 | '_wpnonce' => $field_nonce, |
| 573 | 'action' => 'pods_upload', |
| 574 | 'method' => 'upload', |
| 575 | 'pod' => $pod_id, |
| 576 | 'field' => $field_id, |
| 577 | 'item_id' => $item_id, |
| 578 | 'uri' => $uri_hash, |
| 579 | ], |
| 580 | ]; |
| 581 | |
| 582 | // Disable multi selection if only one is allowed. |
| 583 | if ( 1 === $file_limit ) { |
| 584 | $plupload_init['multi_selection'] = false; |
| 585 | } |
| 586 | |
| 587 | // Backwards compatibility: Pass post ID if we're in an add or edit post screen. |
| 588 | $post = get_post(); |
| 589 | if ( $post instanceof WP_Post ) { |
| 590 | $plupload_init['multipart_params']['post_id'] = $post->ID; |
| 591 | } |
| 592 | |
| 593 | $options['plupload_init'] = $plupload_init; |
| 594 | }//end if |
| 595 | |
| 596 | return $options; |
| 597 | |
| 598 | } |
| 599 | |
| 600 | /** |
| 601 | * {@inheritdoc} |
| 602 | */ |
| 603 | public function build_dfv_field_attributes( $attributes, $args ) { |
| 604 | |
| 605 | // Add template class. |
| 606 | $attributes['class'] .= ' pods-field-template-' . $args->options[ $args->type . '_field_template' ]; |
| 607 | |
| 608 | return $attributes; |
| 609 | |
| 610 | } |
| 611 | |
| 612 | /** |
| 613 | * {@inheritdoc} |
| 614 | */ |
| 615 | public function build_dfv_field_item_data( $args ) { |
| 616 | |
| 617 | $data = array(); |
| 618 | |
| 619 | $title_editable = (int) pods_v( $args->type . '_edit_title', $args->options, 0 ); |
| 620 | |
| 621 | $value = $args->value; |
| 622 | |
| 623 | if ( empty( $value ) ) { |
| 624 | $value = array(); |
| 625 | } else { |
| 626 | $value = (array) $value; |
| 627 | } |
| 628 | |
| 629 | foreach ( $value as $id ) { |
| 630 | $attachment = get_post( $id ); |
| 631 | |
| 632 | if ( empty( $attachment ) ) { |
| 633 | continue; |
| 634 | } |
| 635 | |
| 636 | $icon = ''; |
| 637 | |
| 638 | // @todo Add access check |
| 639 | $edit_link = get_edit_post_link( $attachment->ID, 'raw' ); |
| 640 | |
| 641 | $link = get_permalink( $attachment->ID ); |
| 642 | $download = wp_get_attachment_url( $attachment->ID ); |
| 643 | |
| 644 | $thumb = wp_get_attachment_image_src( $id, 'thumbnail', true ); |
| 645 | |
| 646 | if ( ! empty( $thumb[0] ) ) { |
| 647 | $icon = $thumb[0]; |
| 648 | } |
| 649 | |
| 650 | $title = $attachment->post_title; |
| 651 | |
| 652 | if ( 0 === $title_editable ) { |
| 653 | $title = basename( $attachment->guid ); |
| 654 | } |
| 655 | |
| 656 | $data[] = array( |
| 657 | 'id' => esc_html( $id ), |
| 658 | 'icon' => esc_attr( $icon ), |
| 659 | 'name' => wp_strip_all_tags( html_entity_decode( $title ) ), |
| 660 | 'edit_link' => html_entity_decode( esc_url( $edit_link ) ), |
| 661 | 'link' => html_entity_decode( esc_url( $link ) ), |
| 662 | 'download' => html_entity_decode( esc_url( $download ) ), |
| 663 | 'selected' => true, |
| 664 | ); |
| 665 | }//end foreach |
| 666 | |
| 667 | return $data; |
| 668 | |
| 669 | } |
| 670 | |
| 671 | /** |
| 672 | * {@inheritdoc} |
| 673 | */ |
| 674 | public function validate( $value, $name = null, $options = null, $fields = null, $pod = null, $id = null, $params = null ) { |
| 675 | |
| 676 | // @todo Check file size |
| 677 | // @todo Check file extensions |
| 678 | return parent::validate( $value, $name, $options, $fields, $pod, $id, $params ); |
| 679 | |
| 680 | } |
| 681 | |
| 682 | /** |
| 683 | * {@inheritdoc} |
| 684 | */ |
| 685 | public function save( $value, $id = null, $name = null, $options = null, $fields = null, $pod = null, $params = null ) { |
| 686 | |
| 687 | if ( empty( self::$api ) ) { |
| 688 | self::$api = pods_api(); |
| 689 | } |
| 690 | |
| 691 | if ( null === $value ) { |
| 692 | $value = []; |
| 693 | } elseif ( ! is_array( $value ) || isset( $value['id'] ) ) { |
| 694 | $value = [ |
| 695 | $value, |
| 696 | ]; |
| 697 | } |
| 698 | |
| 699 | $value = array_unique( array_filter( $value ), SORT_REGULAR ); |
| 700 | |
| 701 | // Handle File title saving. |
| 702 | foreach ( $value as $id ) { |
| 703 | $title = false; |
| 704 | |
| 705 | if ( is_array( $id ) ) { |
| 706 | if ( isset( $id['title'] ) && 0 < strlen( trim( $id['title'] ) ) ) { |
| 707 | $title = trim( $id['title'] ); |
| 708 | } |
| 709 | |
| 710 | if ( isset( $id['id'] ) ) { |
| 711 | $id = (int) $id['id']; |
| 712 | } else { |
| 713 | $id = 0; |
| 714 | } |
| 715 | } |
| 716 | |
| 717 | if ( empty( $id ) ) { |
| 718 | continue; |
| 719 | } |
| 720 | |
| 721 | $attachment = null; |
| 722 | $attachment_data = array(); |
| 723 | |
| 724 | // Update the title if set. |
| 725 | if ( false !== $title && 1 === (int) pods_v( static::$type . '_edit_title', $options, 0 ) ) { |
| 726 | $attachment_data['post_title'] = $title; |
| 727 | } |
| 728 | |
| 729 | // Update attachment parent if it's not set yet and we're updating a post. |
| 730 | if ( ! empty( $params->id ) && ! empty( $pod['type'] ) && 'post_type' === $pod['type'] ) { |
| 731 | $attachment = get_post( $id ); |
| 732 | |
| 733 | if ( isset( $attachment->post_parent ) && 0 === (int) $attachment->post_parent ) { |
| 734 | $attachment_data['post_parent'] = (int) $params->id; |
| 735 | } |
| 736 | } |
| 737 | |
| 738 | // Update the attachment if it the data array is not still empty. |
| 739 | if ( ! empty( $attachment_data ) ) { |
| 740 | $attachment_data['ID'] = $id; |
| 741 | |
| 742 | if ( $attachment ) { |
| 743 | // Add post type to trigger attachment update filters from other plugins. |
| 744 | $attachment_data['post_type'] = $attachment->post_type; |
| 745 | } |
| 746 | |
| 747 | self::$api->save_wp_object( 'media', $attachment_data ); |
| 748 | } |
| 749 | }//end foreach |
| 750 | |
| 751 | } |
| 752 | |
| 753 | /** |
| 754 | * {@inheritdoc} |
| 755 | */ |
| 756 | public function ui( $id, $value, $name = null, $options = null, $fields = null, $pod = null ) { |
| 757 | |
| 758 | if ( empty( $value ) ) { |
| 759 | return; |
| 760 | } |
| 761 | |
| 762 | if ( ! empty( $value ) && isset( $value['ID'] ) ) { |
| 763 | $value = array( $value ); |
| 764 | } |
| 765 | |
| 766 | $type = static::$type; |
| 767 | $image_size = apply_filters( "pods_form_ui_field_{$type}_ui_image_size", 'thumbnail', $id, $value, $name, $options, $pod ); |
| 768 | |
| 769 | return $this->images( $id, $value, $name, $options, $pod, $image_size ); |
| 770 | |
| 771 | } |
| 772 | |
| 773 | /** |
| 774 | * Return image(s) markup. |
| 775 | * |
| 776 | * @param int $id Item ID. |
| 777 | * @param mixed $value Field value. |
| 778 | * @param string $name Field name. |
| 779 | * @param array $options Field options. |
| 780 | * @param array $pod Pod options. |
| 781 | * @param string $image_size Image size. |
| 782 | * |
| 783 | * @return string |
| 784 | * @since 2.3.0 |
| 785 | */ |
| 786 | public function images( $id, $value, $name = null, $options = null, $pod = null, $image_size = null ) { |
| 787 | |
| 788 | $images = ''; |
| 789 | |
| 790 | if ( empty( $value ) || ! is_array( $value ) ) { |
| 791 | return $images; |
| 792 | } |
| 793 | |
| 794 | foreach ( $value as $v ) { |
| 795 | $images .= pods_image( $v, $image_size ); |
| 796 | } |
| 797 | |
| 798 | return $images; |
| 799 | |
| 800 | } |
| 801 | |
| 802 | /** |
| 803 | * Data callback for Image Sizes. |
| 804 | * |
| 805 | * @param string $name The name of the field. |
| 806 | * @param string|array $value The value of the field. |
| 807 | * @param array $options Field options. |
| 808 | * @param array $pod Pod data. |
| 809 | * @param int $id Item ID. |
| 810 | * |
| 811 | * @return array |
| 812 | * |
| 813 | * @since 2.3.0 |
| 814 | */ |
| 815 | public function data_image_sizes( $name = null, $value = null, $options = null, $pod = null, $id = null ) { |
| 816 | |
| 817 | $data = array(); |
| 818 | |
| 819 | $image_sizes = get_intermediate_image_sizes(); |
| 820 | |
| 821 | foreach ( $image_sizes as $image_size ) { |
| 822 | $data[ $image_size ] = ucwords( str_replace( '-', ' ', $image_size ) ); |
| 823 | } |
| 824 | |
| 825 | $data['full'] = __( 'Full Size' ); // Translated by WordPress core. |
| 826 | |
| 827 | return apply_filters( 'pods_form_ui_field_pick_data_image_sizes', $data, $name, $value, $options, $pod, $id ); |
| 828 | |
| 829 | } |
| 830 | |
| 831 | /** |
| 832 | * Create a WP Gallery from the passed values (need to be attachments) |
| 833 | * |
| 834 | * @since 2.7.0 |
| 835 | * |
| 836 | * @param string|array $value The value(s). |
| 837 | * @param array $options The field options. |
| 838 | * |
| 839 | * @return string |
| 840 | */ |
| 841 | public function do_wp_gallery( $value, $options ) { |
| 842 | |
| 843 | if ( ! $value ) { |
| 844 | return ''; |
| 845 | } |
| 846 | |
| 847 | $shortcode_args = array(); |
| 848 | |
| 849 | if ( ! empty( $options[ static::$type . '_wp_gallery_columns' ] ) ) { |
| 850 | $shortcode_args['columns'] = absint( $options[ static::$type . '_wp_gallery_columns' ] ); |
| 851 | } |
| 852 | |
| 853 | if ( ! empty( $options[ static::$type . '_wp_gallery_random_sort' ] ) ) { |
| 854 | $shortcode_args['orderby'] = 'rand'; |
| 855 | } |
| 856 | |
| 857 | if ( ! empty( $options[ static::$type . '_wp_gallery_link' ] ) ) { |
| 858 | $shortcode_args['link'] = $options[ static::$type . '_wp_gallery_link' ]; |
| 859 | } |
| 860 | |
| 861 | if ( ! empty( $options[ static::$type . '_wp_gallery_size' ] ) ) { |
| 862 | $shortcode_args['size'] = $options[ static::$type . '_wp_gallery_size' ]; |
| 863 | } |
| 864 | |
| 865 | if ( isset( $value['ID'] ) ) { |
| 866 | $shortcode_args['ids'] = $value['ID']; |
| 867 | } else { |
| 868 | $images = array(); |
| 869 | |
| 870 | foreach ( (array) $value as $v ) { |
| 871 | if ( ! is_array( $v ) ) { |
| 872 | $images[] = (int) $v; |
| 873 | } elseif ( isset( $v['ID'] ) ) { |
| 874 | $images[] = (int) $v['ID']; |
| 875 | } |
| 876 | } |
| 877 | |
| 878 | $shortcode_args['ids'] = implode( ',', $images ); |
| 879 | } |
| 880 | |
| 881 | if ( is_callable( 'gallery_shortcode' ) ) { |
| 882 | return gallery_shortcode( $shortcode_args ); |
| 883 | } else { |
| 884 | $shortcode = '[gallery'; |
| 885 | |
| 886 | foreach ( $shortcode_args as $key => $shortcode_arg ) { |
| 887 | $shortcode .= ' ' . esc_attr( $key ) . '="' . esc_attr( $shortcode_arg ) . '"'; |
| 888 | } |
| 889 | |
| 890 | $shortcode .= ']'; |
| 891 | |
| 892 | return do_shortcode( $shortcode ); |
| 893 | } |
| 894 | |
| 895 | } |
| 896 | |
| 897 | /** |
| 898 | * Handle file row output for uploaders |
| 899 | * |
| 900 | * @param array $attributes Field options. |
| 901 | * @param int $limit List limit. |
| 902 | * @param bool $editable Whether the items should be editable. |
| 903 | * @param null|int|string $id Item ID. |
| 904 | * @param null|string $icon Icon URL. |
| 905 | * @param null|string $name File name. |
| 906 | * @param bool $linked Whether the items should be linked. |
| 907 | * @param null|string $link Link URL. |
| 908 | * |
| 909 | * @return string |
| 910 | * @since 2.0.0 |
| 911 | * |
| 912 | * @deprecated 2.7.0 |
| 913 | */ |
| 914 | public function markup( $attributes, $limit = 1, $editable = true, $id = null, $icon = null, $name = null, $linked = false, $link = null ) { |
| 915 | |
| 916 | _doing_it_wrong( 'PodsField_File::markup', esc_html__( 'This method has been deprecated and will be removed from Pods 3.0', 'pods' ), '2.7' ); |
| 917 | |
| 918 | // Preserve current file type. |
| 919 | $field_type = PodsForm::$field_type; |
| 920 | |
| 921 | ob_start(); |
| 922 | |
| 923 | if ( empty( $id ) ) { |
| 924 | $id = '{{id}}'; |
| 925 | } |
| 926 | |
| 927 | if ( empty( $icon ) ) { |
| 928 | $icon = '{{icon}}'; |
| 929 | } |
| 930 | |
| 931 | if ( empty( $name ) ) { |
| 932 | $name = '{{name}}'; |
| 933 | } |
| 934 | |
| 935 | if ( empty( $link ) ) { |
| 936 | $link = '{{link}}'; |
| 937 | } |
| 938 | |
| 939 | $editable = (boolean) $editable; |
| 940 | $linked = (boolean) $linked; |
| 941 | ?> |
| 942 | <li class="pods-file hidden" id="pods-file-<?php echo esc_attr( $id ); ?>"> |
| 943 | <?php |
| 944 | // @codingStandardsIgnoreLine |
| 945 | echo PodsForm::field( $attributes['name'] . '[' . $id . '][id]', $id, 'hidden' ); |
| 946 | ?> |
| 947 | |
| 948 | <ul class="pods-file-meta media-item"> |
| 949 | <?php if ( 1 !== (int) $limit ) { ?> |
| 950 | <li class="pods-file-col pods-file-handle">Handle</li> |
| 951 | <?php } ?> |
| 952 | |
| 953 | <li class="pods-file-col pods-file-icon"> |
| 954 | <img class="pinkynail" src="<?php echo esc_url( $icon ); ?>" alt="Icon" /> |
| 955 | </li> |
| 956 | |
| 957 | <li class="pods-file-col pods-file-name"> |
| 958 | <?php |
| 959 | if ( $editable ) { |
| 960 | // @codingStandardsIgnoreLine |
| 961 | echo PodsForm::field( $attributes['name'] . '[' . $id . '][title]', $name, 'text' ); |
| 962 | } else { |
| 963 | echo esc_html( $name ); |
| 964 | } |
| 965 | ?> |
| 966 | </li> |
| 967 | |
| 968 | <li class="pods-file-col pods-file-actions"> |
| 969 | <ul> |
| 970 | <li class="pods-file-col pods-file-delete"><a href="#delete">Delete</a></li> |
| 971 | <?php |
| 972 | if ( $linked ) { |
| 973 | ?> |
| 974 | <li class="pods-file-col pods-file-download"> |
| 975 | <a href="<?php echo esc_url( $link ); ?>" target="_blank" rel="noopener noreferrer">Download</a></li> |
| 976 | <?php |
| 977 | } |
| 978 | ?> |
| 979 | </ul> |
| 980 | </li> |
| 981 | </ul> |
| 982 | </li> |
| 983 | <?php |
| 984 | PodsForm::$field_type = $field_type; |
| 985 | |
| 986 | return ob_get_clean(); |
| 987 | |
| 988 | } |
| 989 | |
| 990 | /** |
| 991 | * Handle AJAX plupload calls. |
| 992 | * |
| 993 | * @since 2.3.0 |
| 994 | */ |
| 995 | public function admin_ajax_upload() { |
| 996 | |
| 997 | pods_session_start(); |
| 998 | |
| 999 | // Sanitize input @codingStandardsIgnoreLine |
| 1000 | $params = pods_unslash( (array) $_POST ); |
| 1001 | |
| 1002 | foreach ( $params as $key => $value ) { |
| 1003 | if ( 'action' === $key ) { |
| 1004 | continue; |
| 1005 | } |
| 1006 | |
| 1007 | unset( $params[ $key ] ); |
| 1008 | |
| 1009 | $params[ str_replace( '_podsfix_', '', $key ) ] = $value; |
| 1010 | } |
| 1011 | |
| 1012 | $params = (object) $params; |
| 1013 | |
| 1014 | $methods = array( |
| 1015 | 'upload', |
| 1016 | ); |
| 1017 | |
| 1018 | if ( ! isset( $params->method ) || ! in_array( $params->method, $methods, true ) || ! isset( $params->pod ) || ! isset( $params->field ) || ! isset( $params->uri ) || empty( $params->uri ) ) { |
| 1019 | return pods_error( __( 'Invalid AJAX request', 'pods' ), PodsInit::$admin ); |
| 1020 | } elseif ( ! empty( $params->pod ) && empty( $params->field ) ) { |
| 1021 | return pods_error( __( 'Invalid AJAX request', 'pods' ), PodsInit::$admin ); |
| 1022 | } elseif ( empty( $params->pod ) && ! current_user_can( 'upload_files' ) ) { |
| 1023 | return pods_error( __( 'Invalid AJAX request', 'pods' ), PodsInit::$admin ); |
| 1024 | } |
| 1025 | |
| 1026 | /** |
| 1027 | * Access Checking |
| 1028 | */ |
| 1029 | $upload_disabled = false; |
| 1030 | $is_user_logged_in = is_user_logged_in(); |
| 1031 | |
| 1032 | if ( defined( 'PODS_DISABLE_FILE_UPLOAD' ) && true === PODS_DISABLE_FILE_UPLOAD ) { |
| 1033 | $upload_disabled = true; |
| 1034 | } elseif ( ! $is_user_logged_in && defined( 'PODS_UPLOAD_REQUIRE_LOGIN' ) ) { |
| 1035 | if ( true === PODS_UPLOAD_REQUIRE_LOGIN ) { |
| 1036 | $upload_disabled = true; |
| 1037 | } elseif ( is_string( PODS_UPLOAD_REQUIRE_LOGIN ) && ! current_user_can( PODS_UPLOAD_REQUIRE_LOGIN ) ) { |
| 1038 | $upload_disabled = true; |
| 1039 | } |
| 1040 | } |
| 1041 | |
| 1042 | $uid = pods_session_id(); |
| 1043 | |
| 1044 | if ( $is_user_logged_in ) { |
| 1045 | $uid = 'user_' . get_current_user_id(); |
| 1046 | } |
| 1047 | |
| 1048 | $nonce_check = 'pods_upload_' . (int) $params->pod . '_' . $uid . '_' . $params->uri . '_' . (int) $params->field; |
| 1049 | |
| 1050 | if ( true === $upload_disabled || ! isset( $params->_wpnonce ) || false === wp_verify_nonce( $params->_wpnonce, $nonce_check ) ) { |
| 1051 | return pods_error( __( 'Unauthorized request', 'pods' ), PodsInit::$admin ); |
| 1052 | } |
| 1053 | |
| 1054 | $pod = array(); |
| 1055 | $field = array( |
| 1056 | 'type' => 'file', |
| 1057 | 'options' => array(), |
| 1058 | ); |
| 1059 | |
| 1060 | if ( empty( self::$api ) ) { |
| 1061 | self::$api = pods_api(); |
| 1062 | } |
| 1063 | |
| 1064 | self::$api->display_errors = false; |
| 1065 | |
| 1066 | if ( ! empty( $params->pod ) ) { |
| 1067 | $pod = self::$api->load_pod( array( 'id' => (int) $params->pod ) ); |
| 1068 | $field = self::$api->load_field( array( 'id' => (int) $params->field ) ); |
| 1069 | |
| 1070 | if ( empty( $pod ) || empty( $field ) || (int) $pod['id'] !== (int) $field['pod_id'] || ! isset( $pod['fields'][ $field['name'] ] ) ) { |
| 1071 | return pods_error( __( 'Invalid field request', 'pods' ), PodsInit::$admin ); |
| 1072 | } |
| 1073 | |
| 1074 | if ( ! in_array( $field['type'], PodsForm::file_field_types(), true ) ) { |
| 1075 | return pods_error( __( 'Invalid field', 'pods' ), PodsInit::$admin ); |
| 1076 | } |
| 1077 | } |
| 1078 | |
| 1079 | $method = $params->method; |
| 1080 | |
| 1081 | // Cleaning up $params |
| 1082 | unset( $params->action, $params->method, $params->_wpnonce ); |
| 1083 | |
| 1084 | $params->item_id = (int) pods_v( 'item_id', $params, 0 ); |
| 1085 | |
| 1086 | /** |
| 1087 | * Upload a new file (advanced - returns URL and ID) |
| 1088 | */ |
| 1089 | if ( 'upload' === $method ) { |
| 1090 | $file = $_FILES['Filedata']; |
| 1091 | |
| 1092 | $limit_size = pods_v( $field['type'] . '_restrict_filesize', $field['options'] ); |
| 1093 | |
| 1094 | if ( ! empty( $limit_size ) ) { |
| 1095 | if ( false !== stripos( $limit_size, 'GB' ) ) { |
| 1096 | $limit_size = (float) trim( str_ireplace( 'GB', '', $limit_size ) ); |
| 1097 | $limit_size = $limit_size * 1025 * 1025 * 1025; |
| 1098 | // convert to MB to KB to B |
| 1099 | } elseif ( false !== stripos( $limit_size, 'MB' ) ) { |
| 1100 | $limit_size = (float) trim( str_ireplace( 'MB', '', $limit_size ) ); |
| 1101 | $limit_size = $limit_size * 1025 * 1025; |
| 1102 | // convert to KB to B |
| 1103 | } elseif ( false !== stripos( $limit_size, 'KB' ) ) { |
| 1104 | $limit_size = (float) trim( str_ireplace( 'KB', '', $limit_size ) ); |
| 1105 | $limit_size *= 1025; |
| 1106 | // convert to B |
| 1107 | } elseif ( false !== stripos( $limit_size, 'B' ) ) { |
| 1108 | $limit_size = (float) trim( str_ireplace( 'B', '', $limit_size ) ); |
| 1109 | } else { |
| 1110 | $limit_size = wp_max_upload_size(); |
| 1111 | } |
| 1112 | |
| 1113 | if ( 0 < $limit_size && $limit_size < $file['size'] ) { |
| 1114 | $error = __( 'File size too large, max size is %s', 'pods' ); |
| 1115 | $error = sprintf( $error, pods_v( $field['type'] . '_restrict_filesize', $field['options'] ) ); |
| 1116 | |
| 1117 | return pods_error( '<div style="color:#FF0000">Error: ' . $error . '</div>' ); |
| 1118 | } |
| 1119 | }//end if |
| 1120 | |
| 1121 | $limit_file_type = pods_v( $field['type'] . '_type', $field['options'], 'images' ); |
| 1122 | |
| 1123 | if ( 'images' === $limit_file_type ) { |
| 1124 | $limit_types = 'jpg,jpeg,png,gif'; |
| 1125 | } elseif ( 'video' === $limit_file_type ) { |
| 1126 | $limit_types = 'mpg,mov,flv,mp4'; |
| 1127 | } elseif ( 'audio' === $limit_file_type ) { |
| 1128 | $limit_types = 'mp3,m4a,wav,wma'; |
| 1129 | } elseif ( 'text' === $limit_file_type ) { |
| 1130 | $limit_types = 'txt,rtx,csv,tsv'; |
| 1131 | } elseif ( 'any' === $limit_file_type ) { |
| 1132 | $limit_types = ''; |
| 1133 | } else { |
| 1134 | $limit_types = pods_v( $field['type'] . '_allowed_extensions', $field['options'], '', true ); |
| 1135 | } |
| 1136 | |
| 1137 | $limit_types = trim( |
| 1138 | str_replace( |
| 1139 | array( ' ', '.', "\n", "\t", ';' ), array( |
| 1140 | '', |
| 1141 | ',', |
| 1142 | ',', |
| 1143 | ',', |
| 1144 | ), $limit_types |
| 1145 | ), ',' |
| 1146 | ); |
| 1147 | |
| 1148 | $mime_types = get_allowed_mime_types(); |
| 1149 | |
| 1150 | if ( in_array( $limit_file_type, array( 'images', 'audio', 'video' ), true ) ) { |
| 1151 | $new_limit_types = array(); |
| 1152 | |
| 1153 | foreach ( $mime_types as $type => $mime ) { |
| 1154 | if ( 0 === strpos( $mime, $limit_file_type ) ) { |
| 1155 | $type = explode( '|', $type ); |
| 1156 | |
| 1157 | $new_limit_types = array_merge( $new_limit_types, $type ); |
| 1158 | } |
| 1159 | } |
| 1160 | |
| 1161 | if ( ! empty( $new_limit_types ) ) { |
| 1162 | $limit_types = implode( ',', $new_limit_types ); |
| 1163 | } |
| 1164 | } elseif ( 'any' !== $limit_file_type ) { |
| 1165 | $new_limit_types = array(); |
| 1166 | |
| 1167 | $limit_types = explode( ',', $limit_types ); |
| 1168 | |
| 1169 | foreach ( $limit_types as $k => $limit_type ) { |
| 1170 | $found = false; |
| 1171 | |
| 1172 | foreach ( $mime_types as $type => $mime ) { |
| 1173 | if ( 0 === strpos( $mime, $limit_type ) ) { |
| 1174 | $type = explode( '|', $type ); |
| 1175 | |
| 1176 | foreach ( $type as $t ) { |
| 1177 | if ( ! in_array( $t, $new_limit_types, true ) ) { |
| 1178 | $new_limit_types[] = $t; |
| 1179 | } |
| 1180 | } |
| 1181 | |
| 1182 | $found = true; |
| 1183 | } |
| 1184 | } |
| 1185 | |
| 1186 | if ( ! $found ) { |
| 1187 | $new_limit_types[] = $limit_type; |
| 1188 | } |
| 1189 | }//end foreach |
| 1190 | |
| 1191 | if ( ! empty( $new_limit_types ) ) { |
| 1192 | $limit_types = implode( ',', $new_limit_types ); |
| 1193 | } |
| 1194 | }//end if |
| 1195 | |
| 1196 | $limit_types = explode( ',', $limit_types ); |
| 1197 | |
| 1198 | $limit_types = array_filter( array_unique( $limit_types ) ); |
| 1199 | |
| 1200 | if ( ! empty( $limit_types ) ) { |
| 1201 | $file_info = pathinfo( $file['name'] ); |
| 1202 | $ok = false; |
| 1203 | |
| 1204 | if ( isset( $file_info['extension'] ) ) { |
| 1205 | // Enforce lowercase for the extension checking. |
| 1206 | $file_info['extension'] = strtolower( $file_info['extension'] ); |
| 1207 | |
| 1208 | foreach ( $limit_types as $limit_type ) { |
| 1209 | $limit_type = strtolower( trim( $limit_type, ' .' ) ); |
| 1210 | |
| 1211 | if ( $limit_type === $file_info['extension'] ) { |
| 1212 | $ok = true; |
| 1213 | |
| 1214 | break; |
| 1215 | } |
| 1216 | } |
| 1217 | } |
| 1218 | |
| 1219 | if ( false === $ok ) { |
| 1220 | $error = __( 'File type not allowed, please use one of the following: %s', 'pods' ); |
| 1221 | $error = sprintf( $error, '.' . implode( ', .', $limit_types ) ); |
| 1222 | |
| 1223 | return pods_error( '<div style="color:#FF0000">Error: ' . $error . '</div>' ); |
| 1224 | } |
| 1225 | }//end if |
| 1226 | |
| 1227 | $custom_handler = apply_filters( 'pods_upload_handle', null, 'Filedata', $params->item_id, $params, $field ); |
| 1228 | |
| 1229 | if ( null === $custom_handler ) { |
| 1230 | |
| 1231 | // Start custom directory. |
| 1232 | $upload_dir = pods_v( $field['type'] . '_upload_dir', $field['options'], 'wp' ); |
| 1233 | |
| 1234 | if ( 'wp' !== $upload_dir ) { |
| 1235 | $custom_dir = pods_v( $field['type'] . '_upload_dir_custom', $field['options'], '' ); |
| 1236 | $context_pod = null; |
| 1237 | |
| 1238 | if ( $params->item_id ) { |
| 1239 | $context_pod = pods( pods_v( 'name', $pod, false ), $params->item_id ); |
| 1240 | |
| 1241 | if ( ! $context_pod->exists() ) { |
| 1242 | $context_pod = null; |
| 1243 | } |
| 1244 | } |
| 1245 | |
| 1246 | /** |
| 1247 | * Filter the custom upload directory Pod context. |
| 1248 | * |
| 1249 | * @since 2.7.28 |
| 1250 | * |
| 1251 | * @param Pods $context_pod The Pods object of the associated pod for the post type. |
| 1252 | * @param array $params The POSTed parameters for the request. |
| 1253 | * @param array $field The field configuration associated to the upload field. |
| 1254 | * @param array $pod The pod configuration associated to the upload field. |
| 1255 | */ |
| 1256 | $context_pod = apply_filters( 'pods_upload_dir_custom_context_pod', $context_pod, $params, $field, $pod ); |
| 1257 | |
| 1258 | $custom_dir = pods_evaluate_tags( $custom_dir, array( 'pod' => $context_pod ) ); |
| 1259 | |
| 1260 | /** |
| 1261 | * Filter the custom Pod upload directory. |
| 1262 | * |
| 1263 | * @since 2.7.28 |
| 1264 | * |
| 1265 | * @param string $custom_dir The directory to use for the uploaded file. |
| 1266 | * @param array $params The POSTed parameters for the request. |
| 1267 | * @param Pods $context_pod The Pods object of the associated pod for the post type. |
| 1268 | * @param array $field The field configuration associated to the upload field. |
| 1269 | * @param array $pod The pod configuration associated to the upload field. |
| 1270 | */ |
| 1271 | $custom_dir = apply_filters( 'pods_upload_dir_custom', $custom_dir, $params, $context_pod, $field, $pod ); |
| 1272 | |
| 1273 | self::$tmp_upload_dir = $custom_dir; |
| 1274 | |
| 1275 | add_filter( 'upload_dir', array( $this, 'filter_upload_dir' ) ); |
| 1276 | } |
| 1277 | |
| 1278 | // Upload file. |
| 1279 | $post_id = 0; |
| 1280 | if ( 'post_type' === pods_v( 'type', $pod, null ) ) { |
| 1281 | $post_id = $params->item_id; |
| 1282 | } |
| 1283 | |
| 1284 | $attachment_id = media_handle_upload( 'Filedata', $post_id ); |
| 1285 | |
| 1286 | // End custom directory. |
| 1287 | if ( 'wp' !== $upload_dir ) { |
| 1288 | remove_filter( 'upload_dir', array( $this, 'filter_upload_dir' ) ); |
| 1289 | |
| 1290 | self::$tmp_upload_dir = null; |
| 1291 | } |
| 1292 | |
| 1293 | if ( is_object( $attachment_id ) ) { |
| 1294 | $errors = array(); |
| 1295 | |
| 1296 | foreach ( $attachment_id->errors['upload_error'] as $error_code => $error_message ) { |
| 1297 | $errors[] = '[' . $error_code . '] ' . $error_message; |
| 1298 | } |
| 1299 | |
| 1300 | return pods_error( '<div style="color:#FF0000">Error: ' . implode( '</div><div>', $errors ) . '</div>' ); |
| 1301 | } else { |
| 1302 | $attachment = get_post( $attachment_id, ARRAY_A ); |
| 1303 | |
| 1304 | $attachment['filename'] = basename( $attachment['guid'] ); |
| 1305 | |
| 1306 | $thumb = wp_get_attachment_image_src( $attachment['ID'], 'thumbnail', true ); |
| 1307 | |
| 1308 | $attachment['thumbnail'] = ''; |
| 1309 | |
| 1310 | if ( ! empty( $thumb[0] ) ) { |
| 1311 | $attachment['thumbnail'] = $thumb[0]; |
| 1312 | } |
| 1313 | |
| 1314 | $attachment['link'] = get_permalink( $attachment['ID'] ); |
| 1315 | $attachment['edit_link'] = get_edit_post_link( $attachment['ID'] ); |
| 1316 | $attachment['download'] = wp_get_attachment_url( $attachment['ID'] ); |
| 1317 | |
| 1318 | $attachment = apply_filters( 'pods_upload_attachment', $attachment, $params->item_id ); |
| 1319 | |
| 1320 | wp_send_json( $attachment ); |
| 1321 | }//end if |
| 1322 | }//end if |
| 1323 | }//end if |
| 1324 | |
| 1325 | die(); |
| 1326 | // KBAI! |
| 1327 | } |
| 1328 | |
| 1329 | /** |
| 1330 | * Modify the upload directory. |
| 1331 | * |
| 1332 | * @since 2.7.28 |
| 1333 | * |
| 1334 | * @see wp_upload_dir() |
| 1335 | * |
| 1336 | * @param array $uploads The uploads directory information. |
| 1337 | * |
| 1338 | * @return array The filtered uploads directory information. |
| 1339 | */ |
| 1340 | public function filter_upload_dir( $uploads ) { |
| 1341 | if ( empty( self::$tmp_upload_dir ) ) { |
| 1342 | return $uploads; |
| 1343 | } |
| 1344 | |
| 1345 | $dir = trim( self::$tmp_upload_dir, '/' ); |
| 1346 | $subdir = trim( $uploads['subdir'], '/' ); |
| 1347 | |
| 1348 | foreach ( $uploads as $key => $val ) { |
| 1349 | if ( ! is_string( $val ) ) { |
| 1350 | continue; |
| 1351 | } |
| 1352 | |
| 1353 | if ( $subdir ) { |
| 1354 | $uploads[ $key ] = str_replace( $subdir, $dir, $val ); |
| 1355 | } elseif ( in_array( $key, array( 'path', 'url', 'subdir' ), true ) ) { |
| 1356 | $uploads[ $key ] = trailingslashit( $val ) . $dir; |
| 1357 | } |
| 1358 | } |
| 1359 | |
| 1360 | return $uploads; |
| 1361 | } |
| 1362 | |
| 1363 | /** |
| 1364 | * Build field data for Pods DFV. |
| 1365 | * |
| 1366 | * @param object $args { |
| 1367 | * Field information arguments. |
| 1368 | * |
| 1369 | * @type string $name Field name. |
| 1370 | * @type string $type Field type. |
| 1371 | * @type array $options Field options. |
| 1372 | * @type mixed $value Current value. |
| 1373 | * @type array $pod Pod information. |
| 1374 | * @type int|string $id Current item ID. |
| 1375 | * @type string $form_field_type HTML field type. |
| 1376 | * } |
| 1377 | * |
| 1378 | * @return array |
| 1379 | */ |
| 1380 | public function build_dfv_field_data( $args ) { |
| 1381 | $data = parent::build_dfv_field_data( $args ); |
| 1382 | |
| 1383 | // Normalize arrays for multiple select. |
| 1384 | if ( is_array( $data['fieldValue'] ) ) { |
| 1385 | $data['fieldValue'] = array_values( $data['fieldValue'] ); |
| 1386 | } |
| 1387 | |
| 1388 | return $data; |
| 1389 | } |
| 1390 | |
| 1391 | } |
| 1392 |