From 976c0c75e28c801c8ad248eeffbec69236c4e0e6 Mon Sep 17 00:00:00 2001 From: Mykyta Synelnikov Date: Mon, 7 Jul 2025 13:04:19 +0300 Subject: [PATCH] Add Extensions_Updater class for handling extension updates Introduced a new `Extensions_Updater` class to manage extension update processes, including version checks and file execution. Added a corresponding `extension_updater` method in `class-admin.php` to initialize and manage updater instances based on provided data. --- includes/admin/class-admin.php | 17 +++ includes/admin/class-extensions-updater.php | 124 ++++++++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 includes/admin/class-extensions-updater.php diff --git a/includes/admin/class-admin.php b/includes/admin/class-admin.php index 05995bad..526ea925 100644 --- a/includes/admin/class-admin.php +++ b/includes/admin/class-admin.php @@ -2100,5 +2100,22 @@ if ( ! class_exists( 'um\admin\Admin' ) ) { } return UM()->classes['um\admin\users_columns']; } + + /** + * @since 2.10.6 + * + * @param bool|array $data + * @return null|Extensions_Updater + */ + public function extension_updater( $data = false ) { + if ( empty( $data['slug'] ) ) { + return null; + } + $class_index = 'um\admin\extensions_updater_' . $data['slug']; + if ( ! isset( UM()->classes[ $class_index ] ) || empty( UM()->classes[ $class_index ] ) ) { + UM()->classes[ $class_index ] = new Extensions_Updater( $data ); + } + return UM()->classes[ $class_index ]; + } } } diff --git a/includes/admin/class-extensions-updater.php b/includes/admin/class-extensions-updater.php new file mode 100644 index 00000000..11d3aa40 --- /dev/null +++ b/includes/admin/class-extensions-updater.php @@ -0,0 +1,124 @@ +updater_data = wp_parse_args( + $args, + array( + 'slug' => '', + 'version' => '0.0.0', + 'path' => '', + ) + ); + + add_action( 'admin_init', array( $this, 'maybe_run_updater' ) ); + } + + /** + * Maybe run upgrade if needed. + */ + public function maybe_run_updater() { + $last_version_upgrade = $this->get_last_version_upgrade(); + if ( ! empty( $last_version_upgrade ) && version_compare( $last_version_upgrade, $this->updater_data['version'], '>=' ) ) { + // Don't need update. + return; + } + + $packages = $this->get_packages(); + if ( ! empty( $packages ) ) { + $packages_dir = $this->get_packages_dir(); + foreach ( $packages as $package_version ) { + if ( version_compare( $package_version, $last_version_upgrade, '<=' ) ) { + continue; + } + + if ( version_compare( $package_version, $this->updater_data['version'], '>' ) ) { + continue; + } + + $file_path = $packages_dir . $package_version . '.php'; + if ( ! file_exists( $file_path ) ) { + continue; + } + + include_once $file_path; + $this->set_last_version_upgrade( $package_version ); + } + } + + $this->set_last_version_upgrade( $this->updater_data['version'] ); + } + + /** + * Get packages list, based on the files in packages dir. + */ + private function get_packages() { + $packages = array(); + + $handle = opendir( $this->get_packages_dir() ); + // phpcs:ignore Generic.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition, WordPress.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition -- reading folder's content here + while ( false !== ( $filename = readdir( $handle ) ) ) { + if ( '.' !== $filename && '..' !== $filename ) { + $packages[] = preg_replace( '/(.*?)\.php/i', '$1', $filename ); + } + } + closedir( $handle ); + + usort( + $packages, + static function ( $a, $b ) { + return version_compare( $a, $b ); + } + ); + + return $packages; + } + + /** + * Retrieve the directory path where packages are stored for updates. + * + * @return string The normalized path to the packages' directory. + */ + private function get_packages_dir() { + return wp_normalize_path( $this->updater_data['path'] . 'includes/updates/' ); + } + + /** + * Gets the last version upgrade from options. + * + * @return string The last version upgrade. + */ + private function get_last_version_upgrade() { + return get_option( 'um_' . $this->updater_data['slug'] . '_last_version_upgrade', '0.0.0' ); + } + + /** + * Set the last version upgrade for the updater. + * + * @param string $version The version to set as the last upgrade version. + */ + private function set_last_version_upgrade( $version ) { + update_option( 'um_' . $this->updater_data['slug'] . '_last_version_upgrade', $version ); + } +}