'Version')); $this->version = $plugin_data['Version']; } /** * Sets up the Advanced Media Offloader * * @since 1.0.0 * * @return void */ public function initialize() { // Define constants. $this->define('ADVMO', true); $this->define('ADVMO_PATH', plugin_dir_path(__FILE__)); $this->define('ADVMO_URL', plugin_dir_url(__FILE__)); $this->define('ADVMO_BASENAME', plugin_basename(__FILE__)); $this->define('ADVMO_VERSION', $this->version); $this->define('ADVMO_API_VERSION', 1); // Register activation hook. register_activation_hook(__FILE__, array($this, 'plugin_activated')); // Register deactivation hook. register_deactivation_hook(__FILE__, array($this, 'plugin_deactivated')); // Set up container $this->setup_container(); // Include files and setup WordPress hooks $this->include_files(); $this->setup_hooks(); } private function setup_container() { // Include autoloader if (file_exists(ADVMO_PATH . 'vendor/scoper-autoload.php')) { require_once ADVMO_PATH . 'vendor/scoper-autoload.php'; } elseif (file_exists(ADVMO_PATH . 'vendor/autoload.php')) { require_once ADVMO_PATH . 'vendor/autoload.php'; } $this->container = new \Advanced_Media_Offloader\Core\Container(); $this->container->register('cloud_provider_factory', function ($c) { return new \Advanced_Media_Offloader\Factories\CloudProviderFactory(); }); // Register core services $this->container->register('cloud_provider', function ($c) { $cloud_provider_key = advmo_get_cloud_provider_key(); if (empty($cloud_provider_key)) { return null; } if ($c->has('cloud_provider_factory')) { $cloud_provider_factory = $c->get('cloud_provider_factory'); return $cloud_provider_factory::create($cloud_provider_key); } return null; }); $this->container->register('offloader', function ($c) { if ($c->has('cloud_provider') && $c->get('cloud_provider') !== null) { return \Advanced_Media_Offloader\Offloader::get_instance($c->get('cloud_provider')); } return null; }); $this->container->register('settings_page', function ($c) { return \Advanced_Media_Offloader\Admin\GeneralSettings::create($c->get('cloud_provider_factory')); }); $this->container->register('media_overview_page', function ($c) { return \Advanced_Media_Offloader\Admin\MediaOverview::getInstance(); }); $this->container->register('support_page', function ($c) { return \Advanced_Media_Offloader\Admin\SupportPage::getInstance(); }); $this->container->register('bulk_offload_handler', function ($c) { return \Advanced_Media_Offloader\BulkOffloadHandler::get_instance(); }); } private function setup_hooks() { // This guard covers metadata left by earlier offloads, so it must run // even when no cloud provider is currently selected. if (class_exists(\Advanced_Media_Offloader\Observers\MissingImageSubsizesObserver::class)) { (new \Advanced_Media_Offloader\Observers\MissingImageSubsizesObserver())->register(); } # check if AWS SDK is loaded if (!class_exists(WPFitter\Aws\S3\S3Client::class)) { // Show admin notice if AWS SDK is missing. add_action('admin_notices', function () { $this->notice(__('AWS SDK for PHP is required to use Advanced Media Offloader. Please install it via Composer.', 'advanced-media-offloader'), 'error'); }); return; } # Include admin if needed if (is_admin()) { $this->container->get('settings_page'); // Initialize settings $this->container->get('media_overview_page'); // Initialize media overview $this->container->get('support_page'); // Initialize the support page new \Advanced_Media_Offloader\Admin\Observers\CurrentScreen(); \Advanced_Media_Offloader\Admin\Observers\WelcomeNotice::getInstance(); # Add link to the settings page in the plugins list add_filter('plugin_action_links_' . plugin_basename(__FILE__), [$this, 'plugin_action_links']); } # Initialize offloader if cloud provider is configured if ($this->container->has('offloader') && $this->container->get('offloader') !== null) { $this->container->get('offloader')->initializeHooks(); } # Initialize bulk offload handler $this->container->get('bulk_offload_handler'); # Register WP CLI commands $this->register_cli_commands(); } private function include_files() { # include Utility Functions include_once ADVMO_PATH . 'utility-functions.php'; } /** * Register WP CLI commands if WP CLI is available. * * @return void */ private function register_cli_commands() { if (defined('WP_CLI') && WP_CLI) { WP_CLI::add_command('advmo offload', 'Advanced_Media_Offloader\\CLI\\OffloadCommand'); } } public function plugin_action_links($links) { $settings_page_link = '' . __('Settings', 'advanced-media-offloader') . ''; array_unshift($links, $settings_page_link); // Append Donate link (non-intrusive), gated by filter if (apply_filters('advmo_show_donate_links', true)) { $donate_url = add_query_arg(array( 'utm_source' => 'wp-plugin', 'utm_medium' => 'plugins-list', 'utm_campaign' => 'advanced-media-offloader', 'utm_content' => 'plugin-row-donate', ), 'https://buymeacoffee.com/wpfitter'); $donate_link = '' . esc_html__('Donate', 'advanced-media-offloader') . ''; $links[] = $donate_link; } return $links; } /** * Plugin Activation Hook * * @since 1.0.0 */ public function plugin_activated() { // Set the first activated version of Advanced Media Offloader. if (null === get_option('advmo_first_activated_version', null)) { update_option('advmo_first_activated_version', ADVMO_VERSION, true); } // Show the welcome notice until it is dismissed or settings are visited. update_option(\Advanced_Media_Offloader\Admin\Observers\WelcomeNotice::OPTION_KEY, 1, true); } /** * Plugin Deactivation Hook * * @since 3.3.4 */ public function plugin_deactivated() { // Clear any scheduled tasks wp_clear_scheduled_hook('advmo_bulk_offload_media_process_cron'); wp_clear_scheduled_hook('advmo_bulk_offload_cron'); // legacy hook name wp_clear_scheduled_hook('advmo_check_stalled_processes'); wp_clear_scheduled_hook('advmo_retry_pending_local_cleanup'); delete_option('advmo_pending_cleanup_cursor'); // Clear bulk offload related options delete_option('advmo_bulk_offload_cancelled'); delete_option('advmo_bulk_offload_last_update'); delete_option('advmo_bulk_offload_data'); delete_option('advmo_last_connection_check'); delete_option('advmo_last_connection_status'); // Clear any custom cron schedules if ($this->container && $this->container->has('bulk_offload_handler')) { try { $bulk_offload_handler = $this->container->get('bulk_offload_handler'); if ($bulk_offload_handler) { remove_filter('cron_schedules', array($bulk_offload_handler, 'add_cron_interval')); } } catch (\Exception $e) { // Silently fail if handler cannot be retrieved error_log('ADVMO: Error removing cron schedule filter during deactivation: ' . $e->getMessage()); } } // Note: We don't delete the cloud provider settings to preserve configuration } public function define($name, $value = true) { if (!defined($name)) { define($name, $value); } } public function notice($message, $type = 'info') { $class = 'notice notice-' . $type; printf('

%2$s

', esc_attr($class), esc_attr($message)); } } function advmo() { global $advmo; // Instantiate only once. if (!isset($advmo)) { $advmo = new ADVMO(); $advmo->initialize(); } return $advmo; } // Instantiate. advmo(); } // class_exists check