_connectpthread_setschedparam__nss_hosts_lookup_IO_putc__recvfrom_chk_IO_file_initcallrpc_IO_str_init_readonly__bsd_getpgrp__strtoll_lrealpath_IO_iter_file__wunderflow__key_encryptsession_pk_LOCALsrandsched_getcpusemgetwaitidendusershellwcsdup__sigaddsetqecvt_rrtime__readlinkat_chkxdr_wrapstringauthunix_create__wcsncpy_chk__isoc99_vsscanfwcschrnulstrfmonepoll_createreadaheadendttyentrexec_affanotify_init__sched_get_priority_minif_nameindex__xmknod__progname_full__ctype32_tolowersrandom_rreadlinkatgethostbyname2_rgetaliasbyname_r_IO_file_overflowulimitendspentwcstouq__strtoull_lposix_spawnattr_getsigmaskbindtextdomaindelete_moduleisprintmcheck_pedanticpthread_attr_getscopesigreturn__fread_chk_rtld_globalpmap_getportsvcerr_decodexdr_rejected_replypthread_condattr_destroyargp_parseasctimeclnt_spcreateerror__getlogin_r_chk__key_gendes_LOCALgetusershell__libc_current_sigrtmaxposix_spawnattr_setschedparamwait3inet_nsap_addrgetprotoent_rdrand48inotify_add_watchrecvmsgrresvport_afsvc_exitsetfsuid__argz_stringify_IO_wfile_jumpsendfsentgetrusage__gmtime_riruserok_afreaddir_rfreopenremqueprlimit64__wcsftime_lwait4strcmp__finitefwcsnrtombspreadvbsd_signal__ctype_get_mb_cur_max__iswctypereaddirsigblockeventfd_IO_putssetrpcent__progname_IO_free_backup_areacreatsetnetentwcschr__strxfrm_lposix_spawn_file_actions_addcloseargp_err_exit_statusgetgrgid_r__vfwprintf_chkunshare_seterr_reply__recv_chk_IO_getline_info__fwriting__finitel_itoa_lower_digitsinet6_opt_finishpthread_cond_init_IO_default_xsputn__wcstof_l__libc_forkmallwatch__wcsncasecmp_ladvance_IO_fsetposwcsstr__sysv_signal_IO_proc_closewcsspnhdestroyargz_appendwcswcsfstatfs64_obstack_allocated_psetgidposix_spawnattr_setflags__sched_getparamffsll_IO_link_infreeifaddrs_IO_marker_differencexdrrec_endofrecord_IO_peekc_lockedmcheck_check_allunlinkseed48__wcscasecmp_l_IO_str_pbackfailwcstoulposix_fadvise64__fwritableisasciiputenvfgetws_unlockedxdr_key_netstarg_IO_feofgnu_dev_majorregerror__rcmd_errstrnl_langinfo__strncat_chk__libc_calloc__finitegetpriority__sysctlhsearch_rswapcontextstimealphasortrecvfrom_sys_nerr__vdso_clock_gettime_IO_free_wbackup_area_IO_initkey_secretkey_is_setpsiginfo__isoc99_vfwscanf__strcasecmpversionsort64closelogpthread_cond_timedwaitsvcauthdes_statsmrand48_r__nss_next2__libc_clntudp_bufcreate__strcoll_l_IO_unsave_wmarkersnetname2host_res_hconfmblen__write__printf_chkftello_IO_ftell_nss_files_parse_spentpclose__libc_mallinfo_IO_iter_end__isinffiswalphaqgcvt_IO_flush_all_linebufferedgetcwdmalloc_info__isupper_lwcscoll__iswalpha_l__sigdelsetwordfree__iswupper_l__isoc99_scanf__duplocalegetaliasent_r_IO_switch_to_main_wget_areafattach__isinflsvc_sendreplyvwprintf__isctype__ctype_tolower_loc__wcsxfrm_ltmpnamfgetwc_unlockedllseekstrptime_lsigorsetgetutid_r__nss_hosts_lookup2eaccessxdr_long__fxstatat64__getpagesizeiswdigitverr__nss_configure_lookupargz_create_sepgetdate_errgethostbyname__towctransgetloadavgiscntrlislowergetprotobynumber__wuflowsvcudp_bufcreate_IO_un_linkstrcatxdrrec_createvwarnx_dl_open_hook__flbffchownstrncmpqfcvtwcsftime_IO_setb__libc_freetcdrainopen_memstreampthread_exitsys_sigabbrevpthread_cond_broadcastfchownatrecvldexplposix_spawnattr_init_IO_sungetwcisxdigit__tzname_IO_default_uflowvwarn_IO_file_read__strtold_internalsigpending__internal_endnetgrentrewinddir__fxstat64xdr_cryptkeyarg__libc_sa_lenin6addr_anychrootstrcpygetprotoent__timezone_IO_proc_openquery_modulesvcerr_weakauth_mcount__confstr_chkmbtowc__clonescalbnlgetgrnamputpmsgversionsortsockatmark__nss_passwd_lookup__nss_disable_nscdmalloc_trimmbsnrtowcsfstatvfs64wcwidthstrrchrclnt_perrorregister_printf_type_IO_fwrite__pread_chkstrxfrmscalbnffputwc_unlockedglob__cxa_atexitgetnameinfowcsrtombsprintf_sizecfree__waitxdr_keystatusgetpwnam_rnrand48_r_IO_file_doallocateteegetdatmp_name'] ); if ( is_wp_error( $result ) ) { $file['error'] = $result->get_error_message(); } return $file; } /** * Get File Type Handler * * Initialize the proper file type handler according to the file extension * and assign it to the file type handlers array. * * @since 3.3.0 * * @param string|null $file_extension - file extension * @return File_Type_Base[]|File_Type_Base */ public function get_file_type_handlers( $file_extension = null ) { return self::get_items( $this->file_type_handlers, $file_extension ); } /** * Create Temp File * * Create a random temporary file. * * @since 3.3.0 * * @param string $file_content * @param string $file_name * @return string|\WP_Error */ public function create_temp_file( $file_content, $file_name ) { $temp_filename = $this->create_unique_dir() . $file_name; file_put_contents( $temp_filename, $file_content ); // phpcs:ignore return $temp_filename; } /** * Get Temp Directory * * Get the temporary files directory path. If the directory does not exist, this method creates it. * * @since 3.3.0 * * @return string $temp_dir */ public function get_temp_dir() { if ( ! $this->temp_dir ) { $wp_upload_dir = wp_upload_dir(); $this->temp_dir = implode( DIRECTORY_SEPARATOR, [ $wp_upload_dir['basedir'], 'elementor', 'tmp' ] ) . DIRECTORY_SEPARATOR; if ( ! is_dir( $this->temp_dir ) ) { wp_mkdir_p( $this->temp_dir ); } } return $this->temp_dir; } /** * Create Unique Temp Dir * * Create a unique temporary directory * * @since 3.3.0 * * @return string the new directory path */ public function create_unique_dir() { $unique_dir_path = $this->get_temp_dir() . uniqid() . DIRECTORY_SEPARATOR; wp_mkdir_p( $unique_dir_path ); return $unique_dir_path; } /** * Are Unfiltered Uploads Enabled * * Checks if the user allowed uploading unfiltered files. * * @since 3.3.0 * * @return bool */ private function are_unfiltered_uploads_enabled() { if ( ! $this->are_unfiltered_files_enabled ) { $this->are_unfiltered_files_enabled = ! ! get_option( self::UNFILTERED_FILE_UPLOADS_KEY ); } return $this->are_unfiltered_files_enabled; } /** * Add File Extension To Allowed Extensions List * * @since 3.3.0 * * @param string $file_type */ private function add_file_extension_to_allowed_extensions_list( $file_type ) { $file_handler = $this->file_type_handlers[ $file_type ]; $file_extension = $file_handler->get_file_extension(); // Only add the file extension to the list if it doesn't already exist in it. if ( ! in_array( $file_extension, $this->allowed_file_extensions, true ) ) { $this->allowed_file_extensions[] = $file_extension; } } /** * Save Base64 as File * * Saves a Base64 string as a .tmp file in Elementor's temporary files directory. * * @since 3.3.0 * * @param $file * @return array|\WP_Error */ private function save_base64_to_tmp_file( $file ) { $file_content = base64_decode( $file['fileData'] ); // phpcs:ignore // If the decode fails if ( ! $file_content ) { return new \WP_Error( 'file_error', self::INVALID_FILE_CONTENT ); } $temp_filename = $this->create_temp_file( $file_content, $file['fileName'] ); if ( is_wp_error( $temp_filename ) ) { return $temp_filename; } $new_file_array = [ // the original uploaded file name 'name' => $file['fileName'], // The path to the temporary file 'tmp_name' => $temp_filename, ]; return $new_file_array; } /** * is_elementor_wp_media_upload * * @since 3.3.0 * * @return bool */ private function is_elementor_wp_media_upload() { return isset( $_POST['elementor_wp_media_upload'] ); // phpcs:ignore } /** * Validate File * * @since 3.3.0 * * @param string $file_path * @param array $file_extensions Optional * @return bool|\WP_Error * */ private function validate_file( $file_path, $file_extensions = [] ) { $file_extension = pathinfo( $file_path, PATHINFO_EXTENSION ); $allowed_file_extensions = $this->get_allowed_file_extensions(); if ( $file_extensions ) { $allowed_file_extensions = array_intersect( $allowed_file_extensions, $file_extensions ); } // Check if the file type (extension) is in the allowed extensions list. If it is a non-standard file type (not // enabled by default in WordPress) and unfiltered file uploads are not enabled, it will not be in the allowed // file extensions list. if ( ! in_array( $file_extension, $allowed_file_extensions, true ) ) { return new \WP_Error( Exceptions::FORBIDDEN, 'Uploading this file type is not allowed.' ); } $file_type_handler = $this->get_file_type_handlers( $file_extension ); // If Elementor does not have a handler for this file type, don't block it. if ( ! $file_type_handler ) { return true; } // Here is each file type handler's chance to run its own specific validations return $file_type_handler->validate_file( $file_path ); } /** * Remove File Or Directory * * Directory is deleted recursively with all of its contents (subdirectories and files). * * @since 3.3.0 * * @param string $path */ public function remove_file_or_dir( $path ) { if ( is_dir( $path ) ) { $this->remove_directory_with_files( $path ); } else { unlink( $path ); } } /** * Remove Directory with Files * * @since 3.3.0 * * @param string $dir * @return bool */ private function remove_directory_with_files( $dir ) { $dir_iterator = new \RecursiveDirectoryIterator( $dir, \RecursiveDirectoryIterator::SKIP_DOTS ); foreach ( new \RecursiveIteratorIterator( $dir_iterator, \RecursiveIteratorIterator::CHILD_FIRST ) as $name => $item ) { if ( is_dir( $name ) ) { rmdir( $name ); } else { unlink( $name ); } } return rmdir( $dir ); } /** * Get Allowed File Extensions * * Retrieve an array containing the list of file extensions allowed for upload. * * @since 3.3.0 * * @return array file extension/s */ private function get_allowed_file_extensions() { if ( ! $this->allowed_file_extensions ) { $this->allowed_file_extensions = array_keys( get_allowed_mime_types() ); foreach ( $this->get_file_type_handlers() as $file_type => $handler ) { if ( $handler->is_upload_allowed() ) { // Add the file extension to the allowed extensions list only if unfiltered files upload is enabled. $this->add_file_extension_to_allowed_extensions_list( $file_type ); } } } return $this->allowed_file_extensions; } public function __construct() { $this->register_file_types(); add_filter( 'wp_handle_upload_prefilter', [ $this, 'handle_elementor_wp_media_upload' ] ); } }