addons
6 days ago
general-cleanup
6 days ago
class-adbc-admin-init.php
6 days ago
class-adbc-automation.php
6 days ago
class-adbc-hardcoded-items.php
6 days ago
class-adbc-migration.php
6 days ago
class-adbc-routes.php
6 days ago
class-adbc-scan-counter.php
7 months ago
class-adbc-settings.php
6 days ago
class-adbc-singleton.php
7 months ago
class-adbc-admin-init.php
882 lines
| 1 | <?php |
| 2 | |
| 3 | // Exit if accessed directly |
| 4 | if ( ! defined( 'ABSPATH' ) ) |
| 5 | exit; |
| 6 | |
| 7 | /** |
| 8 | * ADBC admin init class. |
| 9 | * |
| 10 | * This class adds the menu and submenu pages, and enqueuing the scripts and styles. |
| 11 | */ |
| 12 | class ADBC_Admin_Init extends ADBC_Singleton { |
| 13 | |
| 14 | /** |
| 15 | * Holds the menu hook for the main left sidebar admin menu item. |
| 16 | */ |
| 17 | private $left_menu; |
| 18 | |
| 19 | /** |
| 20 | * Holds the menu hook for the submenu item under Tools. |
| 21 | */ |
| 22 | private $tools_submenu; |
| 23 | |
| 24 | /** |
| 25 | * Holds the menu hook for the network admin menu item. |
| 26 | */ |
| 27 | private $network_menu; |
| 28 | |
| 29 | /** |
| 30 | * Holds the svg icon for the menu item. |
| 31 | */ |
| 32 | private $icon_svg = ""; |
| 33 | |
| 34 | /** |
| 35 | * Option key used to persist conflict notices across redirects/requests. |
| 36 | * |
| 37 | * @var string |
| 38 | */ |
| 39 | private static $conflict_notice_option_key = 'adbc_conflict_notice'; |
| 40 | |
| 41 | /** |
| 42 | * Store original plugin links before other plugins modify them |
| 43 | */ |
| 44 | private $original_plugin_meta_links = []; |
| 45 | |
| 46 | /** |
| 47 | * Constructor. |
| 48 | */ |
| 49 | protected function __construct() { |
| 50 | |
| 51 | parent::__construct(); |
| 52 | |
| 53 | $this->icon_svg = 'data:image/svg+xml;base64,' . base64_encode( '<svg width="20" height="20" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path fill="#a0a5aa" d="M896 768q237 0 443-43t325-127v170q0 69-103 128t-280 93.5-385 34.5-385-34.5-280-93.5-103-128v-170q119 84 325 127t443 43zm0 768q237 0 443-43t325-127v170q0 69-103 128t-280 93.5-385 34.5-385-34.5-280-93.5-103-128v-170q119 84 325 127t443 43zm0-384q237 0 443-43t325-127v170q0 69-103 128t-280 93.5-385 34.5-385-34.5-280-93.5-103-128v-170q119 84 325 127t443 43zm0-1152q208 0 385 34.5t280 93.5 103 128v128q0 69-103 128t-280 93.5-385 34.5-385-34.5-280-93.5-103-128v-128q0-69 103-128t280-93.5 385-34.5z"/></svg>' ); |
| 54 | } |
| 55 | |
| 56 | /** |
| 57 | * Add the menu and submenu pages. |
| 58 | * |
| 59 | * @return void |
| 60 | */ |
| 61 | public function add_admin_menu() { |
| 62 | |
| 63 | $left_menu = ADBC_Settings::instance()->get_setting( 'left_menu' ); |
| 64 | $tools_menu = ADBC_Settings::instance()->get_setting( 'tools_menu' ); |
| 65 | |
| 66 | if ( $left_menu === '1' ) { |
| 67 | $this->left_menu = add_menu_page( 'Advanced DB Cleaner', 'DB Cleaner', 'manage_options', 'advanced_db_cleaner', [ $this, 'main_page_callback' ], $this->icon_svg, '80.01123' ); |
| 68 | } |
| 69 | |
| 70 | if ( $tools_menu === '1' ) { |
| 71 | $this->tools_submenu = add_submenu_page( 'tools.php', 'Advanced DB Cleaner', 'DB Cleaner', 'manage_options', 'advanced_db_cleaner', [ $this, 'main_page_callback' ], '80.01123' ); |
| 72 | } |
| 73 | } |
| 74 | |
| 75 | /** |
| 76 | * Add the network admin menu page. |
| 77 | * |
| 78 | * @return void |
| 79 | */ |
| 80 | public function add_network_admin_menu() { |
| 81 | |
| 82 | $network_menu = ADBC_Settings::instance()->get_setting( 'network_menu' ); |
| 83 | |
| 84 | if ( $network_menu === '1' ) { |
| 85 | $this->network_menu = add_menu_page( 'Advanced DB Cleaner', 'DB Cleaner', 'manage_network_options', 'advanced_db_cleaner_network', [ $this, 'main_page_callback' ], $this->icon_svg, '80.01123' ); |
| 86 | } |
| 87 | |
| 88 | } |
| 89 | |
| 90 | /** |
| 91 | * Callback for the main page. |
| 92 | * |
| 93 | * @return void |
| 94 | */ |
| 95 | public function main_page_callback() { |
| 96 | |
| 97 | echo "<div id='adbc-plugin-root'></div>"; |
| 98 | } |
| 99 | |
| 100 | /** |
| 101 | * Enqueue the scripts and styles. |
| 102 | * |
| 103 | * @param string $hook The current admin page hook. |
| 104 | * @return void |
| 105 | */ |
| 106 | public function enqueue_scripts( $hook ) { |
| 107 | |
| 108 | // Enqueue global scripts for global notifications such as the rating notice. |
| 109 | $this->enqueue_global_scripts(); |
| 110 | |
| 111 | // Load plugins scripts only in the plugin page. |
| 112 | if ( $hook != $this->left_menu && $hook != $this->tools_submenu && $hook != $this->network_menu ) |
| 113 | return; |
| 114 | |
| 115 | // Enqueue the scripts and styles. |
| 116 | wp_enqueue_style( 'adbc-app-style', ADBC_PLUGIN_ABSOLUTE_URL . '/assets/css/app.css', [], ADBC_PLUGIN_VERSION ); |
| 117 | wp_enqueue_script( 'adbc-vendors-script', ADBC_PLUGIN_ABSOLUTE_URL . '/assets/js/vendors.js', [], ADBC_PLUGIN_VERSION, true ); |
| 118 | wp_enqueue_script( 'adbc-app-script', ADBC_PLUGIN_ABSOLUTE_URL . '/assets/js/app.js', [ 'adbc-vendors-script', 'wp-i18n', 'wp-date' ], ADBC_PLUGIN_VERSION, true ); |
| 119 | |
| 120 | // Load the translations for the app script. |
| 121 | wp_set_script_translations( 'adbc-app-script', 'advanced-database-cleaner', ADBC_PLUGIN_DIR_PATH . 'languages' ); |
| 122 | |
| 123 | // Localize right after enqueuing. |
| 124 | wp_localize_script( |
| 125 | 'adbc-app-script', |
| 126 | 'adbc_app_settings', |
| 127 | array( |
| 128 | 'rest_url' => esc_url_raw( rest_url( ADBC_REST_API_NAMESPACE ) ), |
| 129 | 'nonce' => wp_create_nonce( 'wp_rest' ), |
| 130 | 'version' => ADBC_PLUGIN_VERSION, |
| 131 | 'version_type' => ADBC_VERSION_TYPE, |
| 132 | 'is_pro_version' => ADBC_IS_PRO_VERSION ? '1' : '0', |
| 133 | 'settings' => ADBC_Settings::instance()->get_settings( false ), // Send none sensitive settings. |
| 134 | 'license_data' => ADBC_VERSION_TYPE === "PREMIUM" ? ADBC_License_Manager::get_license_data() : [], // Send masked license key. |
| 135 | 'warnings' => ADBC_Notifications::instance()->get_warnings(), |
| 136 | 'notifications' => ADBC_Notifications::instance()->get_local_notifications(), |
| 137 | 'is_multisite' => is_multisite() ? '1' : '0', |
| 138 | 'sites_list' => ADBC_Sites::instance()->get_sites_list(), |
| 139 | 'actionscheduler_actions_exists' => ADBC_Tables::is_actionscheduler_table_exists( 'actions' ) ? '1' : '0', |
| 140 | 'actionscheduler_logs_exists' => ADBC_Tables::is_actionscheduler_table_exists( 'logs' ) ? '1' : '0', |
| 141 | 'php_max_execution_time' => ( $value = (int) ini_get( 'max_execution_time' ) ) > 0 ? $value : 120, |
| 142 | 'is_woptimize_installed' => self::is_woptimize_installed() ? '1' : '0', |
| 143 | ) |
| 144 | ); |
| 145 | |
| 146 | } |
| 147 | |
| 148 | /** |
| 149 | * Enqueue global scripts for ADBC notifications. |
| 150 | * This runs on all admin pages, not just the plugin pages. |
| 151 | * |
| 152 | * @return void |
| 153 | */ |
| 154 | private function enqueue_global_scripts() { |
| 155 | |
| 156 | // Only load on admin pages and for users with manage_options capability. |
| 157 | if ( ! is_admin() || ! current_user_can( 'manage_options' ) ) |
| 158 | return; |
| 159 | |
| 160 | // Check if we have any global notifications to show |
| 161 | $global_notifications = ADBC_Notifications::instance()->get_global_notifications(); |
| 162 | |
| 163 | if ( empty( $global_notifications ) ) |
| 164 | return; |
| 165 | |
| 166 | $has_rating = isset( $global_notifications['rating_notice'] ); |
| 167 | $has_ltd = isset( $global_notifications['ltd_migration_notice'] ); |
| 168 | |
| 169 | // Only enqueue shared assets if at least one of our custom global notices is active. |
| 170 | if ( ! $has_rating && ! $has_ltd ) |
| 171 | return; |
| 172 | |
| 173 | // Single combined CSS/JS for all global notices (rating + LTD migration). |
| 174 | wp_enqueue_style( |
| 175 | 'adbc-global-style', |
| 176 | ADBC_PLUGIN_ABSOLUTE_URL . '/assets/css/global-style.css', |
| 177 | array(), |
| 178 | ADBC_PLUGIN_VERSION |
| 179 | ); |
| 180 | |
| 181 | wp_enqueue_script( |
| 182 | 'adbc-global-script', |
| 183 | ADBC_PLUGIN_ABSOLUTE_URL . '/assets/js/global-js.js', |
| 184 | array( 'jquery' ), |
| 185 | ADBC_PLUGIN_VERSION, |
| 186 | true |
| 187 | ); |
| 188 | |
| 189 | // Single localized object shared by all notice JS. |
| 190 | wp_localize_script( |
| 191 | 'adbc-global-script', |
| 192 | 'adbc_global_settings', |
| 193 | array( |
| 194 | 'rest_url' => esc_url_raw( rest_url( ADBC_REST_API_NAMESPACE ) ), |
| 195 | 'nonce' => wp_create_nonce( 'wp_rest' ), |
| 196 | ) |
| 197 | ); |
| 198 | } |
| 199 | |
| 200 | /** |
| 201 | * Prioritize plugin's translation files over global ones. |
| 202 | * |
| 203 | * This ensures that translations in the plugin's languages folder |
| 204 | * take precedence over those in wp-content/languages/plugins/ |
| 205 | * |
| 206 | * @param string $mofile Path to the MO file. |
| 207 | * @param string $domain Text domain. |
| 208 | * @return string Modified path to the MO file. |
| 209 | */ |
| 210 | public static function prioritize_plugin_translations( $mofile, $domain ) { |
| 211 | |
| 212 | // Only apply to our plugin's text domain |
| 213 | if ( 'advanced-database-cleaner' !== $domain ) { |
| 214 | return $mofile; |
| 215 | } |
| 216 | |
| 217 | // Get the current locale |
| 218 | $locale = apply_filters( 'plugin_locale', determine_locale(), $domain ); |
| 219 | |
| 220 | // Build the path to our plugin's translation file |
| 221 | $plugin_mofile = ADBC_PLUGIN_DIR_PATH . 'languages/' . $domain . '-' . $locale . '.mo'; |
| 222 | |
| 223 | // If our plugin's translation file exists, use it instead |
| 224 | if ( file_exists( $plugin_mofile ) ) { |
| 225 | return $plugin_mofile; |
| 226 | } |
| 227 | |
| 228 | // Fallback to the original file |
| 229 | return $mofile; |
| 230 | |
| 231 | } |
| 232 | |
| 233 | /** |
| 234 | * Change the script translation file name to load the correct file. |
| 235 | * |
| 236 | * This is necessary because WordPress generates the MD5 hash based on the script file name, |
| 237 | * and we want to ensure that our translations are loaded from the correct file. |
| 238 | * The MD5 of the translation file built by WP will use assets/js/translations.js instead of assets/js/app.js |
| 239 | * |
| 240 | * @param string $file The path to the translation file. |
| 241 | * @param string $handle The script handle. |
| 242 | * @param string $domain The text domain. |
| 243 | * @return string The modified path to the translation file. |
| 244 | */ |
| 245 | public static function change_script_translation_file_name( $file, $handle, $domain ) { |
| 246 | |
| 247 | if ( $domain !== 'advanced-database-cleaner' ) { |
| 248 | return $file; |
| 249 | } |
| 250 | |
| 251 | $file = str_replace( md5( 'assets/js/app.js' ), md5( 'assets/js/translations.js' ), $file ); |
| 252 | |
| 253 | return $file; |
| 254 | |
| 255 | } |
| 256 | |
| 257 | /** |
| 258 | * What happens upon plugin activation. |
| 259 | * |
| 260 | * @return void |
| 261 | */ |
| 262 | public static function activate() { |
| 263 | // Nothing to do here for now |
| 264 | } |
| 265 | |
| 266 | /** |
| 267 | * What happens upon plugin deactivation. |
| 268 | * |
| 269 | * @return void |
| 270 | */ |
| 271 | public static function deactivate() { |
| 272 | |
| 273 | // unschedule analytics cron |
| 274 | wp_clear_scheduled_hook( 'adbc_cron_analytics' ); |
| 275 | |
| 276 | // Deactivate all automation tasks |
| 277 | ADBC_Automation::instance()->deactivate_all_tasks(); |
| 278 | |
| 279 | } |
| 280 | |
| 281 | /** |
| 282 | * Generate ADBC uploads folder if missing. |
| 283 | * |
| 284 | * @return void |
| 285 | */ |
| 286 | public static function create_adbc_uploads_folder_with_its_content() { |
| 287 | |
| 288 | // Check if the WP filesystem is initialized. If it fails, no need to continue. |
| 289 | if ( ! ADBC_Files::instance()->is_wp_fs_initialized() ) |
| 290 | return; |
| 291 | |
| 292 | // Try to create the ADBC uploads folder. If it fails, no need to continue. |
| 293 | if ( ! self::create_adbc_uploads_folder() ) |
| 294 | return; |
| 295 | |
| 296 | // Create files and folders inside the ADBC uploads folder. |
| 297 | ADBC_Files::instance()->create_file( ADBC_Logging::DEBUG_LOG_FILE_PATH ); |
| 298 | |
| 299 | // Create the scan folder. |
| 300 | if ( ADBC_VERSION_TYPE === "PREMIUM" ) { |
| 301 | ADBC_Files::instance()->create_folder( ADBC_Scan_Paths::SCAN_FOLDER_PATH, true ); |
| 302 | ADBC_Files::instance()->create_folder( ADBC_Analytics::ADBC_ANALYTICS_DIR, true ); |
| 303 | ADBC_Files::instance()->create_folder( ADBC_Analytics::ADBC_ANALYTICS_DATABASE_DIR, true ); |
| 304 | ADBC_Files::instance()->create_folder( ADBC_Analytics::ADBC_ANALYTICS_TABLES_DIR, true ); |
| 305 | ADBC_Files::instance()->create_folder( ADBC_Automation::AUTOMATION_EVENT_DIR, true ); |
| 306 | ADBC_Files::instance()->create_file( ADBC_Addons_Activity::ADDONS_ACTIVITY_LOG_FILE_PATH ); |
| 307 | ADBC_Files::instance()->create_file( ADBC_Addons_Activity::ADDONS_ACTIVITY_DICTIONARY ); |
| 308 | ADBC_Files::instance()->create_file( ADBC_Registered_Post_Types_Dict_Tracker::DICT_FILE_PATH ); |
| 309 | ADBC_Files::instance()->create_file( ADBC_Scan_Paths::get_custom_addons_dictionary_file_path() ); |
| 310 | } |
| 311 | |
| 312 | } |
| 313 | |
| 314 | /** |
| 315 | * Setup the ADBC uploads folder (with its content). |
| 316 | * |
| 317 | * @return boolean True if successful, false otherwise. |
| 318 | */ |
| 319 | private static function create_adbc_uploads_folder() { |
| 320 | |
| 321 | // If the ADBC uploads folder doesn't exist, delete all folders starting with the ADBC uploads folder prefix before creating a new one. |
| 322 | if ( ! ADBC_Files::instance()->is_dir( ADBC_UPLOADS_DIR_PATH ) ) { |
| 323 | |
| 324 | $files = glob( ADBC_WP_UPLOADS_DIR_PATH . '/' . ADBC_UPLOADS_DIR_PREFIX . '*' ); |
| 325 | $adbc_folder_length = strlen( ADBC_UPLOADS_DIR_PREFIX ) + ADBC_SECURITY_CODE_LENGTH; |
| 326 | |
| 327 | foreach ( $files as $file ) { |
| 328 | $folder_name = basename( $file ); |
| 329 | // Delete if the folder name = $adbc_folder_length and composed only of alphanumeric, underscores and F. |
| 330 | if ( strlen( $folder_name ) === $adbc_folder_length && preg_match( '/^[a-z0-9_F]+$/', $folder_name ) ) |
| 331 | ADBC_Files::instance()->delete_folder( $file ); |
| 332 | } |
| 333 | } |
| 334 | |
| 335 | // Create the new ADBC uploads folder if it doesn't exist. |
| 336 | ADBC_Files::instance()->create_folder( ADBC_UPLOADS_DIR_PATH, true ); |
| 337 | |
| 338 | // At this point the ADBC uploads folder should exist. Verify if it's readable and writable. |
| 339 | if ( ADBC_Files::instance()->is_readable_and_writable( ADBC_UPLOADS_DIR_PATH ) ) { |
| 340 | ADBC_Notifications::instance()->delete_notification( "uploads_folder" ); // Clear the warning form the DB if it exists. |
| 341 | } else { |
| 342 | ADBC_Notifications::instance()->add_notification( 'uploads_folder' ); |
| 343 | return false; |
| 344 | } |
| 345 | |
| 346 | return true; |
| 347 | } |
| 348 | |
| 349 | /** |
| 350 | * Ensure the integrity of automation tasks. |
| 351 | * |
| 352 | * This method checks all automation tasks, validates their structure, and ensures they are scheduled or unscheduled as needed. |
| 353 | * It also cleans up any orphaned cron hooks that no longer have a corresponding task with their events files. |
| 354 | */ |
| 355 | public static function ensure_automation_integrity() { |
| 356 | |
| 357 | $tasks = ADBC_Automation::instance()->tasks(); |
| 358 | $cron_ids = ADBC_Automation::get_scheduled_automation_crons_ids(); |
| 359 | |
| 360 | foreach ( $tasks as $id => $task ) { |
| 361 | |
| 362 | $valid = ADBC_Automation_Validator::validate_task_structure( $task ); |
| 363 | |
| 364 | // task invalid → remove unschedule & cleanup |
| 365 | if ( $valid === false ) { |
| 366 | ADBC_Automation::instance()->delete( $id ); |
| 367 | continue; |
| 368 | } |
| 369 | |
| 370 | $is_active = (bool) $task['active']; |
| 371 | $is_scheduled = in_array( $id, $cron_ids, true ); |
| 372 | |
| 373 | // valid & inactive → ensure NOT scheduled |
| 374 | if ( ! $is_active && $is_scheduled ) { |
| 375 | ADBC_Automation::instance()->unschedule( $id ); // unschedule the task |
| 376 | // keep events file (user may re-enable later) |
| 377 | } |
| 378 | |
| 379 | // valid & active → ensure scheduled |
| 380 | if ( $is_active && ! $is_scheduled ) { |
| 381 | ADBC_Automation::instance()->schedule( $task ); // schedule the task |
| 382 | } |
| 383 | |
| 384 | } |
| 385 | |
| 386 | // orphan cron hooks (hook exists but task record gone) |
| 387 | foreach ( $cron_ids as $id ) { |
| 388 | if ( ! isset( $tasks[ $id ] ) ) { |
| 389 | // The task is not found in the tasks array, so we can unschedule it and delete its events file. |
| 390 | ADBC_Automation::instance()->unschedule( $id ); |
| 391 | ADBC_Automation::delete_events_file( $id ); |
| 392 | } |
| 393 | } |
| 394 | |
| 395 | } |
| 396 | |
| 397 | /** |
| 398 | * Register the cron_schedules filter to add ADBC custom schedules. |
| 399 | * |
| 400 | * @return void |
| 401 | */ |
| 402 | public static function register_cron_schedules_filter() { |
| 403 | add_filter( 'cron_schedules', [ self::class, 'add_adbc_schedules_frequencies' ] ); |
| 404 | } |
| 405 | |
| 406 | /** |
| 407 | * Add custom schedules for ADBC cron jobs. |
| 408 | * |
| 409 | * @param array $schedules The existing schedules. |
| 410 | * |
| 411 | * @return array The modified schedules with ADBC custom frequencies added. |
| 412 | */ |
| 413 | public static function add_adbc_schedules_frequencies( $schedules ) { |
| 414 | |
| 415 | // Add adbc_hourly schedule (1 hour) |
| 416 | $schedules['adbc_hourly'] = array( |
| 417 | 'interval' => HOUR_IN_SECONDS, |
| 418 | 'display' => __( 'Once hourly', 'advanced-database-cleaner' ) |
| 419 | ); |
| 420 | |
| 421 | // Add adbc_twicedaily schedule (12 hours) |
| 422 | $schedules['adbc_twicedaily'] = array( |
| 423 | 'interval' => 12 * HOUR_IN_SECONDS, |
| 424 | 'display' => __( 'Twice daily', 'advanced-database-cleaner' ) |
| 425 | ); |
| 426 | |
| 427 | // Add adbc_daily schedule (1 day) |
| 428 | $schedules['adbc_daily'] = array( |
| 429 | 'interval' => DAY_IN_SECONDS, |
| 430 | 'display' => __( 'Once daily', 'advanced-database-cleaner' ) |
| 431 | ); |
| 432 | |
| 433 | // Add adbc_weekly schedule (1 week) |
| 434 | $schedules['adbc_weekly'] = array( |
| 435 | 'interval' => WEEK_IN_SECONDS, |
| 436 | 'display' => __( 'Once weekly', 'advanced-database-cleaner' ) |
| 437 | ); |
| 438 | |
| 439 | // Add adbc_monthly schedule (approx. 1 month) |
| 440 | $schedules['adbc_monthly'] = array( |
| 441 | 'interval' => 30 * DAY_IN_SECONDS, // 30 days as a rough monthly interval |
| 442 | 'display' => __( 'Once monthly', 'advanced-database-cleaner' ) |
| 443 | ); |
| 444 | |
| 445 | return $schedules; |
| 446 | |
| 447 | } |
| 448 | |
| 449 | /** |
| 450 | * Initialize settings with defaults if not set. |
| 451 | * |
| 452 | * @return void |
| 453 | */ |
| 454 | public static function maybe_show_global_notifications() { |
| 455 | |
| 456 | // Only load on admin pages and for users with manage_options capability. |
| 457 | if ( ! is_admin() || ! current_user_can( 'manage_options' ) ) |
| 458 | return; |
| 459 | |
| 460 | $notifications = ADBC_Notifications::instance()->get_global_notifications(); |
| 461 | |
| 462 | foreach ( $notifications as $key => $notification ) { |
| 463 | |
| 464 | // Special handling for rating_notice notification |
| 465 | if ( $key === 'rating_notice' ) { |
| 466 | |
| 467 | $rating_url = 'https://wordpress.org/support/plugin/advanced-database-cleaner/reviews/?filter=5'; |
| 468 | |
| 469 | $text = sprintf( |
| 470 | /* translators: 1: Plugin name with link */ |
| 471 | esc_html__( 'You have been using %s for more than 1 week. Would you mind taking a few seconds to give it a 5-star rating on WordPress? Thank you in advance :)', 'advanced-database-cleaner' ), |
| 472 | '<a href="admin.php?page=advanced_db_cleaner">Advanced DB Cleaner</a>' |
| 473 | ); |
| 474 | |
| 475 | if ( is_multisite() ) |
| 476 | $text = esc_html__( 'You have been using the "Advanced DB Cleaner" for more than 1 week. Would you mind taking a few seconds to give it a 5-star rating on WordPress? Thank you in advance :)', 'advanced-database-cleaner' ); |
| 477 | |
| 478 | printf( |
| 479 | '<div id="adbc-rating-notice" class="adbc-notice"> |
| 480 | <div class="adbc-content"> |
| 481 | <div class="adbc-header"> |
| 482 | <div class="adbc-star"> |
| 483 | <span>⭐</span> |
| 484 | </div> |
| 485 | <span class="adbc-title">%s</span> |
| 486 | </div> |
| 487 | |
| 488 | <p class="adbc-text">%s</p> |
| 489 | |
| 490 | <div class="adbc-buttons"> |
| 491 | <div class="adbc-buttons-left"> |
| 492 | <a href="%s" target="_blank" class="adbc-btn adbc-btn-primary"> |
| 493 | <span>⭐</span>%s |
| 494 | </a> |
| 495 | <a class="adbc-btn adbc-btn-secondary adbc-rating-dismiss"> |
| 496 | %s |
| 497 | </a> |
| 498 | <a class="adbc-btn adbc-btn-secondary adbc-rating-dismiss"> |
| 499 | %s |
| 500 | </a> |
| 501 | </div> |
| 502 | |
| 503 | <a id="adbc-rating-btn-remind-me" class="adbc-btn adbc-btn-secondary"> |
| 504 | <span class="dashicons dashicons-clock"></span>%s |
| 505 | </a> |
| 506 | </div> |
| 507 | </div> |
| 508 | |
| 509 | <div> |
| 510 | <a title="%s" class="adbc-btn-dismiss adbc-rating-dismiss"> |
| 511 | <span class="dashicons dashicons-dismiss"></span> |
| 512 | </a> |
| 513 | </div> |
| 514 | </div>', |
| 515 | esc_html__( 'Awesome!', 'advanced-database-cleaner' ), |
| 516 | $text, |
| 517 | $rating_url, |
| 518 | esc_html__( 'Ok, you deserved it', 'advanced-database-cleaner' ), |
| 519 | esc_html__( 'I already did', 'advanced-database-cleaner' ), |
| 520 | esc_html__( 'No, not good enough', 'advanced-database-cleaner' ), |
| 521 | esc_html__( 'Remind me later', 'advanced-database-cleaner' ), |
| 522 | esc_html__( 'Dismiss', 'advanced-database-cleaner' ) |
| 523 | ); |
| 524 | |
| 525 | } elseif ( $key === 'ltd_migration_notice' ) { |
| 526 | |
| 527 | $upgrade_url = 'https://sigmaplugin.com/upgrade-to-full-v4?utm_source=pro-v4-notification&utm_medium=adbc-pro&utm_campaign=plugins&utm_content=upgrade-to-v4'; |
| 528 | |
| 529 | $message_intro = sprintf( |
| 530 | /* translators: 1: opening <a> tag, 2: closing </a> tag */ |
| 531 | __( 'Your %1$sAdvanced DB Cleaner Pro%2$s has been upgraded to version 4.x, a major update featuring a new architecture, a redesigned interface, and many new features.', 'advanced-database-cleaner' ), |
| 532 | '<a href="admin.php?page=advanced_db_cleaner" class="adbc-ltd-text-link">', |
| 533 | '</a>' |
| 534 | ); |
| 535 | |
| 536 | if ( is_multisite() ) |
| 537 | $message_intro = esc_html__( 'Your "Advanced DB Cleaner Pro" has been upgraded to version 4.x, a major update featuring a new architecture, a redesigned interface, and many new features.', 'advanced-database-cleaner' ); |
| 538 | |
| 539 | $phrase1 = sprintf( |
| 540 | /* translators: 1: opening <strong> tag, 2: closing </strong> tag */ |
| 541 | esc_html__( |
| 542 | 'We have introduced a new Remote Scan feature, designed to detect orphaned database items with much higher accuracy. Because this feature requires ongoing infrastructure and maintenance costs, %1$sit is not included in the lifetime plan%2$s.', |
| 543 | 'advanced-database-cleaner' |
| 544 | ), |
| 545 | '<strong>', |
| 546 | '</strong>' |
| 547 | ); |
| 548 | |
| 549 | $phrase2 = esc_html__( 'To access it, we created a separate plugin version under an annual pricing model, bundled with the Remote Scan feature and upcoming AI and cloud capabilities. As a lifetime customer, you can benefit from a 50% discount on the first purchase and all renewals (discount available for a limited time).', 'advanced-database-cleaner' ); |
| 550 | |
| 551 | echo '<div id="adbc-ltd-migration-notice" class="adbc-ltd-migration-notice">'; |
| 552 | echo '<div class="adbc-ltd-icon">'; |
| 553 | echo '<svg id="fi_8606859" enable-background="new 0 0 500 500" height="80" viewBox="0 0 500 500" width="80" xmlns="http://www.w3.org/2000/svg"><path clip-rule="evenodd" d="m350.8 245.46c2.85 6.65 4.75 12.35 7.6 19 1.9 5.7 3.8 13.3 5.7 19.95 3.8 8.55 11.4 34.2 10.45 42.75-.95 7.6 1.9 19 0 21.85-1.9 5.7-6.65 12.35-12.35 13.3 0-2.85 1.9-5.7 1.9-9.5.95-12.35 0-19.95-2.85-31.35-3.8-13.3-19.95-56.05-24.7-70.31l-21.85-49.4c-7.6-16.15-16.15-30.4-23.75-47.5-6.65-18.05-23.75-45.6-38.95-55.1 0-2.85 12.35-10.45 17.1-8.55s10.45 9.5 12.35 13.3c3.8 6.65 6.65 9.5 10.45 16.15 3.8 5.7 6.65 11.4 9.5 17.1 6.65 10.45 13.3 22.8 19 34.2 4.75 12.35 9.5 24.7 15.2 37.05s10.45 23.75 15.2 37.06zm-7.6-61.76c.95 4.75 7.6 19.95 10.45 24.7 1.9 3.8 3.8 8.55 5.7 12.35s2.85 9.5 5.7 12.35c14.26-9.5 12.36-51.3-21.85-49.4zm-246.07 57.95c0 3.8 14.25 42.75 16.15 48.45 6.65 16.15 12.35 33.25 19 48.45 35.15-1.9 41.8-.95 79.81 0 12.35.95 75.06 11.4 86.46 13.3 13.3 1.9 27.55 7.6 40.85 9.5.95 0 6.65-5.7 6.65-5.7 3.8-3.8.95-23.75-.95-29.45-3.8-13.3-7.6-22.8-11.4-34.2-1.9-5.7-3.8-10.45-5.7-17.1-4.75-14.25-15.2-35.15-20.9-48.45-6.65-16.15-5.7-15.2-14.25-31.35-5.7-10.45-10.45-19-15.2-29.45-4.75-12.35-6.65-18.05-15.2-30.4-4.75-6.65-16.15-21.85-22.8-23.75-5.7 4.75-17.1 24.7-30.4 38-6.65 5.7-12.35 11.4-17.1 17.1-6.65 6.65-11.4 9.5-19 15.2-6.65 3.8-12.35 9.5-18.05 15.2l-47.5 37.05c-3.82 2.85-7.62 4.75-10.47 7.6zm17.1 98.81c-1.9 1.9-13.3 2.85-17.1 3.8-5.7.95-10.45 2.85-16.15 4.75-10.45 2.85-21.85 5.7-32.3 8.55-4.75.95-11.4 2.85-18.05 2.85-3.8-.95-3.8-1.9-5.7-4.75-1.9-1.9-3.8-2.85-4.75-4.75-11.4-14.25-21.85-43.7-19.95-61.76 1.9-12.35 6.65-18.05 17.1-22.8 24.7-10.45 37.05-8.55 48.45-12.35 4.75-.95 11.4-3.8 15.2-4.75l32.3 87.41c1.9 3.8 1.9 2.85.95 3.8zm114.96-186.21c5.7-1.9 10.45 2.85 10.45 7.6-.95 3.8-5.7 9.5-8.55 11.4-10.45 11.4-7.6 7.6-19 21.85-9.5 10.45-13.3 11.4-21.85 19.95l-21.85 17.1c-5.7 2.85-12.35-.95-11.4-7.6 0-4.75 5.7-8.55 8.55-11.4l22.8-18.05c7.6-6.65 11.4-13.3 19.95-21.85 2.85-2.85 6.65-5.7 9.5-9.5 3.8-4.75 6.65-7.6 11.4-9.5zm120.67-102.61c-4.75 1.9-4.75 4.75-5.7 12.35-.95 6.65-4.75 27.55-2.85 33.25.95 4.75 6.65 7.6 11.4 5.7 5.7-1.9 4.75-6.65 4.75-13.3.95-7.6 4.75-27.55 3.8-32.3-1.9-4.75-5.7-7.6-11.4-5.7zm110.2 271.72-14.25-15.2c-3.8-2.85-11.4-11.4-15.2-13.3-8.55-.95-14.25 6.65-9.5 13.3l13.3 13.3c4.75 4.75 15.2 20.9 23.75 12.35 3.8-3.8 1.9-5.7 1.9-10.45zm23.76-159.61c-5.7 1.9-7.6 4.75-12.35 6.65s-11.4 2.85-16.15 3.8c-17.1 3.8-7.6 19.95 1.9 18.05 2.85-.95 2.85-1.9 6.65-2.85 2.85-.95 4.75-.95 7.6-1.9 5.7-1.9 9.5-2.85 14.25-5.7 3.8-3.8 9.5-2.85 9.5-10.45 0-5.7-5.7-9.5-11.4-7.6zm-43.71-80.76c-5.7 2.85-5.7 5.7-9.5 11.4-2.85 3.8-5.7 7.6-8.55 11.4-1.9 2.85-6.65 9.5-6.65 13.3 0 6.65 5.7 10.45 11.4 8.55 3.8-.95 5.7-7.6 8.55-11.4 3.8-5.7 15.2-19.95 15.2-24.7 0-5.7-4.75-11.4-10.45-8.55zm18.05 157.71c-4.75.95-8.55 5.7-5.7 11.4s33.25 16.15 40.85 14.25c4.75-.95 8.55-6.65 5.7-11.4-1.9-5.7-10.45-2.85-26.6-10.45-4.75-1.9-8.54-5.7-14.25-3.8zm-410.43 36.11c-9.5 3.8-17.1 5.7-23.75 9.5-10.45 6.65-4.75 19.95 6.65 15.2 3.8-1.9 7.6-2.85 11.4-4.75s7.6-2.85 12.35-4.75c9.5-3.8 5.7-19-6.65-15.2zm14.25 95.01c.95-.95 0 0 1.9-.95l15.2-4.75c4.75-.95 12.35-3.8 17.1-4.75.95.95 2.85 6.65 5.7 11.4 1.9 3.8 4.75 7.6 6.65 11.4 8.55 15.2 5.7 9.5 14.25 21.85 3.8 4.75 13.3 17.1 15.2 20.9 1.9 5.7 2.85 8.55-1.9 12.35-6.65 5.7-16.15 7.6-25.65 9.5-6.65.95-9.5-1.9-12.35-5.7-4.75-6.65-9.5-15.2-13.3-21.85-3.8-8.55-8.55-15.2-12.35-23.75-1.9-4.75-9.5-20.9-10.45-25.65z" fill="#5EA500" fill-rule="evenodd"></path></svg>'; |
| 554 | echo '</div>'; |
| 555 | echo '<div class="adbc-ltd-content">'; |
| 556 | echo '<span class="adbc-ltd-title">' . esc_html__( 'Advanced DB Cleaner Pro V4 is finally here!', 'advanced-database-cleaner' ) . '</span>'; |
| 557 | echo '<p class="adbc-ltd-text">' . wp_kses_post( $message_intro ) . '</p>'; |
| 558 | echo '<div style="background-color:#EFF6FF;padding:16px 20px;margin:10px 0px;border-radius:4px;border:1.5px solid #3b82f6;box-shadow:0 4px 4px rgba(0,0,0,0.06);">'; |
| 559 | echo '<p style="margin:0 0 8px 0;font-weight:700;font-size:14px;color:#FF6900;letter-spacing:0.05em;">ⓘ IMPORTANT!</p>'; |
| 560 | echo '<ul class="adbc-ltd-list"><li>' . $phrase1 . '</li><li>' . $phrase2 . '</li></ul>'; |
| 561 | echo '</div>'; |
| 562 | echo '<div class="adbc-ltd-buttons">'; |
| 563 | echo '<a href="' . esc_url( $upgrade_url ) . '" target="_blank" class="button button-primary adbc-ltd-btn-primary">'; |
| 564 | echo '<span class="dashicons dashicons-arrow-right-alt" style="margin-top:5px;margin-right:5px;"></span>'; |
| 565 | echo '<b>' . esc_html__( 'How to get to the full version - 50% OFF forever', 'advanced-database-cleaner' ) . '</b>'; |
| 566 | echo '</a>'; |
| 567 | echo '<a href="#" id="adbc-ltd-btn-remind-me" class="button adbc-ltd-btn-secondary">'; |
| 568 | echo '<span class="dashicons dashicons-clock" style="margin-top:5px;margin-right:5px;"></span>'; |
| 569 | echo esc_html__( 'Remind me in a week', 'advanced-database-cleaner' ); |
| 570 | echo '</a>'; |
| 571 | echo '</div>'; |
| 572 | echo '</div>'; |
| 573 | echo '<div class="adbc-ltd-dismiss">'; |
| 574 | echo '<a href="#" title="' . esc_attr__( 'Dismiss', 'advanced-database-cleaner' ) . '"><span class="dashicons dashicons-dismiss"></span></a>'; |
| 575 | echo '</div>'; |
| 576 | echo '</div>'; |
| 577 | |
| 578 | } else { |
| 579 | // Standard notification rendering. For now, we are not rendering these notifications in the admin area. |
| 580 | // $type = esc_attr( $notification['type'] ); |
| 581 | // $message = wp_kses_post( $notification['message'] ); |
| 582 | // $dismissible = ! empty( $notification['dismissible'] ) ? ' is-dismissible' : ''; |
| 583 | // printf( |
| 584 | // '<div class="notice notice-%1$s%2$s adbc-notice" data-adbc-notice-key="%3$s"><p>%4$s</p></div>', |
| 585 | // $type, |
| 586 | // $dismissible, |
| 587 | // esc_attr( $key ), |
| 588 | // $message |
| 589 | // ); |
| 590 | } |
| 591 | } |
| 592 | } |
| 593 | |
| 594 | /** |
| 595 | * Static proxy for add_admin_menu to be used in the hooks. |
| 596 | * |
| 597 | * @return void |
| 598 | */ |
| 599 | public static function _add_admin_menu() { |
| 600 | self::instance()->add_admin_menu(); |
| 601 | } |
| 602 | |
| 603 | /** |
| 604 | * Static proxy for add_network_admin_menu to be used in the hooks. |
| 605 | * |
| 606 | * @return void |
| 607 | */ |
| 608 | public static function _add_network_admin_menu() { |
| 609 | self::instance()->add_network_admin_menu(); |
| 610 | } |
| 611 | |
| 612 | /** |
| 613 | * Static proxy for enqueue_scripts to be used in the hooks. |
| 614 | * |
| 615 | * @param string $hook The current admin page hook. |
| 616 | * @return void |
| 617 | */ |
| 618 | public static function _enqueue_scripts( $hook ) { |
| 619 | self::instance()->enqueue_scripts( $hook ); |
| 620 | } |
| 621 | |
| 622 | /** |
| 623 | * Load all cleanup type handlers. |
| 624 | * |
| 625 | * This method includes all PHP files in the type-handlers directories, |
| 626 | * allowing each handler to self-register with the General Cleanup system. |
| 627 | * It supports both free and premium handlers based on the plugin version. |
| 628 | * |
| 629 | * @return void |
| 630 | */ |
| 631 | public static function load_general_cleanup_handlers() { |
| 632 | |
| 633 | $base_dir = ADBC_PLUGIN_DIR_PATH . '/includes/classes/general-cleanup/type-handlers'; |
| 634 | $premium_dir = ADBC_PLUGIN_DIR_PATH . 'includes/premium/classes/general-cleanup/type-handlers'; |
| 635 | |
| 636 | $dirs = [ $base_dir ]; |
| 637 | |
| 638 | // Only add premium if this is the premium build |
| 639 | if ( ADBC_VERSION_TYPE === "PREMIUM" ) { |
| 640 | $dirs[] = $premium_dir; |
| 641 | } |
| 642 | |
| 643 | foreach ( $dirs as $dir ) { |
| 644 | |
| 645 | if ( ! is_dir( $dir ) ) { |
| 646 | continue; |
| 647 | } |
| 648 | |
| 649 | foreach ( glob( $dir . '/*.php' ) as $file ) { |
| 650 | include_once $file; // triggers the self-registration logic |
| 651 | } |
| 652 | |
| 653 | } |
| 654 | |
| 655 | } |
| 656 | |
| 657 | /** |
| 658 | * Detect and handle conflicts between free, pro and premium versions. |
| 659 | * |
| 660 | * @return bool True if a conflict was detected and handled, false otherwise. |
| 661 | */ |
| 662 | public static function has_conflict() { |
| 663 | |
| 664 | if ( ! function_exists( 'deactivate_plugins' ) ) |
| 665 | include_once( ABSPATH . 'wp-admin/includes/plugin.php' ); |
| 666 | |
| 667 | $premium_active = is_plugin_active( 'advanced-database-cleaner-premium/advanced-db-cleaner.php' ); |
| 668 | $pro_active = is_plugin_active( 'advanced-database-cleaner-pro/advanced-db-cleaner.php' ); |
| 669 | $free_active = is_plugin_active( 'advanced-database-cleaner/advanced-db-cleaner.php' ); |
| 670 | |
| 671 | if ( $premium_active && $free_active ) { |
| 672 | |
| 673 | $network_wide = function_exists( 'is_plugin_active_for_network' ) && is_plugin_active_for_network( 'advanced-database-cleaner/advanced-db-cleaner.php' ); |
| 674 | deactivate_plugins( 'advanced-database-cleaner/advanced-db-cleaner.php', true, $network_wide ); |
| 675 | ADBC_Common_Utils::old_plugin_version_deactivation_cleaning(); |
| 676 | self::schedule_conflict_notice( 'free_premium' ); |
| 677 | |
| 678 | return true; |
| 679 | |
| 680 | } |
| 681 | |
| 682 | if ( $premium_active && $pro_active ) { |
| 683 | |
| 684 | $network_wide = function_exists( 'is_plugin_active_for_network' ) && is_plugin_active_for_network( 'advanced-database-cleaner-pro/advanced-db-cleaner.php' ); |
| 685 | deactivate_plugins( 'advanced-database-cleaner-pro/advanced-db-cleaner.php', true, $network_wide ); |
| 686 | ADBC_Common_Utils::old_plugin_version_deactivation_cleaning(); |
| 687 | self::schedule_conflict_notice( 'pro_premium' ); |
| 688 | |
| 689 | return true; |
| 690 | |
| 691 | } |
| 692 | |
| 693 | if ( $pro_active && $free_active ) { |
| 694 | |
| 695 | $network_wide = function_exists( 'is_plugin_active_for_network' ) && is_plugin_active_for_network( 'advanced-database-cleaner/advanced-db-cleaner.php' ); |
| 696 | deactivate_plugins( 'advanced-database-cleaner/advanced-db-cleaner.php', true, $network_wide ); |
| 697 | ADBC_Common_Utils::old_plugin_version_deactivation_cleaning(); |
| 698 | self::schedule_conflict_notice( 'free_pro' ); |
| 699 | |
| 700 | return true; |
| 701 | |
| 702 | } |
| 703 | |
| 704 | return false; |
| 705 | |
| 706 | } |
| 707 | |
| 708 | /** |
| 709 | * Check whether the WOptimize pro is installed on the site. |
| 710 | * |
| 711 | * @return bool True if WOptimize Pro plugin is installed, false otherwise. |
| 712 | */ |
| 713 | public static function is_woptimize_installed() { |
| 714 | |
| 715 | if ( ! function_exists( 'get_plugins' ) ) |
| 716 | include_once( ABSPATH . 'wp-admin/includes/plugin.php' ); |
| 717 | |
| 718 | foreach ( array_keys( get_plugins() ) as $plugin_file ) { |
| 719 | |
| 720 | if ( strpos( $plugin_file, 'woptimize-pro' ) === 0 ) |
| 721 | return true; |
| 722 | |
| 723 | } |
| 724 | |
| 725 | return false; |
| 726 | |
| 727 | } |
| 728 | |
| 729 | /** |
| 730 | * Maybe schedule a conflict notice. |
| 731 | * |
| 732 | * @return void |
| 733 | */ |
| 734 | public static function maybe_schedule_conflict_notice() { |
| 735 | |
| 736 | global $pagenow; |
| 737 | |
| 738 | if ( $pagenow === 'plugins.php' && get_option( self::$conflict_notice_option_key, '' ) !== '' ) { |
| 739 | add_action( 'all_admin_notices', [ self::class, 'render_scheduled_conflict_notice' ] ); |
| 740 | } |
| 741 | |
| 742 | } |
| 743 | |
| 744 | /** |
| 745 | * Persist a conflict notice so it is reliably displayed even after redirects. |
| 746 | * |
| 747 | * @param string $type Conflict type identifier. |
| 748 | * @return void |
| 749 | */ |
| 750 | private static function schedule_conflict_notice( $type ) { |
| 751 | |
| 752 | // Store the last conflict type; it will be rendered (and cleared) on the next admin page load. |
| 753 | update_option( self::$conflict_notice_option_key, $type, false ); |
| 754 | |
| 755 | // Also attempt to render it in the current request when possible. |
| 756 | add_action( 'all_admin_notices', [ self::class, 'render_scheduled_conflict_notice' ] ); |
| 757 | } |
| 758 | |
| 759 | /** |
| 760 | * Render the stored conflict notice (if any) and clear it. |
| 761 | * |
| 762 | * @return void |
| 763 | */ |
| 764 | public static function render_scheduled_conflict_notice() { |
| 765 | |
| 766 | $type = get_option( self::$conflict_notice_option_key, '' ); |
| 767 | |
| 768 | if ( $type === '' ) { |
| 769 | return; |
| 770 | } |
| 771 | |
| 772 | // Clear immediately so the notice is shown only once. |
| 773 | delete_option( self::$conflict_notice_option_key ); |
| 774 | |
| 775 | switch ( $type ) { |
| 776 | case 'free_premium': |
| 777 | self::free_premium_conflict_notice(); |
| 778 | break; |
| 779 | case 'pro_premium': |
| 780 | self::pro_premium_conflict_notice(); |
| 781 | break; |
| 782 | case 'free_pro': |
| 783 | self::free_pro_conflict_notice(); |
| 784 | break; |
| 785 | } |
| 786 | } |
| 787 | |
| 788 | /** |
| 789 | * Display a notice if the free version was deactivated due to the premium version activation. |
| 790 | * |
| 791 | * @return void |
| 792 | */ |
| 793 | public static function free_premium_conflict_notice() { |
| 794 | echo '<div class="notice notice-warning"><p>'; |
| 795 | esc_html_e( 'The free version of Advanced DB Cleaner has been de-activated since the premium version is active.', 'advanced-database-cleaner' ); |
| 796 | echo "</p></div>"; |
| 797 | } |
| 798 | |
| 799 | /** |
| 800 | * Display a notice if the free version was deactivated due to the pro version activation. |
| 801 | * |
| 802 | * @return void |
| 803 | */ |
| 804 | public static function free_pro_conflict_notice() { |
| 805 | echo '<div class="notice notice-warning"><p>'; |
| 806 | esc_html_e( 'The free version of Advanced DB Cleaner has been de-activated since the pro version is active.', 'advanced-database-cleaner' ); |
| 807 | echo "</p></div>"; |
| 808 | } |
| 809 | |
| 810 | /** |
| 811 | * Display a notice if the pro version was deactivated due to the premium version activation. |
| 812 | * |
| 813 | * @return void |
| 814 | */ |
| 815 | public static function pro_premium_conflict_notice() { |
| 816 | echo '<div class="notice notice-warning"><p>'; |
| 817 | esc_html_e( 'The pro version of Advanced DB Cleaner has been de-activated since the newest premium version is active.', 'advanced-database-cleaner' ); |
| 818 | echo "</p></div>"; |
| 819 | } |
| 820 | |
| 821 | /** |
| 822 | * Static proxy for capture_original_plugin_meta_links to be used in the hooks. |
| 823 | * |
| 824 | * @param array $links The current plugin meta links. |
| 825 | * @param string $file The plugin file. |
| 826 | * @return array The modified plugin meta links. |
| 827 | */ |
| 828 | public static function _capture_original_plugin_meta_links( $links, $file ) { |
| 829 | return self::instance()->capture_original_plugin_meta_links( $links, $file ); |
| 830 | } |
| 831 | |
| 832 | /** |
| 833 | * Static proxy for restore_plugin_meta_links to be used in the hooks. |
| 834 | * |
| 835 | * @param array $links The current plugin meta links. |
| 836 | * @param string $file The plugin file. |
| 837 | * @return array The modified plugin meta links. |
| 838 | */ |
| 839 | public static function _restore_plugin_meta_links( $links, $file ) { |
| 840 | return self::instance()->restore_plugin_meta_links( $links, $file ); |
| 841 | } |
| 842 | |
| 843 | /** |
| 844 | * Capture the original WordPress default plugin meta links before any plugin modifies them |
| 845 | */ |
| 846 | public function capture_original_plugin_meta_links( $links, $file ) { |
| 847 | |
| 848 | $plugin_file = plugin_basename( ADBC_MAIN_PLUGIN_FILE_PATH ); |
| 849 | |
| 850 | if ( $file === $plugin_file && empty( $this->original_plugin_meta_links ) ) { |
| 851 | $this->original_plugin_meta_links = $links; |
| 852 | } |
| 853 | |
| 854 | return $links; |
| 855 | |
| 856 | } |
| 857 | |
| 858 | /** |
| 859 | * Remove all third-party links |
| 860 | */ |
| 861 | public function restore_plugin_meta_links( $links, $file ) { |
| 862 | |
| 863 | $plugin_file = plugin_basename( ADBC_MAIN_PLUGIN_FILE_PATH ); |
| 864 | |
| 865 | if ( $file !== $plugin_file ) { |
| 866 | return $links; |
| 867 | } |
| 868 | |
| 869 | return $this->original_plugin_meta_links; |
| 870 | |
| 871 | } |
| 872 | |
| 873 | /** |
| 874 | * Load the plugin text domain for translations. |
| 875 | * |
| 876 | * @return void |
| 877 | */ |
| 878 | public static function load_text_domain() { |
| 879 | load_plugin_textdomain( 'advanced-database-cleaner', false, ADBC_PLUGIN_DIR_NAME . '/languages/' ); |
| 880 | } |
| 881 | |
| 882 | } |