PluginProbe
SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent / 3.4.4
SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent v3.4.4
3.5.4 3.5.3 3.5.2 3.5.1 3.4.9 3.5.0 3.4.8 3.4.7 trunk 2.3.1 3.3.6 3.3.7 3.3.8 3.3.9 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.6
supportcandy / includes / models / class-wpsc-attachment.php

class-wpsc-attachment.php in SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent 3.4.4, at includes/models/class-wpsc-attachment.php

1,341 lines 41.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 exit; // Exit if accessed directly!
4 }
5
6 if ( ! class_exists( 'WPSC_Attachment' ) ) :
7
8 final class WPSC_Attachment {
9
10 /**
11 * Object data in key => val pair.
12 *
13 * @var array
14 */
15 private $data = array();
16
17 /**
18 * Set whether or not current object properties modified
19 *
20 * @var boolean
21 */
22 private $is_modified = false;
23
24 /**
25 * Schema for this model
26 *
27 * @var array
28 */
29 public static $schema = array();
30
31 /**
32 * Prevent fields to modify
33 *
34 * @var array
35 */
36 public static $prevent_modify = array();
37
38 /**
39 * Catche for search results for ticket list of attachments.
40 *
41 * @var array
42 */
43 private static $tl_search_items;
44
45 /**
46 * Initialize this class
47 *
48 * @return void
49 */
50 public static function init() {
51
52 // Apply schema for this model.
53 add_action( 'init', array( __CLASS__, 'apply_schema' ), 2 );
54
55 // Get object of this class.
56 add_filter( 'wpsc_load_ref_classes', array( __CLASS__, 'load_ref_class' ) );
57
58 // File upload.
59 add_action( 'wp_ajax_wpsc_file_upload', array( __CLASS__, 'file_upload' ) );
60 add_action( 'wp_ajax_nopriv_wpsc_file_upload', array( __CLASS__, 'file_upload' ) );
61
62 // Custom image in tinymce.
63 add_action( 'wp_ajax_wpsc_add_custom_image_tinymce', array( __CLASS__, 'add_custom_image_tinymce' ) );
64 add_action( 'wp_ajax_nopriv_wpsc_add_custom_image_tinymce', array( __CLASS__, 'add_custom_image_tinymce' ) );
65 add_action( 'wp_ajax_wpsc_edit_custom_image_tinymce', array( __CLASS__, 'edit_custom_image_tinymce' ) );
66 add_action( 'wp_ajax_nopriv_wpsc_edit_custom_image_tinymce', array( __CLASS__, 'edit_custom_image_tinymce' ) );
67
68 // Check download file.
69 add_action( 'init', array( __CLASS__, 'check_download_file' ), 100 );
70
71 // Upload tinymce image.
72 add_action( 'wp_ajax_wpsc_tinymce_upload_file', array( __CLASS__, 'tinymce_upload_file' ) );
73 add_action( 'wp_ajax_nopriv_wpsc_tinymce_upload_file', array( __CLASS__, 'tinymce_upload_file' ) );
74
75 // Attachment garbage collector.
76 add_action( 'wpsc_attach_garbage_collector', array( __CLASS__, 'garbage_collector' ) );
77 }
78
79 /**
80 * Change file upload path
81 *
82 * @param array $param - file upload array.
83 * @return array
84 */
85 public static function wpsc_upload_dir( $param ) {
86
87 $today = new DateTime();
88 $file_path = $param['basedir'] . '/wpsc/' . $today->format( 'Y' ) . '/' . $today->format( 'm' );
89 if ( ! file_exists( $file_path ) ) {
90 mkdir( $file_path, 0755, true );
91 }
92
93 $param['path'] = $file_path;
94
95 return $param;
96 }
97
98 /**
99 * Custom upload mime types
100 *
101 * @param array $existing_mimes - file upload array.
102 * @return array
103 */
104 public static function wpsc_custom_upload_mimes( $existing_mimes ) {
105
106 $settings = get_option( 'wpsc-gs-file-attachments', array() );
107
108 // Merge allowed-file-ext-mimes first.
109 if ( isset( $settings['allowed-file-ext-mimes'] ) ) {
110 $existing_mimes = array_merge( $existing_mimes, $settings['allowed-file-ext-mimes'] );
111 }
112
113 // Then apply mime-exceptions to give them priority.
114 if ( isset( $settings['mime-exceptions'] ) && is_array( $settings['mime-exceptions'] ) ) {
115 foreach ( $settings['mime-exceptions'] as $type ) {
116 $type_array = explode( ':', $type );
117 if ( count( $type_array ) === 2 ) {
118 $existing_mimes[ $type_array[0] ] = $type_array[1];
119 }
120 }
121 }
122
123 return $existing_mimes;
124 }
125
126 /**
127 * Apply schema for this model
128 *
129 * @return void
130 */
131 public static function apply_schema() {
132
133 $schema = array(
134 'id' => array(
135 'has_ref' => false,
136 'ref_class' => '',
137 'has_multiple_val' => false,
138 ),
139 'name' => array(
140 'has_ref' => false,
141 'ref_class' => '',
142 'has_multiple_val' => false,
143 ),
144 'file_path' => array(
145 'has_ref' => false,
146 'ref_class' => '',
147 'has_multiple_val' => false,
148 ),
149 'is_image' => array(
150 'has_ref' => false,
151 'ref_class' => '',
152 'has_multiple_val' => false,
153 ),
154 'is_active' => array(
155 'has_ref' => false,
156 'ref_class' => '',
157 'has_multiple_val' => false,
158 ),
159 'is_uploaded' => array(
160 'has_ref' => false,
161 'ref_class' => '',
162 'has_multiple_val' => false,
163 ),
164 'date_created' => array(
165 'has_ref' => true,
166 'ref_class' => 'datetime',
167 'has_multiple_val' => false,
168 ),
169 'source' => array(
170 'has_ref' => false,
171 'ref_class' => '',
172 'has_multiple_val' => false,
173 ),
174 'source_id' => array(
175 'has_ref' => false,
176 'ref_class' => '',
177 'has_multiple_val' => false,
178 ),
179 'ticket_id' => array(
180 'has_ref' => false,
181 'ref_class' => '',
182 'has_multiple_val' => false,
183 ),
184 'customer_id' => array(
185 'has_ref' => false,
186 'ref_class' => '',
187 'has_multiple_val' => false,
188 ),
189 );
190 self::$schema = apply_filters( 'wpsc_attachment_schema', $schema );
191
192 // Prevent modify.
193 $prevent_modify = array( 'id' );
194 self::$prevent_modify = apply_filters( 'wpsc_attachment_prevent_modify', $prevent_modify );
195 }
196
197 /**
198 * Model constructor
199 *
200 * @param int $id - Optional. Data record id to retrive object for.
201 */
202 public function __construct( $id = 0 ) {
203
204 global $wpdb;
205
206 $id = intval( $id );
207
208 if ( $id > 0 ) {
209
210 $attachment = $wpdb->get_row( "SELECT * FROM {$wpdb->prefix}psmsc_attachments WHERE id = " . $id, ARRAY_A );
211 if ( ! is_array( $attachment ) ) {
212 return;
213 }
214
215 foreach ( $attachment as $key => $val ) {
216 $this->data[ $key ] = $val !== null ? $val : '';
217 }
218 }
219 }
220
221 /**
222 * Convert object into an array
223 *
224 * @return array
225 */
226 public function to_array() {
227
228 return $this->data;
229 }
230
231 /**
232 * Magic get function to use with object arrow function
233 *
234 * @param string $var_name - variable name.
235 * @return mixed
236 */
237 public function __get( $var_name ) {
238
239 if ( ! isset( $this->data[ $var_name ] ) ||
240 $this->data[ $var_name ] == null ||
241 $this->data[ $var_name ] == ''
242 ) {
243 return self::$schema[ $var_name ]['has_multiple_val'] ? array() : '';
244 }
245
246 if ( self::$schema[ $var_name ]['has_multiple_val'] ) {
247
248 $response = array();
249 $values = $this->data[ $var_name ] ? explode( '|', $this->data[ $var_name ] ) : array();
250 foreach ( $values as $val ) {
251 $response[] = self::$schema[ $var_name ]['has_ref'] ?
252 WPSC_Functions::get_object( self::$schema[ $var_name ]['ref_class'], $val ) :
253 $val;
254 }
255 return $response;
256
257 } else {
258
259 return self::$schema[ $var_name ]['has_ref'] && $this->data[ $var_name ] ?
260 WPSC_Functions::get_object( self::$schema[ $var_name ]['ref_class'], $this->data[ $var_name ] ) :
261 $this->data[ $var_name ];
262 }
263 }
264
265 /**
266 * Magic function to use setting object field with arrow function
267 *
268 * @param string $var_name - (Required) property slug.
269 * @param mixed $value - (Required) value to set for a property.
270 * @return void
271 */
272 public function __set( $var_name, $value ) {
273
274 if (
275 ! isset( $this->data[ $var_name ] ) ||
276 in_array( $var_name, self::$prevent_modify )
277 ) {
278 return;
279 }
280
281 $data_val = '';
282 if ( self::$schema[ $var_name ]['has_multiple_val'] ) {
283
284 $data_vals = array_map(
285 fn( $val ) => is_object( $val ) ? WPSC_Functions::set_object( self::$schema[ $var_name ]['ref_class'], $val ) : $val,
286 $value
287 );
288
289 $data_val = $data_vals ? implode( '|', $data_vals ) : '';
290
291 } else {
292
293 $data_val = is_object( $value ) ? WPSC_Functions::set_object( self::$schema[ $var_name ]['ref_class'], $value ) : $value;
294 }
295
296 if ( $this->data[ $var_name ] == $data_val ) {
297 return;
298 }
299
300 $this->data[ $var_name ] = $data_val;
301 $this->is_modified = true;
302 }
303
304 /**
305 * Save changes made
306 *
307 * @return boolean
308 */
309 public function save() {
310
311 global $wpdb;
312
313 if ( ! $this->is_modified ) {
314 return true;
315 }
316
317 $data = $this->data;
318 $success = true;
319
320 if ( ! isset( $data['id'] ) ) {
321
322 $at = self::insert( $data );
323 if ( $at ) {
324 $this->data = $at->data;
325 $success = true;
326 } else {
327 $success = false;
328 }
329 } else {
330
331 unset( $data['id'] );
332 $success = $wpdb->update(
333 $wpdb->prefix . 'psmsc_attachments',
334 $data,
335 array( 'id' => $this->data['id'] )
336 );
337 }
338 $this->is_modified = false;
339 return $success ? true : false;
340 }
341
342 /**
343 * Insert new attachment
344 *
345 * @param array $data - insert data.
346 * @return WPSC_Attachment
347 */
348 public static function insert( $data ) {
349
350 global $wpdb;
351
352 $data['is_active'] = isset( $data['is_active'] ) ? $data['is_active'] : 0;
353
354 $success = $wpdb->insert(
355 $wpdb->prefix . 'psmsc_attachments',
356 $data
357 );
358
359 if ( ! $success ) {
360 return false;
361 }
362
363 $attachment = new WPSC_Attachment( $wpdb->insert_id );
364 return $attachment;
365 }
366
367 /**
368 * Make it inactive so that garbage collector will delete files associated in
369 * background and then delete the record. This will improve its performance.
370 *
371 * @param WPSC_Attachment $attachment - attachment object.
372 * @return boolean
373 */
374 public static function destroy( $attachment ) {
375
376 $attachment->is_active = 0;
377 $attachment->save();
378 return true;
379 }
380
381 /**
382 * Set data to create new object using direct data. Used in find method
383 *
384 * @param array $data - data to set for object.
385 * @return void
386 */
387 private function set_data( $data ) {
388
389 foreach ( $data as $var_name => $val ) {
390 $this->data[ $var_name ] = $val !== null ? $val : '';
391 }
392 }
393
394 /**
395 * Find records based on given filters
396 *
397 * @param array $filter - array containing array items like search, where, orderby, order, page_no, items_per_page, etc.
398 * @param boolean $is_object - return data as array or object. Default object.
399 * @return mixed
400 */
401 public static function find( $filter = array(), $is_object = true ) {
402
403 global $wpdb;
404
405 $sql = 'SELECT * FROM ' . $wpdb->prefix . 'psmsc_attachments ';
406 $where = self::get_where( $filter );
407
408 $filter['items_per_page'] = isset( $filter['items_per_page'] ) ? $filter['items_per_page'] : 5;
409 $filter['page_no'] = isset( $filter['page_no'] ) ? $filter['page_no'] : 1;
410 $filter['orderby'] = isset( $filter['orderby'] ) ? $filter['orderby'] : 'id';
411 $filter['order'] = isset( $filter['order'] ) ? $filter['order'] : 'ASC';
412
413 $order = WPSC_Functions::parse_order( $filter );
414 $limit = WPSC_Functions::parse_limit( $filter );
415
416 $sql = $sql . $where . $order . $limit;
417 $results = $wpdb->get_results( $sql, ARRAY_A );
418
419 // total results.
420 $sql = 'SELECT count(id) FROM ' . $wpdb->prefix . 'psmsc_attachments ';
421 $total_items = $wpdb->get_var( $sql . $where );
422
423 $response = WPSC_Functions::parse_response( $results, $total_items, $filter );
424
425 // Return array.
426 if ( ! $is_object ) {
427 return $response;
428 }
429
430 // create and return array of objects.
431 $temp_results = array();
432 foreach ( $response['results'] as $attachment ) {
433
434 $ob = new WPSC_Attachment();
435 $data = array();
436 foreach ( $attachment as $key => $val ) {
437 $data[ $key ] = $val;
438 }
439 $ob->set_data( $data );
440 $temp_results[] = $ob;
441 }
442 $response['results'] = $temp_results;
443
444 return $response;
445 }
446
447 /**
448 * Get where for find method
449 *
450 * @param array $filter - user filter.
451 * @return array
452 */
453 private static function get_where( $filter ) {
454
455 $where = array( '1=1' );
456
457 // Set user defined filters.
458 $meta_query = isset( $filter['meta_query'] ) ? $filter['meta_query'] : array();
459 if ( $meta_query ) {
460 $where[] = WPSC_Functions::parse_user_filters( __CLASS__, $meta_query );
461 }
462
463 // Search.
464 $search = WPSC_Functions::get_filter_search_str( $filter );
465 if ( $search ) {
466 $search_query = array(
467 'CONVERT(name USING utf8) LIKE \'%' . $search . '%\'',
468 );
469 $search_query = apply_filters( 'wpsc_attachment_search_query', $search_query, $filter );
470 $where[] = '( ' . implode( ' OR ', $search_query ) . ' )';
471 }
472
473 return 'WHERE ' . implode( ' AND ', $where ) . ' ';
474 }
475
476 /**
477 * Load current class to reference classes
478 *
479 * @param array $classes - Associative array of class names indexed by its slug.
480 * @return array
481 */
482 public static function load_ref_class( $classes ) {
483
484 $classes['wpsc_attachment'] = array(
485 'class' => __CLASS__,
486 'save-key' => 'id',
487 );
488 return $classes;
489 }
490
491 /**
492 * Clear records and actual files for attachments that are not active for more than 24 hrs.
493 * This uses cron-job for background running to improve performace of load-time while deleting attachments.
494 *
495 * @return void
496 */
497 public static function garbage_collector() {
498
499 global $wpdb;
500 $d = ( new DateTime() )->sub( new DateInterval( 'P1D' ) );
501
502 $attachments = self::find(
503 array(
504 'items_per_page' => 20,
505 'meta_query' => array(
506 'relation' => 'AND',
507 array(
508 'slug' => 'date_created',
509 'compare' => '<',
510 'val' => $d->format( 'Y-m-d H:i:s' ),
511 ),
512 array(
513 'relation' => 'OR',
514 array(
515 'slug' => 'is_active',
516 'compare' => '=',
517 'val' => '0',
518 ),
519 array(
520 'slug' => 'source',
521 'compare' => '=',
522 'val' => 'img_editor_tmp',
523 ),
524 ),
525 ),
526 )
527 )['results'];
528 foreach ( $attachments as $attachment ) {
529
530 $upload_dir = wp_upload_dir();
531 $file_path = $upload_dir['basedir'] . $attachment->file_path;
532 if ( file_exists( $file_path ) ) {
533 wp_delete_file( $file_path );
534 }
535 $wpdb->query( "DELETE FROM {$wpdb->prefix}psmsc_attachments WHERE id=" . $attachment->id );
536 }
537 }
538
539 /**
540 * Ajax callback for attachment file upload
541 *
542 * @return void
543 */
544 public static function file_upload() {
545
546 if ( check_ajax_referer( 'wpsc_file_upload', '_ajax_nonce', false ) != 1 ) {
547 wp_send_json_error( 'Unauthorized request!', 401 );
548 }
549
550 if ( ! WPSC_Text_Editor::is_allow_attachments() ) {
551 wp_send_json_error( new WP_Error( '001', 'Unauthorized' ), 401 );
552 }
553
554 $recaptcha = get_option( 'wpsc-recaptcha-settings' );
555 if ( $recaptcha['allow-recaptcha'] === 1 && $recaptcha['recaptcha-version'] == 3 && $recaptcha['recaptcha-site-key'] && $recaptcha['recaptcha-secret-key'] ) {
556 WPSC_MS_Recaptcha::validate( 'file_upload' );
557 }
558
559 $file = isset( $_FILES['wpscFileAttachment'] ) ? $_FILES['wpscFileAttachment'] : false; // phpcs:ignore
560 if ( ! $file ) {
561 wp_send_json_error( 'File not found!', 400 );
562 }
563
564 $file_settings = get_option( 'wpsc-gs-file-attachments' );
565 $original_name = sanitize_file_name( $file['name'] );
566 $filename = time() . '_' . sanitize_file_name( $file['name'] );
567 $extension = strtolower( pathinfo( $filename, PATHINFO_EXTENSION ) );
568 $today = new DateTime();
569 $upload_dir = wp_upload_dir();
570
571 // Allowed file extension.
572 $allowed_file_extensions = explode( ',', $file_settings['allowed-file-extensions'] );
573 $allowed_file_extensions = array_map( 'trim', $allowed_file_extensions );
574 $allowed_file_extensions = array_map( 'strtolower', $allowed_file_extensions );
575 if ( ! ( in_array( $extension, $allowed_file_extensions ) ) ) {
576 wp_send_json_error( 'File extension not allowed!', 400 );
577 }
578
579 // Allowed file size.
580 $allowed_file_size = intval( $file_settings['attachments-max-filesize'] ) * 1000000;
581 if ( ! ( isset( $file['size'] ) && $file['size'] <= $allowed_file_size ) ) {
582 wp_send_json_error( 'File size exceeds allowed limit!', 400 );
583 }
584
585 // Init attachment data.
586 $data = array(
587 'name' => $original_name,
588 'date_created' => $today->format( 'Y-m-d H:i:s' ),
589 );
590
591 // Check for image type. Add a ".txt" extension to non-image file to prevent executing uploaded files on server.
592 $img_extensions = array( 'png', 'jpeg', 'jpg', 'bmp', 'pdf', 'gif' );
593 if ( ! in_array( $extension, $img_extensions ) ) {
594 $data['is_image'] = 0;
595 } else {
596 $data['is_image'] = 1;
597 }
598
599 $ext = pathinfo( $filename, PATHINFO_EXTENSION );
600 $file_name = substr( $filename, 0, -( strlen( $ext ) + 1 ) );
601 $filename = $file_name . '.' . strtolower( $ext );
602 $filepath_short = '/wpsc/' . $today->format( 'Y' ) . '/' . $today->format( 'm' ) . '/' . $filename;
603 $data['file_path'] = $filepath_short;
604
605 // Set up upload overrides.
606 $upload_overrides = array(
607 'test_form' => false,
608 );
609 $file['name'] = $filename;
610 add_filter( 'upload_dir', array( __CLASS__, 'wpsc_upload_dir' ) );
611 add_filter( 'upload_mimes', array( __CLASS__, 'wpsc_custom_upload_mimes' ) );
612 $uploaded_file = wp_handle_upload( $file, $upload_overrides );
613 // Insert record in database.
614 if ( $uploaded_file && empty( $uploaded_file['error'] ) ) {
615
616 $pos = strpos( $uploaded_file['file'], 'wpsc/' );
617 if ( $pos === false ) {
618 wp_send_json_error( 'Something went wrong!', 500 );
619 }
620 $new_path = substr( $uploaded_file['file'], $pos );
621 if ( $new_path[0] !== '/' ) {
622 $new_path = '/' . $new_path;
623 }
624 $data['file_path'] = $new_path;
625 $attachment = self::insert( $data );
626 if ( ! $attachment->id ) {
627 wp_send_json_error( 'Something went wrong!', 500 );
628 }
629
630 wp_send_json( array( 'id' => $attachment->id ) );
631
632 } else {
633
634 $error_message = isset( $uploaded_file['error'] ) ? $uploaded_file['error'] : 'Something went wrong!';
635 wp_send_json_error( $error_message, 500 );
636 }
637 }
638
639 /**
640 * Returns attachment ids to be used for search in ticket list
641 *
642 * @param string $search - search string.
643 * @return array
644 */
645 public static function get_tl_search_string( $search ) {
646
647 $search_items = array();
648 if ( is_array( self::$tl_search_items ) ) {
649 $search_items = self::$tl_search_items;
650 } else {
651 $attachments = self::find(
652 array(
653 'search' => $search,
654 'items_per_page' => 0,
655 )
656 )['results'];
657 if ( $attachments ) {
658 foreach ( $attachments as $attachment ) {
659 $search_items[] = $attachment->id;
660 }
661 }
662 self::$tl_search_items = $search_items;
663 }
664
665 return $search_items;
666 }
667
668 /**
669 * Custom tinymce image popup
670 *
671 * @return void
672 */
673 public static function add_custom_image_tinymce() {
674
675 if ( check_ajax_referer( 'wpsc_add_custom_image_tinymce', '_ajax_nonce', false ) != 1 ) {
676 wp_send_json_error( 'Unauthorized request!', 401 );
677 }
678
679 $title = esc_attr__( 'Insert/edit image', 'supportcandy' );
680
681 $editor_id = isset( $_POST['editor_id'] ) ? sanitize_text_field( wp_unslash( $_POST['editor_id'] ) ) : '';
682 if ( ! $editor_id ) {
683 wp_send_json_error( 'Something went wrong!', 400 );
684 }
685
686 ob_start();?>
687 <form action="#" onsubmit="return false;" class="wpsc-insert-edit-image">
688 <div class="wpsc-input-group">
689 <div class="label-container">
690 <label for=""><?php esc_attr_e( 'Source', 'supportcandy' ); ?></label>
691 <span class="required-char">*</span>
692 </div>
693 <div style="display:flex;">
694 <input type="text" accept="image/*" id="wpsc-tinymce-image-url" class="wpsc-tinymce-image-url" style="flex-grow: 1;" autocomplete="off">
695 <button id="wpsc-tinymce-get-file-url" class="wpsc-button small secondary" style="margin-left: 2px; width:100px;" onclick="wpsc_tinymce_image_picker();"><?php esc_attr_e( 'Upload', 'supportcandy' ); ?></button>
696 <input type='file' accept="image/*" name='fileupload' id='wpsc-fileupload' style='display: none;'>
697 </div>
698 </div>
699 <div class="wpsc-input-group">
700 <div class="label-container">
701 <label for=""><?php esc_attr_e( 'Dimentions', 'supportcandy' ); ?></label>
702 <span class="required-char">*</span>
703 </div>
704 <div style="display: flex; align-items:center;">
705 <input type="text" id="wpsc-tinymce-image-width" aria-label="width" class="wpsc-image-dimention" style="width:70px; margin-right:5px;" autocomplete="off">
706 <span class="wpsc-image-dimention-x-sign" style="margin-right:5px;">x</span>
707 <input type="text" id="wpsc-tinymce-image-height" aria-label="height" class="wpsc-image-dimention" style="width:70px; margin-right:10px;" autocomplete="off">
708 <div class="checkbox-container">
709 <?php $unique_id = uniqid( 'wpsc_' ); ?>
710 <input id="<?php echo esc_attr( $unique_id ); ?>" type="checkbox" checked value="1"/>
711 <label for="<?php echo esc_attr( $unique_id ); ?>"><?php esc_attr_e( 'Constraint properties', 'supportcandy' ); ?></label>
712 </div>
713 </div>
714 </div>
715 <script>
716 jQuery(".wpsc-tinymce-image-url").change(function(){
717
718 var img = new Image();
719 img.src = jQuery(this).val();
720 img.onload = function() {
721 jQuery('#wpsc-tinymce-image-height').val(this.height);
722 jQuery('#wpsc-tinymce-image-width').val(this.width);
723 var aspectRatio = this.width/this.height;
724 //Get new height:
725 jQuery("#wpsc-tinymce-image-width").on("change", function(){
726
727 if(jQuery("#<?php echo esc_attr( $unique_id ); ?>").prop('checked') == true){
728 newWidth = jQuery(this).val();
729 newHeight = Math.round(newWidth/aspectRatio);
730 jQuery("#wpsc-tinymce-image-height").val(newHeight);
731 }
732 });
733 //Get new width:
734 jQuery("#wpsc-tinymce-image-height").on("change", function(){
735
736 if(jQuery("#<?php echo esc_attr( $unique_id ); ?>").prop('checked') == true){
737 newHeight = jQuery(this).val();
738 newWidth = Math.round(newHeight*aspectRatio);
739 jQuery("#wpsc-tinymce-image-width").val(newWidth);
740 }
741 });
742 }
743 });
744
745 /**
746 * Tinymce image picker
747 */
748 function wpsc_tinymce_image_picker() {
749
750 jQuery("#wpsc-fileupload").trigger("click");
751 jQuery("#wpsc-fileupload").unbind('change');
752
753 jQuery("#wpsc-fileupload").on("change", function() {
754 var file = this.files[0];
755 var dataform = new FormData();
756 dataform.append('file', file);
757 dataform.append('file_name', file.name);
758 dataform.append('action', 'wpsc_tinymce_upload_file');
759 dataform.append('_ajax_nonce', '<?php echo esc_attr( wp_create_nonce( 'wpsc_tinymce_upload_file' ) ); ?>');
760
761 jQuery.ajax({
762 url: supportcandy.ajax_url,
763 type: 'POST',
764 data: dataform,
765 processData: false,
766 contentType: false
767 }).done(function (res) {
768
769 jQuery('.wpsc-tinymce-image-url').val(res.imgURL);
770 var img = new Image();
771 img.src = res.imgURL;
772 img.onload = function() {
773
774 jQuery('#wpsc-tinymce-image-height').val(this.height);
775 jQuery('#wpsc-tinymce-image-width').val(this.width);
776 var aspectRatio = this.width/this.height;
777
778 //Get new height:
779 jQuery("#wpsc-tinymce-image-width").on("change", function() {
780
781 if(jQuery("#<?php echo esc_attr( $unique_id ); ?>").prop('checked') == true){
782 newWidth = jQuery(this).val();
783 newHeight = Math.round(newWidth/aspectRatio);
784 jQuery("#wpsc-tinymce-image-height").val(newHeight);
785 }
786 });
787
788 //Get new width:
789 jQuery("#wpsc-tinymce-image-height").on("change", function() {
790
791 if(jQuery("#<?php echo esc_attr( $unique_id ); ?>").prop('checked') == true){
792 newHeight = jQuery(this).val();
793 newWidth = Math.round(newHeight*aspectRatio);
794 jQuery("#wpsc-tinymce-image-width").val(newWidth);
795 }
796 });
797 };
798 });
799 });
800 }
801 </script>
802 </form>
803 <?php
804 $body = ob_get_clean();
805
806 ob_start();
807 ?>
808 <button class="wpsc-button small primary" onclick="wpsc_insert_editor_img('<?php echo esc_attr( $editor_id ); ?>');">
809 <?php esc_attr_e( 'Submit', 'supportcandy' ); ?>
810 </button>
811 <button class="wpsc-button small secondary" onclick="wpsc_close_modal();">
812 <?php esc_attr_e( 'Cancel', 'supportcandy' ); ?>
813 </button>
814 <?php
815 $footer = ob_get_clean();
816
817 $response = array(
818 'title' => $title,
819 'body' => $body,
820 'footer' => $footer,
821 );
822 wp_send_json( $response );
823 }
824
825 /**
826 * Custom tinymce image popup
827 *
828 * @return void
829 */
830 public static function edit_custom_image_tinymce() {
831
832 if ( check_ajax_referer( 'wpsc_edit_custom_image_tinymce', '_ajax_nonce', false ) != 1 ) {
833 wp_send_json_error( 'Unauthorized request!', 401 );
834 }
835
836 $title = esc_attr__( 'Edit image', 'supportcandy' );
837
838 $editor_id = isset( $_POST['editor_id'] ) ? sanitize_text_field( wp_unslash( $_POST['editor_id'] ) ) : '';
839 if ( ! $editor_id ) {
840 wp_send_json_error( 'Something went wrong!', 400 );
841 }
842
843 $height = isset( $_POST['height'] ) ? intval( $_POST['height'] ) : '';
844 if ( ! $height ) {
845 wp_send_json_error( 'Something went wrong!', 400 );
846 }
847
848 $width = isset( $_POST['width'] ) ? intval( $_POST['width'] ) : '';
849 if ( ! $width ) {
850 wp_send_json_error( 'Something went wrong!', 400 );
851 }
852
853 $src = isset( $_POST['src'] ) ? esc_url_raw( wp_unslash( $_POST['src'] ) ) : '';
854 if ( ! $src ) {
855 wp_send_json_error( 'Something went wrong!', 400 );
856 }
857
858 ob_start();
859 ?>
860 <form action="#" onsubmit="return false;" class="wpsc-insert-edit-image">
861 <div class="wpsc-input-group">
862 <div class="label-container">
863 <label for=""><?php esc_attr_e( 'Source', 'supportcandy' ); ?></label>
864 <span class="required-char">*</span>
865 </div>
866 <div style="display:flex;">
867 <input type="text" id="wpsc-tinymce-image-url" class="wpsc-tinymce-image-url" style="flex-grow: 1;" autocomplete="off" value="<?php echo esc_attr( $src ); ?>">
868 <button id="wpsc-tinymce-get-file-url" class="wpsc-button small secondary" style="margin-left: 2px; width:100px" onclick="wpsc_tinymce_image_picker();"><?php esc_attr_e( 'Upload', 'supportcandy' ); ?></button>
869 <input type='file' accept="image/*" name='fileupload' id='wpsc-fileupload' style='display: none;'>
870 </div>
871 </div>
872 <div class="wpsc-input-group">
873 <div class="label-container">
874 <label for=""><?php esc_attr_e( 'Dimentions', 'supportcandy' ); ?></label>
875 <span class="required-char">*</span>
876 </div>
877 <div style="display: flex; align-items:center;">
878 <input type="text" id="wpsc-tinymce-image-width" aria-label="width" class="wpsc-image-dimention" style="width:70px; margin-right:5px;" autocomplete="off" value="<?php echo esc_attr( $width ); ?>">
879 <span class="wpsc-image-dimention-x-sign" style="margin-right:5px;">x</span>
880 <input type="text" id="wpsc-tinymce-image-height" aria-label="height" class="wpsc-image-dimention" style="width:70px; margin-right:10px;" autocomplete="off" value="<?php echo esc_attr( $height ); ?>" >
881 <div class="checkbox-container">
882 <?php $unique_id = uniqid( 'wpsc_' ); ?>
883 <input id="<?php echo esc_attr( $unique_id ); ?>" type="checkbox" checked value="1"/>
884 <label for="<?php echo esc_attr( $unique_id ); ?>"><?php esc_attr_e( 'Constraint properties', 'supportcandy' ); ?></label>
885 </div>
886 </div>
887 </div>
888 <script>
889 jQuery(".wpsc-tinymce-image-url").change(function(){
890
891 var img = new Image();
892 img.src = jQuery(this).val();
893 img.onload = function() {
894 jQuery('#wpsc-tinymce-image-height').val(this.height);
895 jQuery('#wpsc-tinymce-image-width').val(this.width);
896 var aspectRatio = this.width/this.height;
897 //Get new height:
898 jQuery("#wpsc-tinymce-image-width").on("change", function(){
899
900 if(jQuery("#<?php echo esc_attr( $unique_id ); ?>").prop('checked') == true){
901 newWidth = jQuery(this).val();
902 newHeight = Math.round(newWidth/aspectRatio);
903 jQuery("#wpsc-tinymce-image-height").val(newHeight);
904 }
905 });
906 //Get new width:
907 jQuery("#wpsc-tinymce-image-height").on("change", function(){
908
909 if(jQuery("#<?php echo esc_attr( $unique_id ); ?>").prop('checked') == true){
910 newHeight = jQuery(this).val();
911 newWidth = Math.round(newHeight*aspectRatio);
912 jQuery("#wpsc-tinymce-image-width").val(newWidth);
913 }
914 });
915 }
916 });
917 var height = <?php echo esc_attr( $height ); ?>;
918 var width = <?php echo esc_attr( $width ); ?>;
919 var aspectRatio = width/height;
920 jQuery("#wpsc-tinymce-image-width").on("change", function(){
921
922 if(jQuery("#<?php echo esc_attr( $unique_id ); ?>").prop('checked') == true){
923 newWidth = jQuery(this).val();
924 newHeight = Math.round(newWidth/aspectRatio);
925 jQuery("#wpsc-tinymce-image-height").val(newHeight);
926 }
927 });
928 //Get new width:
929 jQuery("#wpsc-tinymce-image-height").on("change", function(){
930
931 if(jQuery("#<?php echo esc_attr( $unique_id ); ?>").prop('checked') == true){
932 newHeight = jQuery(this).val();
933 newWidth = Math.round(newHeight*aspectRatio);
934 jQuery("#wpsc-tinymce-image-width").val(newWidth);
935 }
936 });
937
938 /**
939 * Tinymce image picker
940 */
941 function wpsc_tinymce_image_picker() {
942
943 jQuery("#wpsc-fileupload").trigger("click");
944 jQuery("#wpsc-fileupload").unbind('change');
945
946 jQuery("#wpsc-fileupload").on("change", function() {
947 var file = this.files[0];
948 var dataform = new FormData();
949 dataform.append('file', file);
950 dataform.append('file_name', file.name);
951 dataform.append('action', 'wpsc_tinymce_upload_file');
952 dataform.append('_ajax_nonce', '<?php echo esc_attr( wp_create_nonce( 'wpsc_tinymce_upload_file' ) ); ?>');
953
954 jQuery.ajax({
955 url: supportcandy.ajax_url,
956 type: 'POST',
957 data: dataform,
958 processData: false,
959 contentType: false
960 }).done(function (res) {
961
962 jQuery('.wpsc-tinymce-image-url').val(res.imgURL);
963 var img = new Image();
964 img.src = res.imgURL;
965 img.onload = function() {
966
967 jQuery('#wpsc-tinymce-image-height').val(this.height);
968 jQuery('#wpsc-tinymce-image-width').val(this.width);
969 var aspectRatio = this.width/this.height;
970
971 //Get new height:
972 jQuery("#wpsc-tinymce-image-width").on("change", function() {
973
974 if(jQuery("#<?php echo esc_attr( $unique_id ); ?>").prop('checked') == true){
975 newWidth = jQuery(this).val();
976 newHeight = Math.round(newWidth/aspectRatio);
977 jQuery("#wpsc-tinymce-image-height").val(newHeight);
978 }
979 });
980
981 //Get new width:
982 jQuery("#wpsc-tinymce-image-height").on("change", function() {
983
984 if(jQuery("#<?php echo esc_attr( $unique_id ); ?>").prop('checked') == true){
985 newHeight = jQuery(this).val();
986 newWidth = Math.round(newHeight*aspectRatio);
987 jQuery("#wpsc-tinymce-image-width").val(newWidth);
988 }
989 });
990 };
991 });
992 });
993 }
994 </script>
995 </form>
996 <?php
997 $body = ob_get_clean();
998
999 ob_start();
1000 ?>
1001 <button class="wpsc-button small primary" onclick="wpsc_insert_editor_img('<?php echo esc_attr( $editor_id ); ?>');">
1002 <?php esc_attr_e( 'Submit', 'supportcandy' ); ?>
1003 </button>
1004 <button class="wpsc-button small secondary" onclick="wpsc_close_modal();">
1005 <?php esc_attr_e( 'Cancel', 'supportcandy' ); ?>
1006 </button>
1007 <?php
1008 $footer = ob_get_clean();
1009
1010 $response = array(
1011 'title' => $title,
1012 'body' => $body,
1013 'footer' => $footer,
1014 );
1015 wp_send_json( $response );
1016 }
1017
1018 /**
1019 * Check download file
1020 *
1021 * @return void
1022 */
1023 public static function check_download_file() {
1024
1025 if ( isset( $_REQUEST['wpsc_attachment'] ) ) { // phpcs:ignore
1026
1027 if ( WPSC_Functions::is_site_admin() && ! extension_loaded( 'fileinfo' ) ) {
1028 echo 'The fileinfo extension is not available. Please enable it in your PHP configuration.';
1029 exit;
1030 }
1031
1032 $current_user = WPSC_Current_User::$current_user;
1033 $has_auth = true;
1034 if ( isset( $_REQUEST['user'] ) && ! $current_user ) { // phpcs:ignore
1035
1036 $customer = new WPSC_Customer( intval( $_REQUEST['user'] ) ); // phpcs:ignore
1037 if ( ! $customer->id ) {
1038 wp_send_json_error( __( 'Bad request!', 'supportcandy' ), 400 );
1039 }
1040
1041 $current_user = WPSC_Current_User::change_current_user( $customer->email );
1042 $has_auth = false;
1043 }
1044
1045 $attachment_id = intval( $_REQUEST['wpsc_attachment'] ); // phpcs:ignore
1046 $attachment = new WPSC_Attachment( $attachment_id );
1047 if ( ! $attachment->id ) {
1048 return;
1049 }
1050 $auth_code = isset($_REQUEST['auth_code']) ? sanitize_text_field( $_REQUEST['auth_code'] ) : ''; // phpcs:ignore
1051 $advanced = get_option( 'wpsc-ms-advanced-settings' );
1052 switch ( $attachment->source ) {
1053
1054 case 'cf':
1055 $cf = new WPSC_Custom_Field( $attachment->source_id );
1056 if ( ! $cf->id ) {
1057 wp_send_json_error( __( 'Bad request!', 'supportcandy' ), 400 );
1058 }
1059
1060 if ( in_array( $cf->field, array( 'ticket', 'agentonly' ) ) ) { // ticket field.
1061
1062 $ticket = new WPSC_Ticket( $attachment->ticket_id );
1063 if ( ! $ticket->id ) {
1064 $ticket = new WPSC_Archive_Ticket( $attachment->ticket_id );
1065 if ( ! $ticket->id ) {
1066 wp_send_json_error( __( 'Bad request!', 'supportcandy' ), 400 );
1067 }
1068 }
1069
1070 if ( ! $has_auth ) {
1071 $auth_code = isset( $_REQUEST['auth_code'] ) ? sanitize_text_field( $_REQUEST['auth_code'] ) : ''; // phpcs:ignore
1072 if ( ! $auth_code || $auth_code != $ticket->auth_code ) {
1073 wp_send_json_error( 'Unauthorized!', 401 );
1074 }
1075 }
1076
1077 if ( is_a( $ticket, 'WPSC_Ticket' ) || is_a( $ticket, 'WPSC_Archive_Ticket' ) ) {
1078 // Determine correct class based on ticket type.
1079 $ticket_class = is_a( $ticket, 'WPSC_Ticket' )
1080 ? 'WPSC_Individual_Ticket'
1081 : 'WPSC_Individual_Archive_Ticket';
1082
1083 // Assign current ticket to class static property.
1084 $ticket_class::$ticket = $ticket;
1085 $has_access = (
1086 ( $current_user->is_agent && $ticket_class::has_ticket_cap( 'view' ) ) ||
1087 $ticket_class::is_customer() ||
1088 ( ! $advanced['ticket-url-auth'] && $ticket->auth_code === $auth_code )
1089 );
1090
1091 if ( ! $has_access ) {
1092 wp_send_json_error( __( 'Unauthorized!', 'supportcandy' ), 401 );
1093 }
1094 }
1095 self::file_download( $attachment );
1096
1097 } else { // customer field.
1098
1099 $customer = new WPSC_Customer( intval( $attachment->customer_id ) );
1100 $ticket_widgets = get_option( 'wpsc-ticket-widget', array() );
1101 $raised_by = $ticket_widgets['raised-by'];
1102
1103 if (
1104 $current_user->customer->id == $customer->id ||
1105 (
1106 $current_user->is_agent &&
1107 in_array( $current_user->agent->role, $raised_by['allowed-agent-roles'] )
1108 )
1109 ) {
1110 self::file_download( $attachment );
1111 }
1112 }
1113 break;
1114
1115 case 'reply':
1116 case 'report':
1117 $ticket = new WPSC_Ticket( $attachment->ticket_id );
1118 if ( ! $ticket->id ) {
1119 $ticket = new WPSC_Archive_Ticket( $attachment->ticket_id );
1120 if ( ! $ticket->id ) {
1121 wp_send_json_error( __( 'Bad request!', 'supportcandy' ), 400 );
1122 }
1123 }
1124
1125 if ( ! $has_auth ) {
1126 $auth_code = isset( $_REQUEST['auth_code'] ) ? sanitize_text_field( $_REQUEST['auth_code'] ) : ''; // phpcs:ignore
1127 if ( ! $auth_code || $auth_code != $ticket->auth_code ) {
1128 wp_send_json_error( 'Unauthorized!', 401 );
1129 }
1130 }
1131
1132 if ( is_a( $ticket, 'WPSC_Ticket' ) || is_a( $ticket, 'WPSC_Archive_Ticket' ) ) {
1133 // Determine correct class based on ticket type.
1134 $ticket_class = is_a( $ticket, 'WPSC_Ticket' )
1135 ? 'WPSC_Individual_Ticket'
1136 : 'WPSC_Individual_Archive_Ticket';
1137
1138 // Assign current ticket to class static property.
1139 $ticket_class::$ticket = $ticket;
1140 $has_access = (
1141 ( $current_user->is_agent && $ticket_class::has_ticket_cap( 'view' ) ) ||
1142 $ticket_class::is_customer() ||
1143 ( ! $advanced['ticket-url-auth'] && $ticket->auth_code === $auth_code )
1144 );
1145
1146 if ( ! $has_access ) {
1147 wp_send_json_error( __( 'Unauthorized!', 'supportcandy' ), 401 );
1148 }
1149 }
1150 self::file_download( $attachment );
1151 break;
1152
1153 case 'note':
1154 $ticket = new WPSC_Ticket( $attachment->ticket_id );
1155 if ( ! $ticket->id ) {
1156 $ticket = new WPSC_Archive_Ticket( $attachment->ticket_id );
1157 if ( ! $ticket->id ) {
1158 wp_send_json_error( __( 'Bad request!', 'supportcandy' ), 400 );
1159 }
1160 }
1161
1162 if ( ! $has_auth ) {
1163 $auth_code = isset( $_REQUEST['auth_code'] ) ? sanitize_text_field( $_REQUEST['auth_code'] ) : ''; // phpcs:ignore
1164 if ( ! $auth_code || $auth_code != $ticket->auth_code ) {
1165 wp_send_json_error( 'Unauthorized!', 401 );
1166 }
1167 }
1168
1169 if ( is_a( $ticket, 'WPSC_Ticket' ) || is_a( $ticket, 'WPSC_Archive_Ticket' ) ) {
1170
1171 // Determine correct handler class dynamically.
1172 $ticket_class = is_a( $ticket, 'WPSC_Ticket' )
1173 ? 'WPSC_Individual_Ticket'
1174 : 'WPSC_Individual_Archive_Ticket';
1175
1176 // Assign the ticket.
1177 $ticket_class::$ticket = $ticket;
1178 if ( ! ( $current_user->is_agent && $ticket_class::has_ticket_cap( 'pn' ) ) ) {
1179 wp_send_json_error( __( 'Unauthorized!', 'supportcandy' ), 401 );
1180 }
1181 }
1182
1183 self::file_download( $attachment );
1184 break;
1185
1186 case 'img_editor':
1187 $ticket = new WPSC_Ticket( $attachment->ticket_id );
1188 if ( ! $ticket->id ) {
1189 $ticket = new WPSC_Archive_Ticket( $attachment->ticket_id );
1190 if ( ! $ticket->id ) {
1191 wp_send_json_error( __( 'Bad request!', 'supportcandy' ), 400 );
1192 }
1193 }
1194
1195 if ( is_a( $ticket, 'WPSC_Ticket' ) || is_a( $ticket, 'WPSC_Archive_Ticket' ) ) {
1196
1197 // Determine class dynamically.
1198 $ticket_class = is_a( $ticket, 'WPSC_Ticket' )
1199 ? 'WPSC_Individual_Ticket'
1200 : 'WPSC_Individual_Archive_Ticket';
1201
1202 $ticket_class::$ticket = $ticket;
1203 if (
1204 ! (
1205 ( $current_user->is_agent && $ticket_class::has_ticket_cap( 'view' ) ) ||
1206 $ticket_class::is_customer() ||
1207 ( $ticket->auth_code == $auth_code )
1208 )
1209 ) {
1210 wp_send_json_error( 'Unauthorized!', 401 );
1211 }
1212 self::file_download( $attachment );
1213 } else {
1214 wp_send_json_error( __( 'Invalid ticket type.', 'supportcandy' ), 400 );
1215 }
1216 break;
1217 case 'img_editor_tmp':
1218 self::file_download( $attachment );
1219 }
1220 }
1221 }
1222
1223 /**
1224 * Download attachment
1225 *
1226 * @param WPSC_Attachment $attachment - attachment object.
1227 * @return void
1228 */
1229 public static function file_download( $attachment ) {
1230
1231 // Turn off all output buffering.
1232 while ( ob_get_level() ) {
1233 ob_end_clean();
1234 }
1235
1236 $upload_dir = wp_upload_dir();
1237 $file_path = $upload_dir['basedir'] . $attachment->file_path;
1238 if ( ! file_exists( $file_path ) ) {
1239 echo 'File does not exists!';
1240 exit;
1241 }
1242
1243 // Check whether attachment is of image type.
1244 $attach_settings = get_option( 'wpsc-gs-file-attachments' );
1245 if ( $attachment->is_image && $attach_settings['image-download-behaviour'] == 'open-browser' ) {
1246 header( 'Content-Type: ' . mime_content_type( $file_path ) );
1247 readfile( $file_path ); // phpcs:ignore
1248 exit( 0 );
1249 }
1250
1251 header( 'Content-Description: File Transfer' );
1252 header( 'Cache-Control: public' );
1253 header( 'Content-Type: application/force-download' );
1254 header( 'Content-Disposition: attachment;filename="' . $attachment->name . '"' );
1255 header( 'Content-Length: ' . filesize( $file_path ) );
1256 flush();
1257 readfile( $file_path ); // phpcs:ignore
1258 exit( 0 );
1259 }
1260
1261 /**
1262 * Upload tinymce image file to database
1263 *
1264 * @return void
1265 */
1266 public static function tinymce_upload_file() {
1267
1268 if ( check_ajax_referer( 'wpsc_tinymce_upload_file', '_ajax_nonce', false ) != 1 ) {
1269 wp_send_json_error( 'Unauthorized request!', 401 );
1270 }
1271
1272 $file = isset( $_FILES['file'] ) ? $_FILES['file'] : false; // phpcs:ignore
1273 if ( ! $file ) {
1274 wp_send_json_error( 'File not found!', 400 );
1275 }
1276
1277 $file_settings = get_option( 'wpsc-gs-file-attachments' );
1278 $original_name = sanitize_file_name( $file['name'] );
1279 $filename = time() . '_' . sanitize_file_name( $file['name'] );
1280 $extension = strtolower( pathinfo( $filename, PATHINFO_EXTENSION ) );
1281 $today = new DateTime();
1282 $upload_dir = wp_upload_dir();
1283
1284 // Check file extension.
1285 $img_extensions = array( 'jpg', 'jpeg', 'png', 'gif' );
1286 if ( ! ( in_array( $extension, $img_extensions ) ) ) {
1287 wp_send_json_error( 'Invalid file extension!', 400 );
1288 }
1289
1290 // Allowed file size.
1291 $allowed_file_size = intval( $file_settings['attachments-max-filesize'] ) * 1000000;
1292 if ( ! ( isset( $file['size'] ) && $file['size'] <= $allowed_file_size ) ) {
1293 wp_send_json_error( 'File size exceeds allowed limit!', 400 );
1294 }
1295
1296 $filepath_short = '/wpsc/' . $today->format( 'Y' ) . '/' . $today->format( 'm' ) . '/' . $filename;
1297
1298 // Init attachment data.
1299 $data = array(
1300 'name' => $original_name,
1301 'file_path' => $filepath_short,
1302 'is_image' => 1,
1303 'date_created' => $today->format( 'Y-m-d H:i:s' ),
1304 'is_active' => 0,
1305 'source' => 'img_editor_tmp',
1306 );
1307
1308 // Set up upload overrides.
1309 $upload_overrides = array(
1310 'test_form' => false,
1311 );
1312 $file['name'] = $filename;
1313 add_filter( 'upload_dir', array( __CLASS__, 'wpsc_upload_dir' ) );
1314 $uploaded_file = wp_handle_upload( $file, $upload_overrides );
1315 // Insert record in database.
1316 if ( $uploaded_file && empty( $uploaded_file['error'] ) ) {
1317
1318 $pos = strpos( $uploaded_file['file'], '/wpsc/' );
1319 if ( $pos === false ) {
1320 wp_send_json_error( 'Something went wrong!', 500 );
1321 }
1322 $new_path = substr( $uploaded_file['file'], $pos );
1323 $data['file_path'] = $new_path;
1324 $attachment = self::insert( $data );
1325 if ( ! $attachment->id ) {
1326 wp_send_json_error( 'Something went wrong!', 500 );
1327 }
1328
1329 wp_send_json( array( 'imgURL' => home_url( '/' ) . '?wpsc_attachment=' . $attachment->id ) );
1330
1331 } else {
1332
1333 $error_message = isset( $uploaded_file['error'] ) ? $uploaded_file['error'] : 'Something went wrong!';
1334 wp_send_json_error( $error_message, 500 );
1335 }
1336 }
1337 }
1338 endif;
1339
1340 WPSC_Attachment::init();
1341