isDir()) @rmdir($mpseo_f->getPathname()); else wp_delete_file($mpseo_f->getPathname()); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged,WordPress.WP.AlternativeFunctions.file_system_operations_rmdir -- removes the plugin cache folder. } @rmdir($mpseo_cache_dir); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged,WordPress.WP.AlternativeFunctions.file_system_operations_rmdir -- removes the plugin cache folder. } $mpseo_settings=get_option('mpseo_settings',[]); if(empty($mpseo_settings['delete_data_on_uninstall'])) return; global $wpdb; $mpseo_options=['mpseo_redirect_counts','mpseo_settings','mpseo_plan','mpseo_license','mpseo_ai_usage','mpseo_ai_log','mpseo_rewrite_version','mpseo_v49_db_version','mpseo_import_state','mpseo_import_log','mpseo_v58_integrity','mpseo_schema_version','mpseo_migration_history','mpseo_migration_backups','mpseo_v57_selftest','mpseo_access_caps_version']; foreach($mpseo_options as $mpseo_o) delete_option($mpseo_o); delete_transient('mpseo_llms_txt'); $mpseo_tables=['mpseo_redirects','mpseo_404','mpseo_revisions','mpseo_link_index']; foreach($mpseo_tables as $mpseo_t){ // Table identifiers come exclusively from this fixed internal allowlist. $mpseo_name=$wpdb->prefix.$mpseo_t; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange -- dropping the plugin own tables; the user explicitly opted into uninstall cleanup. $wpdb->query($wpdb->prepare('DROP TABLE IF EXISTS %i', $mpseo_name)); } // Escape the underscore: in SQL LIKE, an unescaped underscore matches any character. $mpseo_meta_prefix=$wpdb->esc_like('_mpseo_').'%'; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- plugin custom table or aggregate query with no core API equivalent; values prepared; admin/maintenance query whose result must be fresh. $wpdb->query($wpdb->prepare("DELETE FROM %i WHERE meta_key LIKE %s",$wpdb->postmeta,$mpseo_meta_prefix)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- plugin custom table or aggregate query with no core API equivalent; values prepared; admin/maintenance query whose result must be fresh. $wpdb->query($wpdb->prepare("DELETE FROM %i WHERE meta_key LIKE %s",$wpdb->termmeta,$mpseo_meta_prefix)); // Cached video details (Video block). // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- removes the plugin own cached transients on uninstall; values prepared. $wpdb->query($wpdb->prepare("DELETE FROM %i WHERE option_name LIKE %s OR option_name LIKE %s",$wpdb->options,$wpdb->esc_like('_transient_mpseo_vid_').'%',$wpdb->esc_like('_transient_timeout_mpseo_vid_').'%'));