assets_url = WPMCS_ASSETS_URL; $this->version = WPMCS_VERSION; $this->token = WPMCS_TOKEN; // Initialize setup $this->init(); } /** * Initialize datas */ public function init() { $this->settings = Utils::get_settings(); $this->credentials = Utils::get_credentials(); $this->config = isset($this->credentials['config']) && !empty($this->credentials['config']) ? $this->credentials['config'] : []; $this->bucketConfig = isset($this->credentials['bucketConfig']) && !empty($this->credentials['bucketConfig']) ? $this->credentials['bucketConfig'] : []; $this->service = isset($this->credentials['service']) && !empty($this->credentials['service']) ? $this->credentials['service'] : []; if (isset($this->bucketConfig['bucket_name'])) { $this->bucket_name = $this->bucketConfig['bucket_name']; } if (isset($this->config['region'])) { $this->region = $this->config['region']; } } /** * Add Item In database * @since 1.0.0 * @param */ public function add( $source_id, $url, $key, $source_path, $meta, $source_type = 'media_library', $is_private = 0 ) { global $wpdb; $item_id = false; $data = array( 'provider' => $this->service, 'region' => $this->region, 'storage' => $this->bucket_name, 'source_id' => $source_id, 'source_path' => $source_path, 'source_type' => $source_type, 'url' => $url, 'key' => $key, 'is_private' => $is_private, 'extra' => maybe_serialize($meta), ); if ($wpdb->insert(Db::get_table_name(), $data)) { $item_id = $wpdb->insert_id; $data['id'] = $item_id; Integration::update_meta($source_id, 'item', $data, false, false, $source_type); Cache::update_item_cache($source_id.'_item_'.$source_type, $data); Counter::add( 'uploaded', $source_type ); } return $item_id; } /** * Get Item From Db */ public function get($source_id, $source_type = 'media_library') { global $wpdb; $item = Cache::get_item_cache($source_id.'_item_'.$source_type, false); if($item === false) { $item = Integration::get_meta($source_id, 'item', false, false, false, $source_type); if($item == false){ $item_table = Db::get_table_name(); $item = $wpdb->get_row("SELECT * FROM ".$item_table." WHERE source_id = $source_id AND source_type='$source_type'", ARRAY_A); if($wpdb->last_error || null === $item || !(isset($item) && !empty($item))) { Cache::update_item_cache($source_id.'_item_'.$source_type, ''); return false; } Integration::update_meta($source_id, 'item', $item, false, false, $source_type); } // Update cache Cache::update_item_cache($source_id.'_item_'.$source_type, $item == false ? '' : $item); } return !empty($item) ? $item : false; } /** * Function to delete item from data base * @since 1.0.0 */ public function delete($source_id, $source_type = 'media_library'){ global $wpdb; if (isset($source_id) && !Utils::is_empty($source_id)) { $rows = $wpdb->delete(Db::get_table_name(), array('source_id' => $source_id, 'source_type' => $source_type)); if ($wpdb->last_error || false === $rows) { return false; } Integration::delete_meta($source_id, 'item', false, $source_type); Cache::delete_item_cache($source_id.'_item_'.$source_type); Counter::remove( 'uploaded', $source_type ); return true; } return false; } /** * Function to update item in data base * @since 1.0.0 */ public function update($source_id, $data, $source_type = 'media_library') { global $wpdb; if (isset($source_id) && !Utils::is_empty($source_id)) { $data['provider'] = $this->service; $data['region'] = $this->region; $data['storage'] = $this->bucket_name; $rows = $wpdb->update(Db::get_table_name(), $data, array('source_id' => $source_id, 'source_type' => $source_type)); if ($wpdb->last_error || false === $rows) { return false; } Integration::delete_meta($source_id, 'item', false, $source_type); Cache::delete_item_cache($source_id.'_item_'.$source_type); // Reset cache $current_data = $this->get($source_id, $source_type); return true; } return false; } /** * Get extra values of item from database * @since 1.0.0 * @param */ public function get_extras($source_id, $field = false, $source_type = 'media_library'){ $data = $this->get($source_id, $source_type); if ($data) { if (isset($data['extra']) && !empty($data['extra'])) { if(!Utils::is_empty($field)) { $extras = Utils::maybe_unserialize($data['extra']); return isset($extras[$field]) && !empty($extras[$field]) ? $extras[$field] : false; } return Utils::maybe_unserialize($data['extra']); } } return false; } /** * Get column of item from database * @since 1.0.0 * @param */ public function get_field($source_id, $field, $source_type = 'media_library'){ $data = $this->get($source_id, $source_type); if ($data) { if (isset($data[$field]) && !empty($data[$field])) { return $data[$field]; } } return false; } /** * Get backup values of item from database * @since 1.0.0 * @param */ public function get_backup($source_id, $source_type = 'media_library'){ $data = $this->get_extras($source_id, false, $source_type); if ($data) { if (isset($data['backup']) && !empty($data['backup'])) { return Utils::maybe_unserialize($data['backup']); } } return false; } /** * Checking Item that is served by provider And Is rewrite URL is enabled * @since 1.0.0 * @param */ public function is_available_from_provider($attachment_id, $check_rewrite = true, $source_type = 'media_library') { $item = $this->get($attachment_id, $source_type); if(Utils::is_empty($item)) { return false; } if ($item['provider'] == $this->service) { if( ($check_rewrite && (isset($this->settings['rewrite_url']) && $this->settings['rewrite_url'])) || !$check_rewrite ) { return true; } } return false; } /** * Get items by paths */ public function get_items_by_source_paths( $paths = [] ) { global $wpdb; $items = []; if (!Utils::is_empty($paths)) { // Ensure paths are properly sanitized and ready for the query $like_conditions = array(); foreach ($paths as $path) { // Prepare the SQL conditions for exact match in source_path and partial match in extras column $like_conditions[] = $wpdb->prepare("(source_path = %s OR extra LIKE %s)", $path, '%' . $wpdb->esc_like($path) . '%'); } // Combine the conditions with OR $where_clause = implode(' OR ', $like_conditions); // Execute the SQL query to fetch source_id instead of source_path $item_table = Db::get_table_name(); $sql = "SELECT DISTINCT source_id, source_type FROM " . $item_table . " WHERE " . $where_clause; $results = $wpdb->get_results($sql, ARRAY_A); if ($wpdb->last_error || Utils::is_empty($results)) { return []; } $source_ids = array(); foreach ($results as $row) { $item = $this->get((int)$row['source_id'], $row['source_type']); if(!Utils::is_empty($item)) { $items[] = $item; } } return $items; } return $items; } /** * Get similar existing files like origin path * @since 1.0.0 */ public function get_similar_files_by_path($path){ global $wpdb; if (isset($path) && !empty($path)) { $item_table = Db::get_table_name(); $results = $wpdb->get_results("SELECT source_path FROM " . $item_table . " WHERE source_path LIKE '$path%'", ARRAY_A); if ($wpdb->last_error || null === $results || !(isset($results) && !empty($results))) { return false; } $source_paths = array(); foreach ($results as $row) { $source_paths[] = $row['source_path']; } return $source_paths; } return false; } /** * Get service url of item from database * @since 1.0.0 * @param */ public function get_url($source_id, $size = 'full', $source_type = 'media_library'){ if ($data = $this->get($source_id, $source_type)) { $extras = $this->get_extras($source_id, false, $source_type) ?: []; $key = ''; $url = ''; switch($size) { case 'full': $key = $data['key']; $url = $data['url']; break; case 'original': if( isset($extras) && !empty($extras) && isset($extras['original']) && !empty($extras['original']) ) { $key = $extras['original']['key']; $url = $extras['original']['url']; } default: if( isset($extras) && !empty($extras) && isset($extras['sizes']) && !empty($extras['sizes']) && isset($extras['sizes'][$size]) && !empty($extras['sizes'][$size]) ) { $key = $extras['sizes'][$size]['key']; $url = $extras['sizes'][$size]['url']; } } if(!empty($key)){ if ( isset($this->settings['enable_presigned']) && $this->settings['enable_presigned'] && isset($this->settings['presigned_expire']) && !empty($this->settings['presigned_expire']) ) { $preSignedUrl = Integration::get_meta( $source_id, 'presigned_url_'.$size, false, false, false, $source_type ); if ($preSignedUrl === false) { $new_url = Service::instance()->get_presigned_url($key); if (!Utils::is_empty($new_url)) { $preSignedUrl = Cdn::may_generate_cdn_url($new_url, $key); $expireMinutes = (int)(isset($this->settings['presigned_expire']) && !empty($this->settings['presigned_expire'])) ? $this->settings['presigned_expire'] : 20; $expireSeconds = $expireMinutes * 60; Integration::update_meta($source_id, 'presigned_url_'.$size, $preSignedUrl, false, $expireSeconds, $source_type); } } return $preSignedUrl; } else { return Cdn::may_generate_cdn_url($url, $key); } } } return false; } /** * Get service path of item from database * @since 1.0.0 * @param */ public function moveToServer($source_id, $size = 'full', $all = false, $source_type = 'media_library') { $server_files = array(); $server_file = false; $upload_dir = wp_get_upload_dir(); $source_id = (int)$source_id; if ($data = $this->get($source_id, $source_type)) { $wpmcsService = Service::instance(); if($all) { if ( isset($data['source_path']) && !empty($data['source_path']) && isset($data['key']) && !empty($data['key']) ) { $file_path = trailingslashit($upload_dir['basedir']) . $data['source_path']; if(file_exists($file_path) || $wpmcsService->object_to_server($data['key'], $file_path)) { $server_files['full'] = $file_path; } } $extras = $this->get_extras($source_id, false, $source_type) ?: []; if (isset($extras['original']) && !empty($extras['original'])) { $original = $extras['original']; if(!empty($original)) { $original_file_path = trailingslashit($upload_dir['basedir']) . $original['source_path']; if(file_exists($original_file_path) || $wpmcsService->object_to_server($original['key'], $original_file_path)) { $server_files['original'] = $original_file_path; } } } if (isset($extras['sizes']) && !empty($extras['sizes'])) { $sizes = $extras['sizes']; foreach($sizes as $sub_size => $sub_file) { if(!empty($sub_file)) { $sub_file_path = trailingslashit($upload_dir['basedir']) . $sub_file['source_path']; if(file_exists($sub_file_path) || $wpmcsService->object_to_server($sub_file['key'], $sub_file_path)) { $server_files[$sub_size] = $sub_file_path; } } } } return !empty($server_files) ? $server_files : false; } else { if($size === 'full') { if ( isset($data['source_path']) && !empty($data['source_path']) && isset($data['key']) && !empty($data['key']) ) { $file_path = trailingslashit($upload_dir['basedir']) . $data['source_path']; if(file_exists($file_path) || $wpmcsService->object_to_server($data['key'], $file_path)) { $server_file = $file_path; } } } else if($size === 'original') { $extras = $this->get_extras($source_id, false, $source_type) ?: []; if (isset($extras['original']) && !empty($extras['original'])) { $original = $extras['original']; if(!empty($original)) { $original_file_path = trailingslashit($upload_dir['basedir']) . $original['source_path']; if(file_exists($original_file_path) || $wpmcsService->object_to_server($original['key'], $original_file_path)) { $server_file = $original_file_path; } } } } else { $extras = $this->get_extras($source_id, false, $source_type) ?: []; if (isset($extras['sizes']) && !empty($extras['sizes'])) { $sizes = $extras['sizes']; if(isset($sizes[$size]) && !empty($sizes[$size])) { $sub_file_path = trailingslashit($upload_dir['basedir']) . $sizes[$size]['source_path']; if(file_exists($sub_file_path) || $wpmcsService->object_to_server($sizes[$size]['key'], $sub_file_path)) { $server_file = $sub_file_path; } } } } return $server_file; } } return false; } /** * Get service path of item from database by source url * @since 1.0.0 * @param */ public function moveToServerBySourcePath($source_id, $file, $source_type = 'media_library'){ $server_files = array(); $server_file = false; $upload_dir = wp_get_upload_dir(); $source_id = (int)$source_id; if ($data = $this->get($source_id, $source_type)) { $source_path = Utils::get_attachment_source_path($file); if( isset($data['source_path']) && !empty($data['source_path']) && $data['source_path'] == $source_path ) { $file_path = trailingslashit($upload_dir['basedir']) . $data['source_path']; if(file_exists($file_path) || Service::instance()->object_to_server($data['key'], $file_path)) { return true; } } else { $sizes = $this->get_extras($source_id, 'sizes', $source_type) ?: []; foreach($sizes as $sub_size => $sub_file) { if(!empty($sub_file) && $sub_file['source_path'] == $source_path) { $sub_file_path = trailingslashit($upload_dir['basedir']) . $sub_file['source_path']; if(file_exists($sub_file_path) || Service::instance()->object_to_server($sub_file['key'], $sub_file_path)) { return true; } } } } } return false; } /** * Delete media item */ public function delete_attachments_by_item($item, $delete_backup = true) { $upload_dir = wp_get_upload_dir(); if (isset($item['extra']) && !empty($item['extra'])) { $extras = Utils::maybe_unserialize($item['extra']); if ( isset($extras) && !empty($extras) && isset($extras['sizes']) && !empty($extras['sizes']) ) { foreach ($extras['sizes'] as $sub_image) { if (isset($sub_image['key']) && !empty($sub_image['key'])) { Service::instance()->deleteSingle($sub_image['key']); } } } if ( isset($extras) && !empty($extras) && isset($extras['original']) && !empty($extras['original']) ) { Service::instance()->deleteSingle($extras['original']['key']); } if ( isset($extras) && !empty($extras) && isset($extras['backup']) && !empty($extras['backup']) && $delete_backup ) { $backup = Utils::maybe_unserialize($extras['backup']); if (isset($backup) && !empty($backup)) { $this->delete_attachments_by_item($backup, false); } } } if (isset($item['key']) && !empty($item['key'])) { Service::instance()->deleteSingle($item['key']); } } /** * Function to remove media from server by id * @since 1.0.0 * */ public function may_be_delete_server_files_by_id($attachment_id, $source_type = 'media_library', $delete_main_file=false, $delete_backup = false) { $item = $this->get($attachment_id, $source_type); if(Utils::is_empty($item)) { return false; } if( !( isset($this->settings['remove_from_server']) && $this->settings['remove_from_server'] ) ) { return false; } if (isset($item['extra']) && !empty($item['extra'])) { $extras = Utils::maybe_unserialize($item['extra']); if ( isset($extras) && !empty($extras) && isset($extras['backup']) && !empty($extras['backup']) && $delete_backup ) { $backup = Utils::maybe_unserialize($extras['backup']); if (isset($backup) && !empty($backup)) { $this->may_be_delete_server_files_by_item($backup, $delete_main_file); } } } $this->may_be_delete_server_files_by_item($item, $delete_main_file, $delete_backup); return true; } /** * Function to remove media from server by item */ public function may_be_delete_server_files_by_item( $item, $delete_main_file=false ) { if(Utils::is_empty($item)) { return false; } if( !( isset($this->settings['remove_from_server']) && $this->settings['remove_from_server'] ) ) { return false; } $upload_dir = wp_get_upload_dir(); $has_original = false; $file_path = trailingslashit($upload_dir['basedir']) . $item['source_path']; if (isset($item['extra']) && !empty($item['extra'])) { $extras = Utils::maybe_unserialize($item['extra']); if ( isset($extras) && !empty($extras) && isset($extras['sizes']) && !empty($extras['sizes']) ) { foreach ($extras['sizes'] as $sub_image) { if (isset($sub_image['source_path']) && !empty($sub_image['source_path'])) { $file = trailingslashit($upload_dir['basedir']) . $sub_image['source_path']; if(file_exists($file)) { wp_delete_file($file); } } } } if ( isset($extras) && !empty($extras) && isset($extras['original']) && !empty($extras['original']) ) { $has_original = true; $file = trailingslashit($upload_dir['basedir']).$extras['original']['source_path']; if(file_exists($file) && $delete_main_file) { wp_delete_file($file); } } } if(file_exists($file_path)) { if ($has_original || (!$has_original && $delete_main_file)) { wp_delete_file($file_path); } } return true; } /** * Ensures only one instance of Class is loaded or can be loaded. * * @return Item Class instance * @since 1.0.0 * @static */ public static function instance(){ if (is_null(self::$instance)) { self::$instance = new self(); } return self::$instance; } }