* @return void */ private function scheduleRemoveRevisionsRecords() { aioseo()->actionScheduler->scheduleSingle( 'aioseo_v419_remove_revision_records', 10, [], true ); } /** * Casts the priority column to a float. * * @since 4.3.9 * * @return void */ private function migratePriorityColumn() { if ( ! aioseo()->core->db->columnExists( 'aioseo_posts', 'priority' ) ) { return; } $prefix = aioseo()->core->db->prefix; $aioseoPostsTableName = $prefix . 'aioseo_posts'; // First, cast the default value to NULL since it's a string. aioseo()->core->db->execute( "UPDATE {$aioseoPostsTableName} SET priority = NULL WHERE priority = 'default'" ); // Then, alter the column to a float. aioseo()->core->db->execute( "ALTER TABLE {$aioseoPostsTableName} MODIFY priority float" ); } /** * Update the custom robots.txt rules to the new format, * by replacing `rule` and `directoryPath` with `directive` and `fieldValue`, respectively. * * @since 4.4.2 * * @return void */ private function updateRobotsTxtRules() { $rawOptions = $this->getRawOptions(); $currentRules = $rawOptions && ! empty( $rawOptions['tools']['robots']['rules'] ) ? $rawOptions['tools']['robots']['rules'] : []; if ( empty( $currentRules ) || ! is_array( $currentRules ) ) { return; } $newRules = []; foreach ( $currentRules as $oldRule ) { $parsedRule = json_decode( $oldRule, true ); if ( empty( $parsedRule['rule'] ) && empty( $parsedRule['directoryPath'] ) ) { continue; } $newRule = [ 'userAgent' => array_key_exists( 'userAgent', $parsedRule ) ? $parsedRule['userAgent'] : '', 'directive' => array_key_exists( 'rule', $parsedRule ) ? $parsedRule['rule'] : '', 'fieldValue' => array_key_exists( 'directoryPath', $parsedRule ) ? $parsedRule['directoryPath'] : '', ]; $newRules[] = wp_json_encode( $newRule ); } if ( $newRules ) { aioseo()->options->tools->robots->rules = $newRules; } } /** * Checks if the user is currently using the old GA Analytics v3 integration and create a notification. * * @since 4.5.1 * * @return void */ private function checkForGaAnalyticsV3() { // If either MonsterInsights or ExactMetrics is active, let's return early. $pluginData = aioseo()->helpers->getPluginData(); if ( $pluginData['miPro']['activated'] || $pluginData['miLite']['activated'] || $pluginData['emPro']['activated'] || $pluginData['emLite']['activated'] ) { return; } $rawOptions = $this->getRawOptions(); if ( empty( $rawOptions['deprecated']['webmasterTools']['googleAnalytics']['id'] ) ) { return; } // Let's clear the notification if the search is working again. $notification = Models\Notification::getNotificationByName( 'google-analytics-v3-deprecation' ); if ( $notification->exists() ) { $notification->dismissed = false; $notification->save(); return; } // Determine which plugin name to use. $pluginName = 'MonsterInsights'; if ( ( $pluginData['emPro']['installed'] || $pluginData['emLite']['installed'] ) && ! $pluginData['miPro']['installed'] && ! $pluginData['miLite']['installed'] ) { $pluginName = 'ExactMetrics'; } Models\Notification::addNotification( [ 'slug' => uniqid(), 'notification_name' => 'google-analytics-v3-deprecation', 'title' => __( 'Universal Analytics V3 Deprecation Notice', 'all-in-one-seo-pack' ), 'content' => sprintf( // Translators: 1 - Line break HTML tags, 2 - Plugin short name ("AIOSEO"), Analytics plugin name (e.g. "MonsterInsights"). __( 'You have been using the %2$s Google Analytics V3 (Universal Analytics) integration which has been deprecated by Google and is no longer supported. This may affect your website\'s data accuracy and performance.%1$sTo ensure a seamless analytics experience, we recommend migrating to %3$s, a powerful analytics solution.%1$s%3$s offers advanced features such as real-time tracking, enhanced e-commerce analytics, and easy-to-understand reports, helping you make informed decisions to grow your online presence effectively.%1$sClick the button below to be redirected to the %3$s setup process, where you can start benefiting from its robust analytics capabilities immediately.', 'all-in-one-seo-pack' ), // phpcs:ignore Generic.Files.LineLength.MaxExceeded '

', AIOSEO_PLUGIN_SHORT_NAME, $pluginName ), 'type' => 'error', 'level' => [ 'all' ], 'button1_label' => __( 'Fix Now', 'all-in-one-seo-pack' ), 'button1_action' => admin_url( 'admin.php?page=aioseo-monsterinsights' ), 'start' => gmdate( 'Y-m-d H:i:s' ) ] ); } /** * Adds our custom tables for the query arg monitor. * * @since 4.5.8 * * @return void */ public function addQueryArgMonitorTables() { $db = aioseo()->core->db->db; $charsetCollate = ''; if ( ! empty( $db->charset ) ) { $charsetCollate .= "DEFAULT CHARACTER SET {$db->charset}"; } if ( ! empty( $db->collate ) ) { $charsetCollate .= " COLLATE {$db->collate}"; } // Check for crawl cleanup logs table. if ( ! aioseo()->core->db->tableExists( 'aioseo_crawl_cleanup_logs' ) ) { $tableName = $db->prefix . 'aioseo_crawl_cleanup_logs'; aioseo()->core->db->execute( "CREATE TABLE {$tableName} ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `slug` text NOT NULL, `key` text NOT NULL, `value` text, `hash` varchar(40) NOT NULL, `hits` int(20) NOT NULL DEFAULT 1, `created` datetime NOT NULL, `updated` datetime NOT NULL, PRIMARY KEY (id), UNIQUE KEY ndx_aioseo_crawl_cleanup_logs_hash (hash) ) {$charsetCollate};" ); } // Check for crawl cleanup blocked table. if ( ! aioseo()->core->db->tableExists( 'aioseo_crawl_cleanup_blocked_args' ) ) { $tableName = $db->prefix . 'aioseo_crawl_cleanup_blocked_args'; aioseo()->core->db->execute( "CREATE TABLE {$tableName} ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `key` text, `value` text, `key_value_hash` varchar(40), `regex` varchar(150), `hits` int(20) NOT NULL DEFAULT 0, `created` datetime NOT NULL, `updated` datetime NOT NULL, PRIMARY KEY (id), UNIQUE KEY ndx_aioseo_crawl_cleanup_blocked_args_key_value_hash (key_value_hash), UNIQUE KEY ndx_aioseo_crawl_cleanup_blocked_args_regex (regex) ) {$charsetCollate};" ); } } /** * Adds a notification for the query arg monitor. * * @since 4.5.8 * * @return void */ private function addQueryArgMonitorNotification() { $options = $this->getRawOptions(); if ( empty( $options['searchAppearance']['advanced']['crawlCleanup']['enable'] ) || empty( $options['searchAppearance']['advanced']['crawlCleanup']['removeUnrecognizedQueryArgs'] ) ) { return; } $notification = Models\Notification::getNotificationByName( 'crawl-cleanup-updated' ); if ( $notification->exists() ) { return; } Models\Notification::addNotification( [ 'slug' => uniqid(), 'notification_name' => 'crawl-cleanup-updated', 'title' => __( 'Crawl Cleanup changes you should know about', 'all-in-one-seo-pack' ), 'content' => __( 'We\'ve made some significant changes to how we monitor Query Args for our Crawl Cleanup feature. Instead of DISABLING all query args and requiring you to add individual exceptions, we\'ve now changed it to ALLOW all query args by default with the option to easily block unrecognized ones through our new log table.', 'all-in-one-seo-pack' ), // phpcs:ignore Generic.Files.LineLength.MaxExceeded 'type' => 'info', 'level' => [ 'all' ], 'button1_label' => __( 'Learn More', 'all-in-one-seo-pack' ), 'button1_action' => 'http://route#aioseo-search-appearance&aioseo-scroll=aioseo-query-arg-monitoring&aioseo-highlight=aioseo-query-arg-monitoring:advanced', 'start' => gmdate( 'Y-m-d H:i:s' ) ] ); } /** * Deprecates the "No Pagination for Canonical URLs" setting. * * @since 4.5.9 * * @return void */ public function deprecateNoPaginationForCanonicalUrlsSetting() { $options = $this->getRawOptions(); if ( empty( $options['searchAppearance']['advanced']['noPaginationForCanonical'] ) ) { return; } $deprecatedOptions = aioseo()->internalOptions->deprecatedOptions; if ( ! in_array( 'noPaginationForCanonical', $deprecatedOptions, true ) ) { $deprecatedOptions[] = 'noPaginationForCanonical'; aioseo()->internalOptions->deprecatedOptions = $deprecatedOptions; } aioseo()->options->deprecated->searchAppearance->advanced->noPaginationForCanonical = true; } /** * Deprecates the "Breadcrumbs enabled" setting. * * @since 4.6.5 * * @return void */ public function deprecateBreadcrumbsEnabledSetting() { $options = $this->getRawOptions(); if ( ! isset( $options['breadcrumbs']['enable'] ) || 1 === intval( $options['breadcrumbs']['enable'] ) ) { return; } $deprecatedOptions = aioseo()->internalOptions->deprecatedOptions; if ( ! in_array( 'breadcrumbsEnable', $deprecatedOptions, true ) ) { $deprecatedOptions[] = 'breadcrumbsEnable'; aioseo()->internalOptions->deprecatedOptions = $deprecatedOptions; } aioseo()->options->deprecated->breadcrumbs->enable = false; } /** * Add tables for Writing Assistant. * * @since 4.7.4 * * @return void */ private function addWritingAssistantTables() { $db = aioseo()->core->db->db; $charsetCollate = ''; if ( ! empty( $db->charset ) ) { $charsetCollate .= "DEFAULT CHARACTER SET {$db->charset}"; } if ( ! empty( $db->collate ) ) { $charsetCollate .= " COLLATE {$db->collate}"; } if ( ! aioseo()->core->db->tableExists( 'aioseo_writing_assistant_posts' ) ) { $tableName = $db->prefix . 'aioseo_writing_assistant_posts'; aioseo()->core->db->execute( "CREATE TABLE {$tableName} ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `post_id` bigint(20) unsigned DEFAULT NULL, `keyword_id` bigint(20) unsigned DEFAULT NULL, `content_analysis_hash` VARCHAR(40) DEFAULT NULL, `content_analysis` text DEFAULT NULL, `created` datetime NOT NULL, `updated` datetime NOT NULL, PRIMARY KEY (id), UNIQUE KEY ndx_aioseo_writing_assistant_posts_post_id (post_id), KEY ndx_aioseo_writing_assistant_posts_keyword_id (keyword_id) ) {$charsetCollate};" ); } if ( ! aioseo()->core->db->tableExists( 'aioseo_writing_assistant_keywords' ) ) { $tableName = $db->prefix . 'aioseo_writing_assistant_keywords'; aioseo()->core->db->execute( "CREATE TABLE {$tableName} ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `uuid` varchar(40) NOT NULL, `keyword` varchar(255) NOT NULL, `country` varchar(10) NOT NULL DEFAULT 'us', `language` varchar(10) NOT NULL DEFAULT 'en', `progress` tinyint(3) DEFAULT 0, `keywords` mediumtext NULL, `competitors` mediumtext NULL, `created` datetime NOT NULL, `updated` datetime NOT NULL, PRIMARY KEY (id), UNIQUE KEY ndx_aioseo_writing_assistant_keywords_uuid (uuid), KEY ndx_aioseo_writing_assistant_keywords_keyword (keyword) ) {$charsetCollate};" ); } } /** * Cancels all outstanding sitemap ping actions. * This is needed because we've removed the Ping class. * * @since 4.7.5 * * @return void */ private function cancelScheduledSitemapPings() { as_unschedule_all_actions( 'aioseo_sitemap_ping' ); as_unschedule_all_actions( 'aioseo_sitemap_ping_recurring' ); } /** * Disable email reports. * * @since 4.7.7 * * @return void */ private function disableEmailReports() { aioseo()->options->advanced->emailSummary->enable = false; // Schedule a notification to remind the user to enable email reports in 2 weeks. aioseo()->actionScheduler->scheduleSingle( 'aioseo_email_reports_enable_reminder', 2 * WEEK_IN_SECONDS ); } /** * Cancels all occurrences of the report summary task. * This is needed in order to force the scheduled date to be reset. * * @since 4.7.9 * * @return void */ private function rescheduleEmailReport() { as_unschedule_all_actions( aioseo()->emailReports->summary->actionHook ); } /** * Fixes headlines that could not be analyzed. * * @since 4.7.9 * * @return void */ private function fixSavedHeadlines() { $headlines = aioseo()->internalOptions->internal->headlineAnalysis->headlines; if ( empty( $headlines ) ) { return; } foreach ( $headlines as $key => $headline ) { if ( ! json_decode( $headline ) ) { unset( $headlines[ $key ] ); } } aioseo()->internalOptions->internal->headlineAnalysis->headlines = $headlines; } }