= ! empty( $schemaTypeOptions->software->reviews ) ? $schemaTypeOptions->software->reviews : []; if ( ! empty( $reviews[0] ) ) { $reviewData = json_decode( $reviews[0] ); if ( empty( $reviewData ) ) { break; } $graph['properties']['rating']['value'] = $reviewData->rating; $graph['properties']['review'] = [ 'headline' => $reviewData->headline, 'content' => $reviewData->content, 'author' => $reviewData->author ]; } break; case 'WebPage': if ( 'FAQPage' === $schemaTypeOptions->webPage->webPageType ) { $graph = [ 'id' => '#aioseo-faq-page-' . uniqid(), 'slug' => 'faq-page', 'graphName' => 'FAQPage', 'label' => __( 'FAQ Page', 'all-in-one-seo-pack' ), 'properties' => [ 'type' => $schemaTypeOptions->webPage->webPageType, 'name' => '#post_title', 'description' => '#post_excerpt', 'questions' => [] ] ]; $faqs = $schemaTypeOptions->faq->pages; if ( ! empty( $faqs ) ) { foreach ( $faqs as $faqData ) { $faqData = json_decode( $faqData ); if ( empty( $faqData ) ) { continue; } $graph['properties']['questions'][] = [ 'question' => $faqData->question, 'answer' => $faqData->answer ]; } } } else { $graph = [ 'id' => '#aioseo-web-page-' . uniqid(), 'slug' => 'web-page', 'graphName' => 'WebPage', 'label' => __( 'Web Page', 'all-in-one-seo-pack' ), 'properties' => [ 'type' => $schemaTypeOptions->webPage->webPageType, 'name' => '', 'description' => '' ] ]; } break; case 'default': $dynamicOptions = aioseo()->dynamicOptions->noConflict(); if ( ! empty( $post->post_type ) && $dynamicOptions->searchAppearance->postTypes->has( $post->post_type ) ) { $schemaOptions->defaultGraph = $dynamicOptions->searchAppearance->postTypes->{$post->post_type}->schemaType; } break; case 'none': // If "none', we simply don't have to migrate anything. default: break; } if ( ! empty( $graph ) ) { if ( $isDefault ) { $schemaOptions->default->data->{$schemaType} = $graph; } else { $schemaOptions->graphs[] = $graph; $schemaOptions->default->isEnabled = false; } } $aioseoPost->schema = $schemaOptions; $aioseoPost->save(); return $aioseoPost; } /** * Updates the dashboardWidgets with the new array format. * * @since 4.2.8 * * @return void */ private function migrateDashboardWidgetsOptions() { $rawOptions = $this->getRawOptions(); if ( empty( $rawOptions ) || ! is_bool( $rawOptions['advanced']['dashboardWidgets'] ) ) { return; } $widgets = [ 'seoNews' ]; // If the dashboardWidgets was activated, let's turn on the other widgets. if ( ! empty( $rawOptions['advanced']['dashboardWidgets'] ) ) { $widgets[] = 'seoOverview'; $widgets[] = 'seoSetup'; } aioseo()->options->advanced->dashboardWidgets = $widgets; } /** * Adds the primary_term column to the aioseo_posts table. * * @since 4.3.6 * * @return void */ private function addPrimaryTermColumn() { if ( ! aioseo()->core->db->columnExists( 'aioseo_posts', 'primary_term' ) ) { $tableName = aioseo()->core->db->db->prefix . 'aioseo_posts'; aioseo()->core->db->execute( "ALTER TABLE {$tableName} ADD `primary_term` longtext DEFAULT NULL AFTER `page_analysis`" ); } } /** * Schedules the revision records removal. * * @since 4.3.1 * * @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' ) ] ); } }