diff --git a/changelog.txt b/changelog.txt index 7d0944286..098c75186 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,4 +1,8 @@ == Changelog == += 4.0.2 = +* FIX - in multisite network, deleting site can potentially remove WP-Stateless tables from another site. +* COMPATIBILITY - Gravity Forms Compatibility updated for the newest Gravity Forms version. + = 4.0.1 = * FIX - improvements to Data Optimization process. * FIX - Data Optimization fixed for multisite environment. diff --git a/changes.md b/changes.md index 8cd4f42f2..f793a0fc6 100644 --- a/changes.md +++ b/changes.md @@ -1,3 +1,7 @@ +#### 4.0.2 +* FIX - in multisite network, deleting site can potentially remove WP-Stateless tables from another site. +* COMPATIBILITY - Gravity Forms Compatibility updated for the newest Gravity Forms version. + #### 4.0.1 * FIX - improvements to Data Optimization process. * FIX - Data Optimization fixed for multisite environment. diff --git a/lib/classes/class-bootstrap.php b/lib/classes/class-bootstrap.php index 39c30006c..dd35f4b4a 100644 --- a/lib/classes/class-bootstrap.php +++ b/lib/classes/class-bootstrap.php @@ -595,6 +595,18 @@ public function get_gs_host($sm = array()) { return apply_filters('get_gs_host', $image_host, $image_host, $sm['bucket'], $is_ssl, $sm); } + /** + * Return gs:// path. + * + * @param array $sm + * @return mixed|void + */ + public function get_gs_path() { + $path = 'gs://' . $this->get('sm.bucket'); + + return apply_filters('get_gs_path', $path); + } + /** * Filter for wp_stateless_bucket_link if custom domain is set. * It's get attachment url and remove "storage.googleapis.com" from url. @@ -1748,11 +1760,7 @@ public function create_sync_db($force = false) { * @param $old_site */ public function wp_delete_site($old_site) { - switch_to_blog($old_site->id); - - ud_stateless_db()->clear_db(); - - restore_current_blog(); + ud_stateless_db()->clear_db($old_site->id); } /** @@ -2090,6 +2098,20 @@ public function send_admin_email($subject, $message, $email = '') { wp_mail( $admin_email, $subject, $message); } + + /** + * Check if we are in specific mode + * + * @param string|array $mode + * @return bool + */ + public function is_mode($mode) { + if ( !is_array($mode) ) { + $mode = [$mode]; + } + + return in_array($this->get('sm.mode'), $mode); + } } } } diff --git a/lib/classes/class-db.php b/lib/classes/class-db.php index d48a30ad2..445225ae1 100644 --- a/lib/classes/class-db.php +++ b/lib/classes/class-db.php @@ -202,10 +202,25 @@ public function create_db() { /** * Remove custom DB table on plugin uninstall + * + * @param int $site_id */ - public function clear_db() { - $sql = "DROP TABLE IF EXISTS $this->files, $this->file_sizes, $this->file_meta, $this->sm_sync;"; + public function clear_db($site_id) { + switch_to_blog($id); + + $tables = array( + $this->wpdb->prefix . 'files', + $this->wpdb->prefix . 'files_sizes', + $this->wpdb->prefix . 'file_meta', + $this->wpdb->prefix . 'sm_sync', + ); + + $tables = implode(', ', $tables); + + $sql = "DROP TABLE IF EXISTS $tables;"; $this->wpdb->query($sql); + + restore_current_blog(); } /** diff --git a/lib/classes/class-sync-non-media.php b/lib/classes/class-sync-non-media.php index 9e7cdcb4f..075f669e6 100644 --- a/lib/classes/class-sync-non-media.php +++ b/lib/classes/class-sync-non-media.php @@ -34,6 +34,7 @@ public function __construct() { add_action('sm:sync::moveFile', array($this, 'move_file'), 10, 2); add_action('sm:sync::deleteFile', array($this, 'delete_file')); add_action('sm:sync::deleteFiles', array($this, 'delete_files')); + add_action('sm:sync::unregister_file', array($this, 'unregister_file'), 10, 1); } /** @@ -78,6 +79,7 @@ public function sync_file($name, $absolutePath, $forced = false, $args = array() 'skip_db' => false, 'manual_sync' => false, 'remove_from_queue' => false, // removes entry from queue table if both file is missing. + 'name_with_root' => true, )); if ($this->queue_is_exists($name, 'synced') && !$forced) { @@ -113,7 +115,7 @@ public function sync_file($name, $absolutePath, $forced = false, $args = array() if ($sm_mode == 'stateless' && !wp_doing_ajax()) { global $gs_client; - $gs_name = apply_filters('wp_stateless_file_name', $name, true); + $gs_name = apply_filters('wp_stateless_file_name', $name, $args['name_with_root']); //Bucket $bucket = ud_get_stateless_media()->get('sm.bucket'); @@ -132,6 +134,7 @@ public function sync_file($name, $absolutePath, $forced = false, $args = array() ), 'is_webp' => '', )); + $args = apply_filters('wp_stateless_add_media_args', $args); /** @@ -408,6 +411,19 @@ public function get_gs_client() { return $this->client; } + + /** + * Remove file from DB after file deletion. + * @param string $file + */ + public function unregister_file($file) { + $file = str_replace( ud_get_stateless_media()->get_gs_path(), '', $file); + $file = str_replace( ud_get_stateless_media()->get_gs_host(), '', $file); + + $file = trim($file, '/'); + + $this->queue_remove_file($file); + } } } } diff --git a/lib/classes/compatibility/gravity-forms.php b/lib/classes/compatibility/gravity-forms.php index e9cacbd2e..156de199a 100644 --- a/lib/classes/compatibility/gravity-forms.php +++ b/lib/classes/compatibility/gravity-forms.php @@ -32,6 +32,8 @@ public function module_init($sm) { $this->plugin_version = \GFForms::$version; } add_filter('gform_save_field_value', array($this, 'gform_save_field_value'), 10, 5); + add_filter('gform_upload_path', array($this, 'gf_upload_path'), 10, 1); + add_filter('stateless_skip_cache_busting', array($this, 'skip_cache_busting'), 10, 2); do_action('sm:sync::register_dir', '/gravity_forms/'); @@ -39,6 +41,24 @@ public function module_init($sm) { add_action('gform_file_path_pre_delete_file', array($this, 'gform_file_path_pre_delete_file'), 10, 2); } + /** + * For 'stateless' mode we use upload path and URL without wildcards. + * @param $upload_path + * @return mixed + */ + public function gf_upload_path($upload_path) { + if ( !ud_get_stateless_media()->is_mode('stateless') ) { + return $upload_path; + } + + $dir = wp_upload_dir(); + + $upload_path['path'] = ud_get_stateless_media()->get_gs_path() . str_replace($dir['basedir'], '', $upload_path['path']); + $upload_path['url'] = ud_get_stateless_media()->get_gs_host() . str_replace($dir['baseurl'], '', $upload_path['url']); + + return $upload_path; + } + /** * On gform save field value sync file to GCS and alter the file url to GCS link. * @param $value @@ -55,7 +75,9 @@ public function gform_save_field_value($value, $lead, $field, $form, $input_id) $this->plugin_version = \GFForms::$version; } + $is_stateless = ud_get_stateless_media()->is_mode('stateless'); $type = \GFFormsModel::get_input_type($field); + if ($type == 'fileupload') { $dir = wp_upload_dir(); @@ -71,10 +93,13 @@ public function gform_save_field_value($value, $lead, $field, $form, $input_id) if ($position !== false) { $name = substr($v, $position); - $absolutePath = $dir['basedir'] . '/' . $name; + $path = $is_stateless ? ud_get_stateless_media()->get_gs_path() : $dir['basedir']; + $absolutePath = $path . '/' . $name; + $name = apply_filters('wp_stateless_file_name', $name, 0); + // doing sync - do_action('sm:sync::syncFile', $name, $absolutePath); + do_action( 'sm:sync::syncFile', $name, $absolutePath, false, $is_stateless ? array('name_with_root' => false) : array() ); $value[$k] = ud_get_stateless_media()->get_gs_host() . '/' . $name; // Todo add filter. } @@ -86,7 +111,7 @@ public function gform_save_field_value($value, $lead, $field, $form, $input_id) $value = array_pop($value); } } else if ($type == 'post_image') { - add_action('gform_after_create_post', function ($post_id, $lead, $form) use ($value, $field) { + add_action('gform_after_create_post', function ($post_id, $lead, $form) use ($value, $field, $is_stateless) { global $wpdb; $dir = wp_upload_dir(); $lead_detail_id = $lead['id']; @@ -100,9 +125,11 @@ public function gform_save_field_value($value, $lead, $field, $form, $input_id) $name = rgar($arr_name, 0); // Removed |:| from end of the url. // doing sync - $absolutePath = $dir['basedir'] . '/' . $name; + $path = $is_stateless ? ud_get_stateless_media()->get_gs_path() : $dir['basedir']; + $absolutePath = $path . '/' . $name; $name = apply_filters('wp_stateless_file_name', $name, 0); - do_action('sm:sync::syncFile', $name, $absolutePath); + + do_action( 'sm:sync::syncFile', $name, $absolutePath, false, $is_stateless ? array('name_with_root' => false) : array() ); $value = ud_get_stateless_media()->get_gs_host() . '/' . $name; // Todo add filter. @@ -240,10 +267,12 @@ public function gform_file_path_pre_delete_file($file_path, $url) { $client = ud_get_stateless_media()->get_client(); if (!is_wp_error($client)) { - $client->remove_media(trim($gs_name, '/')); + $client->remove_media(trim($gs_name, '/'), '', false); } } + do_action('sm:sync::unregister_file', $url); + return $file_path; } diff --git a/readme.txt b/readme.txt index c67833a65..e7211ce9d 100644 --- a/readme.txt +++ b/readme.txt @@ -5,8 +5,8 @@ Tags: google cloud, google cloud storage, cdn, uploads, backup License: GPLv2 or later Requires PHP: 8.0 Requires at least: 5.0 -Tested up to: 6.5.0 -Stable tag: 4.0.1 +Tested up to: 6.5.2 +Stable tag: 4.0.2 Upload and serve your WordPress media files from Google Cloud Storage. @@ -121,6 +121,10 @@ Before upgrading to WP-Stateless 3.2.0, please, make sure you use PHP 7.2 or abo Before upgrading to WP-Stateless 3.0, please, make sure you tested it on your development environment. == Changelog == += 4.0.2 = +* FIX - in multisite network, deleting site can potentially remove WP-Stateless tables from another site. +* COMPATIBILITY - Gravity Forms Compatibility updated for the newest Gravity Forms version. + = 4.0.1 = * FIX - improvements to Data Optimization process. * FIX - Data Optimization fixed for multisite environment. diff --git a/wp-stateless-media.php b/wp-stateless-media.php index 93eeb043a..fad9b328c 100644 --- a/wp-stateless-media.php +++ b/wp-stateless-media.php @@ -4,7 +4,7 @@ * Plugin URI: https://stateless.udx.io/ * Description: Upload and serve your WordPress media files from Google Cloud Storage. * Author: UDX - * Version: 4.0.1 + * Version: 4.0.2 * Text Domain: stateless-media * Author URI: https://udx.io * License: GPLv2 or later