Initial commit: Atomaste website
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
namespace AIOSEO\Plugin\Common\Migration;
|
||||
|
||||
// Exit if accessed directly.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
// phpcs:disable WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound
|
||||
|
||||
/**
|
||||
* Migrates the Bad Robots Blocker settings from V3.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
class BadRobots {
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public function __construct() {
|
||||
$oldOptions = aioseo()->migration->oldOptions;
|
||||
|
||||
$deprecatedOptions = aioseo()->internalOptions->internal->deprecatedOptions;
|
||||
array_push( $deprecatedOptions, 'badBotBlocker' );
|
||||
aioseo()->internalOptions->internal->deprecatedOptions = $deprecatedOptions;
|
||||
|
||||
if ( empty( $oldOptions['modules']['aiosp_bad_robots_options'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! empty( $oldOptions['modules']['aiosp_bad_robots_options']['aiosp_bad_robots_blocklist'] ) ) {
|
||||
$badBots = explode( '\r\n', $oldOptions['modules']['aiosp_bad_robots_options']['aiosp_bad_robots_blocklist'] );
|
||||
if ( $badBots ) {
|
||||
foreach ( $badBots as $k => $v ) {
|
||||
$badBots[ $k ] = aioseo()->helpers->sanitizeOption( $v );
|
||||
}
|
||||
aioseo()->options->deprecated->tools->blocker->custom->bots = implode( "\r\n", $badBots );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $oldOptions['modules']['aiosp_bad_robots_options']['aiosp_bad_robots_referlist'] ) ) {
|
||||
$badReferers = explode( '\r\n', $oldOptions['modules']['aiosp_bad_robots_options']['aiosp_bad_robots_referlist'] );
|
||||
if ( $badReferers ) {
|
||||
foreach ( $badReferers as $k => $v ) {
|
||||
$badReferers[ $k ] = aioseo()->helpers->sanitizeOption( $v );
|
||||
}
|
||||
aioseo()->options->deprecated->tools->blocker->custom->referer = implode( "\r\n", $badReferers );
|
||||
}
|
||||
}
|
||||
|
||||
$settings = [
|
||||
'aiosp_bad_robots_block_bots' => [ 'type' => 'boolean', 'newOption' => [ 'deprecated', 'tools', 'blocker', 'blockBots' ] ],
|
||||
'aiosp_bad_robots_block_refer' => [ 'type' => 'boolean', 'newOption' => [ 'deprecated', 'tools', 'blocker', 'blockReferer' ] ],
|
||||
'aiosp_bad_robots_track_blocks' => [ 'type' => 'boolean', 'newOption' => [ 'deprecated', 'tools', 'blocker', 'track' ] ],
|
||||
'aiosp_bad_robots_edit_blocks' => [ 'type' => 'boolean', 'newOption' => [ 'deprecated', 'tools', 'blocker', 'custom', 'enable' ] ],
|
||||
];
|
||||
|
||||
aioseo()->migration->helpers->mapOldToNew( $settings, $oldOptions['modules']['aiosp_bad_robots_options'] );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,881 @@
|
||||
<?php
|
||||
namespace AIOSEO\Plugin\Common\Migration;
|
||||
|
||||
// Exit if accessed directly.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
use AIOSEO\Plugin\Common\Models;
|
||||
|
||||
// phpcs:disable WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound
|
||||
|
||||
/**
|
||||
* Migrates the General Settings from V3.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
class GeneralSettings {
|
||||
/**
|
||||
* The old V3 options.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $oldOptions = [];
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->oldOptions = aioseo()->migration->oldOptions;
|
||||
|
||||
$this->migrateSeparatorCharacter();
|
||||
$this->setDefaultArticleType();
|
||||
$this->migrateHomePageMeta();
|
||||
$this->migrateTitleFormats();
|
||||
$this->migrateDescriptionFormat();
|
||||
$this->migrateNoindexSettings();
|
||||
$this->migrateNofollowSettings();
|
||||
$this->migratePostSeoColumns();
|
||||
$this->migrateSocialUrls();
|
||||
$this->migrateSchemaMarkupSettings();
|
||||
$this->migrateHomePageKeywords();
|
||||
$this->migrateDeprecatedAdvancedOptions();
|
||||
$this->migrateRssContentSettings();
|
||||
$this->migrateRedirectToParent();
|
||||
$this->migrateDisabledPosts();
|
||||
$this->migrateNoPaginationForCanonicalUrls();
|
||||
|
||||
$settings = [
|
||||
'aiosp_admin_bar' => [ 'type' => 'boolean', 'newOption' => [ 'advanced', 'adminBarMenu' ] ],
|
||||
'aiosp_google_verify' => [ 'type' => 'string', 'newOption' => [ 'webmasterTools', 'google' ] ],
|
||||
'aiosp_bing_verify' => [ 'type' => 'string', 'newOption' => [ 'webmasterTools', 'bing' ] ],
|
||||
'aiosp_pinterest_verify' => [ 'type' => 'string', 'newOption' => [ 'webmasterTools', 'pinterest' ] ],
|
||||
'aiosp_yandex_verify' => [ 'type' => 'string', 'newOption' => [ 'webmasterTools', 'yandex' ] ],
|
||||
'aiosp_baidu_verify' => [ 'type' => 'string', 'newOption' => [ 'webmasterTools', 'baidu' ] ],
|
||||
'aiosp_schema_site_represents' => [ 'type' => 'string', 'newOption' => [ 'searchAppearance', 'global', 'schema', 'siteRepresents' ] ],
|
||||
'aiosp_schema_organization_name' => [ 'type' => 'string', 'newOption' => [ 'searchAppearance', 'global', 'schema', 'organizationName' ] ],
|
||||
'aiosp_schema_person_manual_name' => [ 'type' => 'string', 'newOption' => [ 'searchAppearance', 'global', 'schema', 'personName' ] ],
|
||||
'aiosp_schema_organization_logo' => [ 'type' => 'string', 'newOption' => [ 'searchAppearance', 'global', 'schema', 'organizationLogo' ] ],
|
||||
'aiosp_schema_person_manual_image' => [ 'type' => 'string', 'newOption' => [ 'searchAppearance', 'global', 'schema', 'personLogo' ] ],
|
||||
'aiosp_togglekeywords' => [ 'type' => 'boolean', 'newOption' => [ 'searchAppearance', 'advanced', 'useKeywords' ] ],
|
||||
'aiosp_use_categories' => [ 'type' => 'boolean', 'newOption' => [ 'searchAppearance', 'advanced', 'useCategoriesForMetaKeywords' ] ],
|
||||
'aiosp_use_tags_as_keywords' => [ 'type' => 'boolean', 'newOption' => [ 'searchAppearance', 'advanced', 'useTagsForMetaKeywords' ] ],
|
||||
'aiosp_dynamic_postspage_keywords' => [ 'type' => 'boolean', 'newOption' => [ 'searchAppearance', 'advanced', 'dynamicallyGenerateKeywords' ] ],
|
||||
'aiosp_run_shortcodes' => [ 'type' => 'boolean', 'newOption' => [ 'searchAppearance', 'advanced', 'runShortcodes' ] ]
|
||||
];
|
||||
|
||||
aioseo()->migration->helpers->mapOldToNew( $settings, aioseo()->migration->oldOptions );
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates the separator character.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function migrateSeparatorCharacter() {
|
||||
aioseo()->options->searchAppearance->global->separator = '|';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default posts schema type to Article.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function setDefaultArticleType() {
|
||||
if ( aioseo()->dynamicOptions->searchAppearance->postTypes->has( 'post' ) ) {
|
||||
aioseo()->dynamicOptions->searchAppearance->postTypes->post->articleType = 'Article';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates the homepage meta.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function migrateHomePageMeta() {
|
||||
$this->migrateHomePageTitle();
|
||||
$this->migrateHomePageDescription();
|
||||
|
||||
// If the homepage is a static one, we should migrate the meta now.
|
||||
$showOnFront = get_option( 'show_on_front' );
|
||||
$pageOnFront = (int) get_option( 'page_on_front' );
|
||||
if ( 'page' !== $showOnFront || ! $pageOnFront ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$post = 'page' === $showOnFront && $pageOnFront ? get_post( $pageOnFront ) : '';
|
||||
$aioseoPost = Models\Post::getPost( $post->ID );
|
||||
|
||||
$postMeta = aioseo()->core->db
|
||||
->start( 'postmeta' . ' as pm' )
|
||||
->select( 'pm.meta_key, pm.meta_value' )
|
||||
->where( 'pm.post_id', $post->ID )
|
||||
->whereRaw( "`pm`.`meta_key` LIKE '_aioseop_%'" )
|
||||
->run()
|
||||
->result();
|
||||
|
||||
$mappedMeta = [
|
||||
'_aioseop_nofollow' => 'robots_nofollow',
|
||||
'_aioseop_sitemap_priority' => 'priority',
|
||||
'_aioseop_sitemap_frequency' => 'frequency',
|
||||
'_aioseop_keywords' => 'keywords',
|
||||
'_aioseop_opengraph_settings' => '',
|
||||
];
|
||||
|
||||
$meta = [
|
||||
'post_id' => $post->ID,
|
||||
];
|
||||
|
||||
foreach ( $postMeta as $record ) {
|
||||
$name = $record->meta_key;
|
||||
$value = $record->meta_value;
|
||||
|
||||
if ( ! in_array( $name, array_keys( $mappedMeta ), true ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch ( $name ) {
|
||||
case '_aioseop_nofollow':
|
||||
$meta[ $mappedMeta[ $name ] ] = ! empty( $value );
|
||||
if ( ! empty( $value ) ) {
|
||||
$meta['robots_default'] = false;
|
||||
}
|
||||
break;
|
||||
case '_aioseop_keywords':
|
||||
$meta[ $mappedMeta[ $name ] ] = aioseo()->migration->helpers->oldKeywordsToNewKeywords( $value );
|
||||
break;
|
||||
case '_aioseop_opengraph_settings':
|
||||
$class = new Meta();
|
||||
$meta += $class->convertOpenGraphMeta( $value );
|
||||
|
||||
// We'll deal with the OG title/description in the Social Meta migration class.
|
||||
if ( isset( $meta['og_title'] ) ) {
|
||||
unset( $meta['og_title'] );
|
||||
}
|
||||
if ( isset( $meta['og_description'] ) ) {
|
||||
unset( $meta['og_description'] );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$meta[ $mappedMeta[ $name ] ] = aioseo()->helpers->sanitizeOption( $value );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$aioseoPost->set( $meta );
|
||||
$aioseoPost->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates the homepage title.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function migrateHomePageTitle() {
|
||||
$showOnFront = get_option( 'show_on_front' );
|
||||
$pageOnFront = (int) get_option( 'page_on_front' );
|
||||
|
||||
$homePageTitle = ! empty( $this->oldOptions['aiosp_home_title'] ) ? $this->oldOptions['aiosp_home_title'] : '';
|
||||
$format = $this->oldOptions['aiosp_home_page_title_format'];
|
||||
|
||||
if ( 'posts' === $showOnFront ) {
|
||||
$homePageTitle = $homePageTitle ? $homePageTitle : get_bloginfo( 'name' );
|
||||
$title = empty( $format ) ? $homePageTitle : aioseo()->helpers->pregReplace( '#%page_title%#', $homePageTitle, $format );
|
||||
$title = aioseo()->migration->helpers->macrosToSmartTags( $title );
|
||||
aioseo()->options->searchAppearance->global->siteTitle = aioseo()->helpers->sanitizeOption( $title );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the setting globally regardless of what happens below.
|
||||
if ( ! empty( $homePageTitle ) ) {
|
||||
$title = aioseo()->migration->helpers->macrosToSmartTags( aioseo()->helpers->pregReplace( '#%page_title%#', $homePageTitle, $format ) );
|
||||
aioseo()->options->searchAppearance->global->siteTitle = aioseo()->helpers->sanitizeOption( $title );
|
||||
}
|
||||
|
||||
$post = 'page' === $showOnFront && $pageOnFront ? get_post( $pageOnFront ) : '';
|
||||
$metaTitle = get_post_meta( $post->ID, '_aioseop_title', true );
|
||||
|
||||
$homePageTitle = '';
|
||||
if ( empty( $this->oldOptions['aiosp_use_static_home_info'] ) ) {
|
||||
$homePageTitle = ! empty( $this->oldOptions['aiosp_home_title'] ) ? $this->oldOptions['aiosp_home_title'] : '#site_title';
|
||||
$homePageTitle = ! empty( $metaTitle ) ? $metaTitle : $homePageTitle;
|
||||
$homePageTitle = empty( $format ) ? $homePageTitle : aioseo()->helpers->pregReplace( '#%page_title%#', $homePageTitle, $format );
|
||||
$homePageTitle = aioseo()->migration->helpers->macrosToSmartTags( $homePageTitle );
|
||||
} else {
|
||||
if ( ! empty( $metaTitle ) ) {
|
||||
$homePageTitle = empty( $format ) ? $metaTitle : aioseo()->helpers->pregReplace( '#%page_title%#', $metaTitle, $format );
|
||||
$homePageTitle = aioseo()->migration->helpers->macrosToSmartTags( $homePageTitle );
|
||||
}
|
||||
}
|
||||
|
||||
$aioseoPost = Models\Post::getPost( $post->ID );
|
||||
$aioseoPost->set( [
|
||||
'post_id' => $post->ID,
|
||||
'title' => aioseo()->helpers->sanitizeOption( $homePageTitle )
|
||||
] );
|
||||
$aioseoPost->save();
|
||||
|
||||
$this->maybeShowHomePageTitleNotice( $post );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if we should display a notice warning users that their homepage title may have changed.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @param \WP_Post $post The post object.
|
||||
* @return void
|
||||
*/
|
||||
private function maybeShowHomePageTitleNotice( $post ) {
|
||||
$metaTitle = get_post_meta( $post->ID, '_aioseop_title', true );
|
||||
$homePageTitle = ! empty( $this->oldOptions['aiosp_home_title'] ) ? $this->oldOptions['aiosp_home_title'] : '';
|
||||
|
||||
if (
|
||||
empty( $this->oldOptions['aiosp_use_static_home_info'] ) &&
|
||||
$metaTitle &&
|
||||
( trim( $homePageTitle ) !== trim( $metaTitle ) )
|
||||
) {
|
||||
$this->showHomePageSettingsNotice();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates the homepage description.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function migrateHomePageDescription() {
|
||||
$showOnFront = get_option( 'show_on_front' );
|
||||
$pageOnFront = (int) get_option( 'page_on_front' );
|
||||
|
||||
$homePageDescription = ! empty( $this->oldOptions['aiosp_home_description'] ) ? $this->oldOptions['aiosp_home_description'] : '';
|
||||
$format = $this->oldOptions['aiosp_description_format'];
|
||||
|
||||
if ( 'posts' === $showOnFront ) {
|
||||
// If the description had the page_title macro, we want to replace it with the actual page title itself.
|
||||
$homePageDescription = $homePageDescription ? $homePageDescription : get_bloginfo( 'description' );
|
||||
$homePageTitle = ! empty( $this->oldOptions['aiosp_home_title'] ) ? $this->oldOptions['aiosp_home_title'] : get_bloginfo( 'name' );
|
||||
$format = aioseo()->helpers->pregReplace( '#%page_title%#', $homePageTitle, $format );
|
||||
$description = empty( $format ) ? $homePageDescription : aioseo()->helpers->pregReplace( '#%description%#', $homePageDescription, $format );
|
||||
$description = aioseo()->migration->helpers->macrosToSmartTags( $description );
|
||||
aioseo()->options->searchAppearance->global->metaDescription = aioseo()->helpers->sanitizeOption( $description );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the setting globally regardless of what happens below.
|
||||
if ( ! empty( $homePageDescription ) ) {
|
||||
$homePageTitle = ! empty( $this->oldOptions['aiosp_home_title'] ) ? $this->oldOptions['aiosp_home_title'] : get_bloginfo( 'name' );
|
||||
$format = aioseo()->helpers->pregReplace( '#%page_title%#', $homePageTitle, $format );
|
||||
$description = aioseo()->migration->helpers->macrosToSmartTags( aioseo()->helpers->pregReplace( '#%description%#', $homePageDescription, $format ) );
|
||||
aioseo()->options->searchAppearance->global->metaDescription = aioseo()->helpers->sanitizeOption( $description );
|
||||
}
|
||||
|
||||
$post = 'page' === $showOnFront && $pageOnFront ? get_post( $pageOnFront ) : '';
|
||||
$metaDescription = get_post_meta( $post->ID, '_aioseop_description', true );
|
||||
|
||||
$homePageDescription = '';
|
||||
if ( empty( $this->oldOptions['aiosp_use_static_home_info'] ) ) {
|
||||
$homePageDescription = ! empty( $this->oldOptions['aiosp_home_description'] ) ? $this->oldOptions['aiosp_home_description'] : '';
|
||||
$homePageDescription = ! empty( $metaDescription ) ? $metaDescription : $homePageDescription;
|
||||
} else {
|
||||
if ( ! empty( $metaDescription ) ) {
|
||||
$homePageDescription = empty( $format ) ? $metaDescription : aioseo()->helpers->pregReplace( '#%description%#', $metaDescription, $format );
|
||||
$homePageDescription = aioseo()->migration->helpers->macrosToSmartTags( $homePageDescription );
|
||||
}
|
||||
}
|
||||
|
||||
$homePageDescription = empty( $format ) ? $homePageDescription : aioseo()->helpers->pregReplace( '#(%description%|%page_title%)#', $homePageDescription, $format );
|
||||
$homePageDescription = aioseo()->migration->helpers->macrosToSmartTags( $homePageDescription );
|
||||
|
||||
$aioseoPost = Models\Post::getPost( $post->ID );
|
||||
$aioseoPost->set( [
|
||||
'post_id' => $post->ID,
|
||||
'description' => aioseo()->helpers->sanitizeOption( $homePageDescription )
|
||||
] );
|
||||
$aioseoPost->save();
|
||||
|
||||
$this->maybeShowHomePageDescriptionNotice( $post );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if we should display a notice warning users that their homepage title may have changed.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @param \WP_Post $post The post object.
|
||||
* @return void
|
||||
*/
|
||||
private function maybeShowHomePageDescriptionNotice( $post ) {
|
||||
$metaDescription = get_post_meta( $post->ID, '_aioseop_description', true );
|
||||
$homePageDescription = ! empty( $this->oldOptions['aiosp_home_description'] ) ? $this->oldOptions['aiosp_home_description'] : '';
|
||||
|
||||
if (
|
||||
empty( $this->oldOptions['aiosp_use_static_home_info'] ) &&
|
||||
$metaDescription &&
|
||||
( trim( $homePageDescription ) !== trim( $metaDescription ) )
|
||||
) {
|
||||
$this->showHomePageSettingsNotice();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the homepage settings notice.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function showHomePageSettingsNotice() {
|
||||
$notification = Models\Notification::getNotificationByName( 'v3-migration-homepage-settings' );
|
||||
if ( $notification->notification_name ) {
|
||||
return;
|
||||
}
|
||||
|
||||
Models\Notification::addNotification( [
|
||||
'slug' => uniqid(),
|
||||
'notification_name' => 'v3-migration-homepage-settings',
|
||||
'title' => __( 'Review Your Homepage Title & Description', 'all-in-one-seo-pack' ),
|
||||
'content' => sprintf(
|
||||
// Translators: 1 - All in One SEO.
|
||||
__( 'Due to a bug in the previous version of %1$s, your homepage title and description may have changed. Please take a minute to review your homepage settings to verify that they are correct.', 'all-in-one-seo-pack' ), // phpcs:ignore Generic.Files.LineLength.MaxExceeded
|
||||
AIOSEO_PLUGIN_NAME
|
||||
),
|
||||
'type' => 'warning',
|
||||
'level' => [ 'all' ],
|
||||
'button1_label' => __( 'Review Now', 'all-in-one-seo-pack' ),
|
||||
'button1_action' => 'http://route#aioseo-search-appearance&aioseo-scroll=home-page-settings&aioseo-highlight=home-page-settings:global-settings',
|
||||
'start' => gmdate( 'Y-m-d H:i:s' )
|
||||
] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates the title formats.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function migrateTitleFormats() {
|
||||
if ( ! empty( $this->oldOptions['aiosp_archive_title_format'] ) ) {
|
||||
$archives = array_keys( aioseo()->dynamicOptions->searchAppearance->archives->all() );
|
||||
$format = aioseo()->helpers->sanitizeOption( aioseo()->migration->helpers->macrosToSmartTags( $this->oldOptions['aiosp_archive_title_format'] ) );
|
||||
foreach ( $archives as $archive ) {
|
||||
aioseo()->dynamicOptions->searchAppearance->archives->$archive->title = $format;
|
||||
}
|
||||
}
|
||||
|
||||
$settings = [
|
||||
'aiosp_post_title_format' => [ 'type' => 'string', 'newOption' => [ 'searchAppearance', 'postTypes', 'post', 'title' ], 'dynamic' => true ],
|
||||
'aiosp_page_title_format' => [ 'type' => 'string', 'newOption' => [ 'searchAppearance', 'postTypes', 'page', 'title' ], 'dynamic' => true ],
|
||||
'aiosp_attachment_title_format' => [ 'type' => 'string', 'newOption' => [ 'searchAppearance', 'postTypes', 'attachment', 'title' ], 'dynamic' => true ],
|
||||
'aiosp_category_title_format' => [ 'type' => 'string', 'newOption' => [ 'searchAppearance', 'taxonomies', 'category', 'title' ], 'dynamic' => true ],
|
||||
'aiosp_tag_title_format' => [ 'type' => 'string', 'newOption' => [ 'searchAppearance', 'taxonomies', 'post_tag', 'title' ], 'dynamic' => true ],
|
||||
'aiosp_date_title_format' => [ 'type' => 'string', 'newOption' => [ 'searchAppearance', 'archives', 'date', 'title' ] ],
|
||||
'aiosp_author_title_format' => [ 'type' => 'string', 'newOption' => [ 'searchAppearance', 'archives', 'author', 'title' ] ],
|
||||
'aiosp_search_title_format' => [ 'type' => 'string', 'newOption' => [ 'searchAppearance', 'archives', 'search', 'title' ] ],
|
||||
'aiosp_paged_format' => [ 'type' => 'string', 'newOption' => [ 'searchAppearance', 'advanced', 'pagedFormat' ] ]
|
||||
];
|
||||
|
||||
foreach ( $this->oldOptions as $name => $value ) {
|
||||
if (
|
||||
! in_array( $name, array_keys( $settings ), true ) &&
|
||||
preg_match( '#aiosp_(.*)_title_format#', (string) $name, $slug )
|
||||
) {
|
||||
if ( empty( $slug[1] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$objectSlug = aioseo()->helpers->pregReplace( '#_tax#', '', $slug[1] );
|
||||
if ( in_array( $objectSlug, aioseo()->helpers->getPublicPostTypes( true ), true ) ) {
|
||||
$settings[ $name ] = [ 'type' => 'string', 'newOption' => [ 'searchAppearance', 'postTypes', $objectSlug, 'title' ], 'dynamic' => true ];
|
||||
continue;
|
||||
}
|
||||
if ( in_array( $objectSlug, aioseo()->helpers->getPublicTaxonomies( true ), true ) ) {
|
||||
$settings[ $name ] = [ 'type' => 'string', 'newOption' => [ 'searchAppearance', 'taxonomies', $objectSlug, 'title' ], 'dynamic' => true ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aioseo()->migration->helpers->mapOldToNew( $settings, $this->oldOptions, true );
|
||||
|
||||
// Check if any of the title formats were empty and register a notification if so.
|
||||
$found = false;
|
||||
foreach ( $settings as $k => $v ) {
|
||||
if ( 'aiosp_home_page_title_format' === $k ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( isset( $this->oldOptions[ $k ] ) && empty( $this->oldOptions[ $k ] ) ) {
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $found ) {
|
||||
Models\Notification::deleteNotificationByName( 'v3-migration-title-formats-blank' );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$notification = Models\Notification::getNotificationByName( 'v3-migration-title-formats-blank' );
|
||||
if ( $notification->notification_name ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$p1 = sprintf(
|
||||
// Translators: 1 - The plugin short name ("AIOSEO"), 2 - The plugin short name ("AIOSEO"), 3 - Opening link tag, 4 - Closing link tag.
|
||||
__( '%1$s migrated all your title formats, some of which were blank. If you were purposely using blank formats in the previous version of %2$s and want WordPress to handle your titles, you can safely dismiss this message. For more information, check out our documentation on %3$sblank title formats%4$s.', 'all-in-one-seo-pack' ), // phpcs:ignore Generic.Files.LineLength.MaxExceeded
|
||||
AIOSEO_PLUGIN_SHORT_NAME,
|
||||
AIOSEO_PLUGIN_SHORT_NAME,
|
||||
'<a href="' . aioseo()->helpers->utmUrl( AIOSEO_MARKETING_URL . '/docs/blank-title-formats-detected', 'notifications-center', 'v3-migration-title-formats-blank' ) . '">',
|
||||
'</a>'
|
||||
);
|
||||
|
||||
Models\Notification::addNotification( [
|
||||
'slug' => uniqid(),
|
||||
'notification_name' => 'v3-migration-title-formats-blank',
|
||||
'title' => __( 'Blank Title Formats Detected', 'all-in-one-seo-pack' ),
|
||||
'content' => $p1,
|
||||
'type' => 'warning',
|
||||
'level' => [ 'all' ],
|
||||
'button1_label' => __( 'Learn More', 'all-in-one-seo-pack' ),
|
||||
'button1_action' => aioseo()->helpers->utmUrl( AIOSEO_MARKETING_URL . '/docs/blank-title-formats-detected', 'notifications-center', 'v3-migration-title-formats-blank' ),
|
||||
'start' => gmdate( 'Y-m-d H:i:s' )
|
||||
] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates the description format.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function migrateDescriptionFormat() {
|
||||
if (
|
||||
! empty( $this->oldOptions['aiosp_generate_descriptions'] ) &&
|
||||
empty( $this->oldOptions['aiosp_skip_excerpt'] )
|
||||
) {
|
||||
foreach ( aioseo()->helpers->getPublicPostTypes() as $postType ) {
|
||||
if ( empty( $postType['supports']['excerpt'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( aioseo()->dynamicOptions->searchAppearance->postTypes->has( $postType['name'] ) ) {
|
||||
aioseo()->dynamicOptions->searchAppearance->postTypes->{$postType['name']}->metaDescription = '#post_excerpt';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
empty( $this->oldOptions['aiosp_description_format'] ) ||
|
||||
'%description%' === trim( $this->oldOptions['aiosp_description_format'] )
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
$deprecatedOptions = aioseo()->internalOptions->internal->deprecatedOptions;
|
||||
array_push( $deprecatedOptions, 'descriptionFormat' );
|
||||
aioseo()->internalOptions->internal->deprecatedOptions = $deprecatedOptions;
|
||||
|
||||
$format = aioseo()->migration->helpers->macrosToSmartTags( $this->oldOptions['aiosp_description_format'] );
|
||||
aioseo()->options->deprecated->searchAppearance->global->descriptionFormat = aioseo()->helpers->sanitizeOption( $format );
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates the noindex settings.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function migrateNoindexSettings() {
|
||||
if ( ! isset( $this->oldOptions['aiosp_cpostnoindex'] ) && ! isset( $this->oldOptions['aiosp_tax_noindex'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$noindexedPostTypes = is_array( $this->oldOptions['aiosp_cpostnoindex'] ) ? $this->oldOptions['aiosp_cpostnoindex'] : explode( ', ', $this->oldOptions['aiosp_cpostnoindex'] );
|
||||
foreach ( array_intersect( aioseo()->helpers->getPublicPostTypes( true ), $noindexedPostTypes ) as $postType ) {
|
||||
if ( aioseo()->dynamicOptions->noConflict()->searchAppearance->postTypes->has( $postType ) ) {
|
||||
aioseo()->dynamicOptions->searchAppearance->postTypes->$postType->show = false;
|
||||
aioseo()->dynamicOptions->searchAppearance->postTypes->$postType->advanced->robotsMeta->default = false;
|
||||
aioseo()->dynamicOptions->searchAppearance->postTypes->$postType->advanced->robotsMeta->noindex = true;
|
||||
}
|
||||
}
|
||||
|
||||
$noindexedTaxonomies = isset( $this->oldOptions['aiosp_tax_noindex'] ) ? (array) $this->oldOptions['aiosp_tax_noindex'] : [];
|
||||
if ( ! empty( $this->oldOptions['aiosp_category_noindex'] ) ) {
|
||||
$noindexedTaxonomies[] = 'category';
|
||||
}
|
||||
|
||||
if ( ! empty( $this->oldOptions['aiosp_tags_noindex'] ) ) {
|
||||
$noindexedTaxonomies[] = 'post_tag';
|
||||
}
|
||||
|
||||
if ( ! empty( $noindexedTaxonomies ) ) {
|
||||
foreach ( array_intersect( aioseo()->helpers->getPublicTaxonomies( true ), $noindexedTaxonomies ) as $taxonomy ) {
|
||||
if ( aioseo()->dynamicOptions->noConflict()->searchAppearance->taxonomies->has( $taxonomy ) ) {
|
||||
aioseo()->dynamicOptions->searchAppearance->taxonomies->$taxonomy->show = false;
|
||||
aioseo()->dynamicOptions->searchAppearance->taxonomies->$taxonomy->advanced->robotsMeta->default = false;
|
||||
aioseo()->dynamicOptions->searchAppearance->taxonomies->$taxonomy->advanced->robotsMeta->noindex = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $this->oldOptions['aiosp_archive_date_noindex'] ) ) {
|
||||
aioseo()->options->searchAppearance->archives->date->show = false;
|
||||
aioseo()->options->searchAppearance->archives->date->advanced->robotsMeta->default = false;
|
||||
aioseo()->options->searchAppearance->archives->date->advanced->robotsMeta->noindex = true;
|
||||
}
|
||||
|
||||
if ( ! empty( $this->oldOptions['aiosp_archive_author_noindex'] ) ) {
|
||||
aioseo()->options->searchAppearance->archives->author->show = false;
|
||||
aioseo()->options->searchAppearance->archives->author->advanced->robotsMeta->default = false;
|
||||
aioseo()->options->searchAppearance->archives->author->advanced->robotsMeta->noindex = true;
|
||||
}
|
||||
|
||||
if ( ! empty( $this->oldOptions['aiosp_search_noindex'] ) ) {
|
||||
aioseo()->options->searchAppearance->archives->search->show = false;
|
||||
aioseo()->options->searchAppearance->archives->search->advanced->robotsMeta->default = false;
|
||||
aioseo()->options->searchAppearance->archives->search->advanced->robotsMeta->noindex = true;
|
||||
} else {
|
||||
// We need to do this as V4 will noindex the search page otherwise.
|
||||
aioseo()->options->searchAppearance->archives->search->show = true;
|
||||
aioseo()->options->searchAppearance->archives->search->advanced->robotsMeta->default = true;
|
||||
aioseo()->options->searchAppearance->archives->search->advanced->robotsMeta->noindex = false;
|
||||
}
|
||||
|
||||
if ( ! empty( $this->oldOptions['aiosp_paginated_noindex'] ) ) {
|
||||
aioseo()->options->searchAppearance->advanced->globalRobotsMeta->default = false;
|
||||
aioseo()->options->searchAppearance->advanced->globalRobotsMeta->noindexPaginated = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates the nofollow settings.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function migrateNofollowSettings() {
|
||||
if ( ! empty( $this->oldOptions['aiosp_cpostnofollow'] ) ) {
|
||||
foreach ( array_intersect( aioseo()->helpers->getPublicPostTypes( true ), $this->oldOptions['aiosp_cpostnofollow'] ) as $postType ) {
|
||||
if ( aioseo()->dynamicOptions->noConflict()->searchAppearance->postTypes->has( $postType ) ) {
|
||||
aioseo()->dynamicOptions->searchAppearance->postTypes->$postType->advanced->robotsMeta->default = false;
|
||||
aioseo()->dynamicOptions->searchAppearance->postTypes->$postType->advanced->robotsMeta->nofollow = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $this->oldOptions['aiosp_paginated_nofollow'] ) ) {
|
||||
aioseo()->options->searchAppearance->advanced->globalRobotsMeta->nofollowPaginated = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates the post SEO columns.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function migratePostSeoColumns() {
|
||||
if ( ! isset( $this->oldOptions['aiosp_posttypecolumns'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$publicPostTypes = aioseo()->helpers->getPublicPostTypes( true );
|
||||
$postTypes = array_intersect( (array) $this->oldOptions['aiosp_posttypecolumns'], $publicPostTypes );
|
||||
|
||||
aioseo()->options->advanced->postTypes->included = array_values( $postTypes );
|
||||
if ( count( $publicPostTypes ) !== count( $postTypes ) ) {
|
||||
aioseo()->options->advanced->postTypes->all = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates the schema social URLs.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function migrateSocialUrls() {
|
||||
if ( ! empty( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_facebook_publisher'] ) ) {
|
||||
aioseo()->options->social->profiles->urls->facebookPageUrl = esc_url( wp_strip_all_tags( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_facebook_publisher'] ) );
|
||||
aioseo()->options->social->profiles->sameUsername->enable = false;
|
||||
}
|
||||
|
||||
if ( empty( $this->oldOptions['aiosp_schema_social_profile_links'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$socialUrls = aioseo()->helpers->pregReplace( '/\s/', '\r\n', $this->oldOptions['aiosp_schema_social_profile_links'] );
|
||||
$socialUrls = array_filter( explode( '\r\n', $socialUrls ) );
|
||||
|
||||
if ( ! count( $socialUrls ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$supportedNetworks = [
|
||||
'facebook.com' => 'facebookPageUrl',
|
||||
'twitter.com' => 'twitterUrl',
|
||||
'instagram.com' => 'instagramUrl',
|
||||
'tiktok.com' => 'tiktokUrl',
|
||||
'pinterest.com' => 'pinterestUrl',
|
||||
'youtube.com' => 'youtubeUrl',
|
||||
'linkedin.com' => 'linkedinUrl',
|
||||
'tumblr.com' => 'tumblrUrl',
|
||||
'yelp.com' => 'yelpPageUrl',
|
||||
'soundcloud.com' => 'soundCloudUrl',
|
||||
'wikipedia.org' => 'wikipediaUrl',
|
||||
'myspace.com' => 'myspaceUrl',
|
||||
'wordpress.org' => 'wordpressUrl',
|
||||
];
|
||||
|
||||
$found = false;
|
||||
foreach ( $supportedNetworks as $url => $settingName ) {
|
||||
$url = aioseo()->helpers->escapeRegex( $url );
|
||||
foreach ( $socialUrls as $socialUrl ) {
|
||||
if ( preg_match( "/.*$url.*/", (string) $socialUrl ) ) {
|
||||
aioseo()->options->social->profiles->urls->$settingName = esc_url( wp_strip_all_tags( $socialUrl ) );
|
||||
$found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $found ) {
|
||||
aioseo()->options->social->profiles->sameUsername->enable = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates the Schema Markup settings in the General Settings menu.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function migrateSchemaMarkupSettings() {
|
||||
$this->migrateSchemaPhoneNumber();
|
||||
|
||||
if (
|
||||
isset( $this->oldOptions['aiosp_schema_markup'] ) &&
|
||||
empty( $this->oldOptions['aiosp_schema_markup'] )
|
||||
) {
|
||||
$deprecatedOptions = aioseo()->internalOptions->internal->deprecatedOptions;
|
||||
array_push( $deprecatedOptions, 'enableSchemaMarkup' );
|
||||
aioseo()->internalOptions->internal->deprecatedOptions = $deprecatedOptions;
|
||||
aioseo()->options->deprecated->searchAppearance->global->schema->enableSchemaMarkup = false;
|
||||
}
|
||||
|
||||
if ( ! empty( $this->oldOptions['aiosp_schema_person_user'] ) ) {
|
||||
if ( -1 === (int) $this->oldOptions['aiosp_schema_person_user'] ) {
|
||||
aioseo()->options->searchAppearance->global->schema->person = 'manual';
|
||||
} else {
|
||||
aioseo()->options->searchAppearance->global->schema->person = intval( $this->oldOptions['aiosp_schema_person_user'] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates the schema phone number.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function migrateSchemaPhoneNumber() {
|
||||
if ( empty( $this->oldOptions['aiosp_schema_phone_number'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$phoneNumber = aioseo()->helpers->sanitizeOption( $this->oldOptions['aiosp_schema_phone_number'] );
|
||||
if ( ! preg_match( '#\+\d+#', (string) $phoneNumber ) ) {
|
||||
$notification = Models\Notification::getNotificationByName( 'v3-migration-schema-number' );
|
||||
if ( $notification->notification_name ) {
|
||||
return;
|
||||
}
|
||||
|
||||
Models\Notification::addNotification( [
|
||||
'slug' => uniqid(),
|
||||
'notification_name' => 'v3-migration-schema-number',
|
||||
'title' => __( 'Invalid Phone Number for Knowledge Graph', 'all-in-one-seo-pack' ),
|
||||
'content' => sprintf(
|
||||
// Translators: 1 - The phone number.
|
||||
__( 'The phone number that you previously entered for your Knowledge Graph schema markup is invalid. As it needs to be internationally formatted, please enter it (%1$s) again with the country code, e.g. +1 (555) 555-1234.', 'all-in-one-seo-pack' ), // phpcs:ignore Generic.Files.LineLength.MaxExceeded
|
||||
"<strong>$phoneNumber</strong>"
|
||||
),
|
||||
'type' => 'warning',
|
||||
'level' => [ 'all' ],
|
||||
'button1_label' => __( 'Fix Now', 'all-in-one-seo-pack' ),
|
||||
'button1_action' => 'http://route#aioseo-search-appearance&aioseo-scroll=schema-graph-phone&aioseo-highlight=schema-graph-phone:global-settings',
|
||||
'button2_label' => __( 'Remind Me Later', 'all-in-one-seo-pack' ),
|
||||
'button2_action' => 'http://action#notification/v3-migration-schema-number-reminder',
|
||||
'start' => gmdate( 'Y-m-d H:i:s' )
|
||||
] );
|
||||
|
||||
return;
|
||||
}
|
||||
aioseo()->options->searchAppearance->global->schema->phone = $phoneNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates the homepage keywords.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function migrateHomePageKeywords() {
|
||||
if ( ! empty( $this->oldOptions['aiosp_home_keywords'] ) ) {
|
||||
aioseo()->options->searchAppearance->global->keywords = aioseo()->migration->helpers->oldKeywordsToNewKeywords( $this->oldOptions['aiosp_home_keywords'] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates the deprecated V3 advanced General Settings options.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function migrateDeprecatedAdvancedOptions() {
|
||||
$deprecatedOptions = aioseo()->internalOptions->internal->deprecatedOptions;
|
||||
|
||||
if ( empty( $this->oldOptions['aiosp_generate_descriptions'] ) ) {
|
||||
array_push( $deprecatedOptions, 'autogenerateDescriptions' );
|
||||
aioseo()->options->deprecated->searchAppearance->advanced->autogenerateDescriptions = false;
|
||||
} else {
|
||||
if ( ! empty( $this->oldOptions['aiosp_skip_excerpt'] ) ) {
|
||||
array_push( $deprecatedOptions, 'useContentForAutogeneratedDescriptions' );
|
||||
aioseo()->options->deprecated->searchAppearance->advanced->useContentForAutogeneratedDescriptions = true;
|
||||
}
|
||||
}
|
||||
|
||||
aioseo()->internalOptions->internal->deprecatedOptions = $deprecatedOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates the RSS content settings.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function migrateRssContentSettings() {
|
||||
if ( isset( $this->oldOptions['aiosp_rss_content_before'] ) ) {
|
||||
aioseo()->options->rssContent->before = esc_html( aioseo()->migration->helpers->macrosToSmartTags( $this->oldOptions['aiosp_rss_content_before'] ) );
|
||||
}
|
||||
|
||||
if ( isset( $this->oldOptions['aiosp_rss_content_after'] ) ) {
|
||||
aioseo()->options->rssContent->after = esc_html( aioseo()->migration->helpers->macrosToSmartTags( $this->oldOptions['aiosp_rss_content_after'] ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates the Redirect Attachment to Parent setting.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function migrateRedirectToParent() {
|
||||
if ( isset( $this->oldOptions['aiosp_redirect_attachement_parent'] ) ) {
|
||||
if ( ! empty( $this->oldOptions['aiosp_redirect_attachement_parent'] ) ) {
|
||||
aioseo()->dynamicOptions->searchAppearance->postTypes->attachment->redirectAttachmentUrls = 'attachment_parent';
|
||||
} else {
|
||||
aioseo()->dynamicOptions->searchAppearance->postTypes->attachment->redirectAttachmentUrls = 'disabled';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates the excluded posts.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function migrateDisabledPosts() {
|
||||
if ( empty( $this->oldOptions['aiosp_ex_pages'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$deprecatedOptions = aioseo()->internalOptions->internal->deprecatedOptions;
|
||||
if ( ! in_array( 'excludePosts', $deprecatedOptions, true ) ) {
|
||||
array_push( $deprecatedOptions, 'excludePosts' );
|
||||
aioseo()->internalOptions->internal->deprecatedOptions = $deprecatedOptions;
|
||||
}
|
||||
|
||||
$excludedPosts = aioseo()->options->deprecated->searchAppearance->advanced->excludePosts;
|
||||
$pages = explode( ',', $this->oldOptions['aiosp_ex_pages'] );
|
||||
if ( count( $pages ) ) {
|
||||
foreach ( $pages as $page ) {
|
||||
$page = trim( $page );
|
||||
$id = intval( $page );
|
||||
if ( ! $id ) {
|
||||
$post = get_page_by_path( $page, OBJECT, aioseo()->helpers->getPublicPostTypes( true ) );
|
||||
if ( $post && is_object( $post ) ) {
|
||||
$id = $post->ID;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $id ) {
|
||||
$post = get_post( $id );
|
||||
if ( ! is_object( $post ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$excludedPost = new \stdClass();
|
||||
$excludedPost->value = $id;
|
||||
$excludedPost->type = $post->post_type;
|
||||
$excludedPost->label = $post->post_title;
|
||||
$excludedPost->link = get_permalink( $id );
|
||||
|
||||
array_push( $excludedPosts, wp_json_encode( $excludedPost ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
aioseo()->options->deprecated->searchAppearance->advanced->excludePosts = $excludedPosts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates the deprecated "No Pagination for Canonical URLs" setting.
|
||||
*
|
||||
* @since 4.5.9
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function migrateNoPaginationForCanonicalUrls() {
|
||||
if ( empty( $this->oldOptions['aiosp_no_paged_canonical_links'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$deprecatedOptions = aioseo()->internalOptions->deprecatedOptions;
|
||||
if ( ! in_array( 'noPaginationForCanonical', $deprecatedOptions, true ) ) {
|
||||
$deprecatedOptions[] = 'noPaginationForCanonical';
|
||||
aioseo()->internalOptions->deprecatedOptions = $deprecatedOptions;
|
||||
}
|
||||
|
||||
aioseo()->options->deprecated->searchAppearance->advanced->noPaginationForCanonical = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,247 @@
|
||||
<?php
|
||||
namespace AIOSEO\Plugin\Common\Migration;
|
||||
|
||||
// Exit if accessed directly.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
use AIOSEO\Plugin\Common\Models;
|
||||
|
||||
/**
|
||||
* Contains a number of helper functions for the V3 migration.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
class Helpers {
|
||||
/**
|
||||
* Maps a list of old settings from V3 to their counterparts in V4.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @param array $mappings The old settings, mapped to their new settings.
|
||||
* @param array $group The old settings group.
|
||||
* @param bool $convertMacros Whether to convert the old V3 macros to V4 smart tags.
|
||||
* @return void
|
||||
*/
|
||||
public function mapOldToNew( $mappings, $group, $convertMacros = false ) {
|
||||
if (
|
||||
! is_array( $mappings ) ||
|
||||
! is_array( $group ) ||
|
||||
! count( $mappings ) ||
|
||||
! count( $group )
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
$mainOptions = aioseo()->options->noConflict();
|
||||
$dynamicOptions = aioseo()->dynamicOptions->noConflict();
|
||||
foreach ( $mappings as $name => $values ) {
|
||||
if ( ! isset( $group[ $name ] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$error = false;
|
||||
$options = ! empty( $values['dynamic'] ) ? $dynamicOptions : $mainOptions;
|
||||
$lastOption = '';
|
||||
for ( $i = 0; $i < count( $values['newOption'] ); $i++ ) {
|
||||
$lastOption = $values['newOption'][ $i ];
|
||||
if ( ! $options->has( $lastOption, false ) ) {
|
||||
$error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( count( $values['newOption'] ) - 1 !== $i ) {
|
||||
$options = $options->$lastOption;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $error ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch ( $values['type'] ) {
|
||||
case 'boolean':
|
||||
if ( ! empty( $group[ $name ] ) ) {
|
||||
$options->$lastOption = true;
|
||||
break;
|
||||
}
|
||||
$options->$lastOption = false;
|
||||
break;
|
||||
case 'integer':
|
||||
case 'float':
|
||||
$value = aioseo()->helpers->sanitizeOption( $group[ $name ] );
|
||||
if ( $value ) {
|
||||
$options->$lastOption = $value;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$value = $group[ $name ];
|
||||
if ( $convertMacros ) {
|
||||
$value = $this->macrosToSmartTags( $value );
|
||||
}
|
||||
$options->$lastOption = aioseo()->helpers->sanitizeOption( $value );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the macros from V3 with our new Smart Tags from V4.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @param string $string The string.
|
||||
* @return string $string The converted string.
|
||||
*/
|
||||
public function macrosToSmartTags( $string ) {
|
||||
$macros = [
|
||||
'%site_title%' => '#site_title',
|
||||
'%blog_title%' => '#site_title',
|
||||
'%site_description%' => '#tagline',
|
||||
'%blog_description%' => '#tagline',
|
||||
'%wp_title%' => '#post_title',
|
||||
'%post_title%' => '#post_title',
|
||||
'%page_title%' => '#post_title',
|
||||
'%post_date%' => '#post_date',
|
||||
'%post_month%' => '#post_month',
|
||||
'%post_year%' => '#post_year',
|
||||
'%date%' => '#archive_date',
|
||||
'%day%' => '#post_day',
|
||||
'%month%' => '#post_month',
|
||||
'%monthnum%' => '#post_month',
|
||||
'%year%' => '#post_year',
|
||||
'%current_date%' => '#current_date',
|
||||
'%current_day%' => '#current_day',
|
||||
'%current_month%' => '#current_month',
|
||||
'%current_month_i18n%' => '#current_month',
|
||||
'%current_year%' => '#current_year',
|
||||
'%category_title%' => '#taxonomy_title',
|
||||
'%tag%' => '#taxonomy_title',
|
||||
'%tag_title%' => '#taxonomy_title',
|
||||
'%archive_title%' => '#archive_title',
|
||||
'%taxonomy_title%' => '#taxonomy_title',
|
||||
'%taxonomy_description%' => '#taxonomy_description',
|
||||
'%tag_description%' => '#taxonomy_description',
|
||||
'%category_description%' => '#taxonomy_description',
|
||||
'%author%' => '#author_name',
|
||||
'%search%' => '#search_term',
|
||||
'%page%' => '#page_number',
|
||||
'%site_link%' => '#site_link',
|
||||
'%site_link_raw%' => '#site_link_alt',
|
||||
'%post_link%' => '#post_link',
|
||||
'%post_link_raw%' => '#post_link_alt',
|
||||
'%author_name%' => '#author_name',
|
||||
'%author_link%' => '#author_link',
|
||||
'%image_title%' => '#image_title',
|
||||
'%image_seo_title%' => '#image_seo_title',
|
||||
'%image_seo_description%' => '#image_seo_description',
|
||||
'%post_seo_title%' => '#post_seo_title',
|
||||
'%post_seo_description%' => '#post_seo_description',
|
||||
'%alt_tag%' => '#alt_tag',
|
||||
'%description%' => '#description',
|
||||
// These need to run last so we don't replace other known tags.
|
||||
'%.*_title%' => '#post_title',
|
||||
'%[^%]*_author_login%' => '#author_first_name #author_last_name',
|
||||
'%[^%]*_author_nicename%' => '#author_first_name #author_last_name',
|
||||
'%[^%]*_author_firstname%' => '#author_first_name',
|
||||
'%[^%]*_author_lastname%' => '#author_last_name',
|
||||
];
|
||||
|
||||
if ( preg_match_all( '#%cf_([^%]*)%#', (string) $string, $matches ) && ! empty( $matches[1] ) ) {
|
||||
foreach ( $matches[1] as $name ) {
|
||||
if ( preg_match( '#\s#', (string) $name ) ) {
|
||||
$notification = Models\Notification::getNotificationByName( 'v3-migration-custom-field' );
|
||||
if ( ! $notification->notification_name ) {
|
||||
Models\Notification::addNotification( [
|
||||
'slug' => uniqid(),
|
||||
'notification_name' => 'v3-migration-custom-field',
|
||||
'title' => __( 'Custom field names with spaces detected', 'all-in-one-seo-pack' ),
|
||||
'content' => sprintf(
|
||||
// Translators: 1 - The plugin short name ("AIOSEO"), 2 - Same as previous.
|
||||
__( '%1$s has detected that you have one or more custom fields with spaces in their name.
|
||||
In order for %2$s to correctly parse these custom fields, their names cannot contain any spaces.', 'all-in-one-seo-pack' ),
|
||||
AIOSEO_PLUGIN_SHORT_NAME,
|
||||
AIOSEO_PLUGIN_SHORT_NAME
|
||||
),
|
||||
'type' => 'warning',
|
||||
'level' => [ 'all' ],
|
||||
'button1_label' => __( 'Remind Me Later', 'all-in-one-seo-pack' ),
|
||||
'button1_action' => 'http://action#notification/v3-migration-custom-field-reminder',
|
||||
'start' => gmdate( 'Y-m-d H:i:s' )
|
||||
] );
|
||||
}
|
||||
} else {
|
||||
$string = aioseo()->helpers->pregReplace( "#%cf_$name%#", "#custom_field-$name", $string );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( preg_match_all( '#%tax_([^%]*)%#', (string) $string, $matches ) && ! empty( $matches[1] ) ) {
|
||||
foreach ( $matches[1] as $name ) {
|
||||
if ( ! preg_match( '#\s#', (string) $name ) ) {
|
||||
$string = aioseo()->helpers->pregReplace( "#%tax_$name%#", "#tax_name-$name", $string );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( $macros as $macro => $tag ) {
|
||||
$string = aioseo()->helpers->pregReplace( "#$macro(?![a-zA-Z0-9_])#im", $tag, $string );
|
||||
}
|
||||
|
||||
$string = preg_replace( '/%([a-f0-9]{2}[^%]*)%/i', '#$1#', (string) $string );
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the old comma-separated keywords format to the new JSON format.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @param string $keywords A comma-separated list of keywords.
|
||||
* @return string $keywords The keywords formatted in JSON.
|
||||
*/
|
||||
public function oldKeywordsToNewKeywords( $keywords ) {
|
||||
if ( ! $keywords ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$oldKeywords = array_filter( explode( ',', $keywords ) );
|
||||
if ( ! is_array( $oldKeywords ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$keywords = [];
|
||||
foreach ( $oldKeywords as $oldKeyword ) {
|
||||
$oldKeyword = aioseo()->helpers->sanitizeOption( $oldKeyword );
|
||||
|
||||
$keyword = new \stdClass();
|
||||
$keyword->label = $oldKeyword;
|
||||
$keyword->value = $oldKeyword;
|
||||
|
||||
$keywords[] = $keyword;
|
||||
}
|
||||
|
||||
return $keywords;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the plugin so that the migration can run again.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function redoMigration() {
|
||||
aioseo()->core->db->delete( 'options' )
|
||||
->whereRaw( "`option_name` LIKE 'aioseo_options_internal%'" )
|
||||
->run();
|
||||
|
||||
aioseo()->core->cache->delete( 'v3_migration_in_progress_posts' );
|
||||
aioseo()->core->cache->delete( 'v3_migration_in_progress_terms' );
|
||||
|
||||
aioseo()->actionScheduler->unschedule( 'aioseo_migrate_post_meta' );
|
||||
aioseo()->actionScheduler->unschedule( 'aioseo_migrate_term_meta' );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,461 @@
|
||||
<?php
|
||||
namespace AIOSEO\Plugin\Common\Migration;
|
||||
|
||||
// Exit if accessed directly.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
// phpcs:disable WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound
|
||||
|
||||
use AIOSEO\Plugin\Common\Models;
|
||||
|
||||
/**
|
||||
* Migrates the post meta from V3.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
class Meta {
|
||||
/**
|
||||
* Holds the old options array.
|
||||
*
|
||||
* @since 4.0.3
|
||||
*
|
||||
* @var array|null
|
||||
*/
|
||||
protected static $oldOptions = null;
|
||||
|
||||
/**
|
||||
* Migrates the plugin meta data.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function migrateMeta() {
|
||||
try {
|
||||
if ( as_next_scheduled_action( 'aioseo_migrate_post_meta' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
as_schedule_single_action( time() + 30, 'aioseo_migrate_post_meta', [], 'aioseo' );
|
||||
} catch ( \Exception $e ) {
|
||||
// Do nothing.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates the post meta data from V3.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function migratePostMeta() {
|
||||
if ( aioseo()->core->cache->get( 'v3_migration_in_progress_settings' ) ) {
|
||||
aioseo()->actionScheduler->scheduleSingle( 'aioseo_migrate_post_meta', 30, [], true );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$postsPerAction = 50;
|
||||
$publicPostTypes = implode( "', '", aioseo()->helpers->getPublicPostTypes( true ) );
|
||||
$timeStarted = gmdate( 'Y-m-d H:i:s', aioseo()->core->cache->get( 'v3_migration_in_progress_posts' ) );
|
||||
|
||||
$postsToMigrate = aioseo()->core->db
|
||||
->start( 'posts' . ' as p' )
|
||||
->select( 'p.ID' )
|
||||
->leftJoin( 'aioseo_posts as ap', '`p`.`ID` = `ap`.`post_id`' )
|
||||
->whereRaw( "( ap.post_id IS NULL OR ap.updated < '$timeStarted' )" )
|
||||
->whereRaw( "( p.post_type IN ( '$publicPostTypes' ) )" )
|
||||
->whereRaw( 'p.post_status NOT IN( \'auto-draft\' )' )
|
||||
->orderBy( 'p.ID DESC' )
|
||||
->limit( $postsPerAction )
|
||||
->run()
|
||||
->result();
|
||||
|
||||
if ( ! $postsToMigrate || ! count( $postsToMigrate ) ) {
|
||||
aioseo()->core->cache->delete( 'v3_migration_in_progress_posts' );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( $postsToMigrate as $post ) {
|
||||
$newPostMeta = $this->getMigratedPostMeta( $post->ID );
|
||||
|
||||
$aioseoPost = Models\Post::getPost( $post->ID );
|
||||
$aioseoPost->set( $newPostMeta );
|
||||
$aioseoPost->save();
|
||||
|
||||
$this->updateLocalizedPostMeta( $post->ID, $newPostMeta );
|
||||
$this->migrateAdditionalPostMeta( $post->ID );
|
||||
}
|
||||
|
||||
if ( count( $postsToMigrate ) === $postsPerAction ) {
|
||||
try {
|
||||
as_schedule_single_action( time() + 30, 'aioseo_migrate_post_meta', [], 'aioseo' );
|
||||
} catch ( \Exception $e ) {
|
||||
// Do nothing.
|
||||
}
|
||||
} else {
|
||||
aioseo()->core->cache->delete( 'v3_migration_in_progress_posts' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the migrated post meta for a given post.
|
||||
*
|
||||
* @since 4.0.3
|
||||
*
|
||||
* @param int $postId The post ID.
|
||||
* @return array The post meta.
|
||||
*/
|
||||
public function getMigratedPostMeta( $postId ) {
|
||||
if ( is_category() || is_tag() || is_tax() || ! is_numeric( $postId ) ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if ( null === self::$oldOptions ) {
|
||||
self::$oldOptions = get_option( 'aioseop_options' );
|
||||
}
|
||||
|
||||
if ( empty( self::$oldOptions ) ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$postMeta = aioseo()->core->db
|
||||
->start( 'postmeta' . ' as pm' )
|
||||
->select( 'pm.meta_key, pm.meta_value' )
|
||||
->where( 'pm.post_id', $postId )
|
||||
->whereRaw( "`pm`.`meta_key` LIKE '_aioseop_%'" )
|
||||
->run()
|
||||
->result();
|
||||
|
||||
$mappedMeta = [
|
||||
'_aioseop_title' => 'title',
|
||||
'_aioseop_description' => 'description',
|
||||
'_aioseop_custom_link' => 'canonical_url',
|
||||
'_aioseop_sitemap_exclude' => '',
|
||||
'_aioseop_disable' => '',
|
||||
'_aioseop_noindex' => 'robots_noindex',
|
||||
'_aioseop_nofollow' => 'robots_nofollow',
|
||||
'_aioseop_sitemap_priority' => 'priority',
|
||||
'_aioseop_sitemap_frequency' => 'frequency',
|
||||
'_aioseop_keywords' => 'keywords',
|
||||
'_aioseop_opengraph_settings' => ''
|
||||
];
|
||||
|
||||
$meta = [
|
||||
'post_id' => $postId,
|
||||
];
|
||||
|
||||
if ( ! $postMeta || ! count( $postMeta ) ) {
|
||||
return $meta;
|
||||
}
|
||||
|
||||
foreach ( $postMeta as $record ) {
|
||||
$name = $record->meta_key;
|
||||
$value = $record->meta_value;
|
||||
|
||||
if ( ! in_array( $name, array_keys( $mappedMeta ), true ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch ( $name ) {
|
||||
case '_aioseop_description':
|
||||
$meta[ $mappedMeta[ $name ] ] = aioseo()->helpers->sanitizeOption( aioseo()->migration->helpers->macrosToSmartTags( $value ) );
|
||||
break;
|
||||
case '_aioseop_title':
|
||||
if ( ! empty( $value ) ) {
|
||||
$meta[ $mappedMeta[ $name ] ] = $this->getPostTitle( $postId, $value );
|
||||
}
|
||||
break;
|
||||
case '_aioseop_sitemap_exclude':
|
||||
if ( empty( $value ) ) {
|
||||
break;
|
||||
}
|
||||
$this->migrateExcludedPost( $postId );
|
||||
break;
|
||||
case '_aioseop_disable':
|
||||
if ( empty( $value ) ) {
|
||||
break;
|
||||
}
|
||||
$this->migrateSitemapExcludedPost( $postId );
|
||||
break;
|
||||
case '_aioseop_noindex':
|
||||
case '_aioseop_nofollow':
|
||||
if ( 'on' === (string) $value ) {
|
||||
$meta['robots_default'] = false;
|
||||
$meta[ $mappedMeta[ $name ] ] = true;
|
||||
} elseif ( 'off' === (string) $value ) {
|
||||
$meta['robots_default'] = false;
|
||||
}
|
||||
break;
|
||||
case '_aioseop_keywords':
|
||||
$meta[ $mappedMeta[ $name ] ] = aioseo()->migration->helpers->oldKeywordsToNewKeywords( $value );
|
||||
break;
|
||||
case '_aioseop_opengraph_settings':
|
||||
$meta += $this->convertOpenGraphMeta( $value );
|
||||
break;
|
||||
case '_aioseop_sitemap_priority':
|
||||
case '_aioseop_sitemap_frequency':
|
||||
if ( empty( $value ) ) {
|
||||
$meta[ $mappedMeta[ $name ] ] = 'default';
|
||||
break;
|
||||
}
|
||||
$meta[ $mappedMeta[ $name ] ] = $value;
|
||||
break;
|
||||
default:
|
||||
$meta[ $mappedMeta[ $name ] ] = esc_html( wp_strip_all_tags( strval( $value ) ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $meta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates a given disabled post from V3.
|
||||
*
|
||||
* @since 4.0.3
|
||||
*
|
||||
* @param int $postId The post ID.
|
||||
* @return void
|
||||
*/
|
||||
private function migrateExcludedPost( $postId ) {
|
||||
$post = get_post( $postId );
|
||||
if ( ! is_object( $post ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
aioseo()->options->sitemap->general->advancedSettings->enable = true;
|
||||
$excludedPosts = aioseo()->options->sitemap->general->advancedSettings->excludePosts;
|
||||
|
||||
foreach ( $excludedPosts as $excludedPost ) {
|
||||
$excludedPost = json_decode( $excludedPost );
|
||||
if ( $excludedPost->value === $postId ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$excludedPost = [
|
||||
'value' => $post->ID,
|
||||
'type' => $post->post_type,
|
||||
'label' => $post->post_title,
|
||||
'link' => get_permalink( $post )
|
||||
];
|
||||
|
||||
$excludedPosts[] = wp_json_encode( $excludedPost );
|
||||
aioseo()->options->sitemap->general->advancedSettings->excludePosts = $excludedPosts;
|
||||
|
||||
$deprecatedOptions = aioseo()->internalOptions->internal->deprecatedOptions;
|
||||
if ( ! in_array( 'excludePosts', $deprecatedOptions, true ) ) {
|
||||
array_push( $deprecatedOptions, 'excludePosts' );
|
||||
aioseo()->internalOptions->internal->deprecatedOptions = $deprecatedOptions;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates a given sitemap excluded post from V3.
|
||||
*
|
||||
* @since 4.0.3
|
||||
*
|
||||
* @param int $postId The post ID.
|
||||
* @return void
|
||||
*/
|
||||
private function migrateSitemapExcludedPost( $postId ) {
|
||||
$post = get_post( $postId );
|
||||
if ( ! is_object( $post ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$excludedPosts = aioseo()->options->deprecated->searchAppearance->advanced->excludePosts;
|
||||
foreach ( $excludedPosts as $excludedPost ) {
|
||||
$excludedPost = json_decode( $excludedPost );
|
||||
if ( $excludedPost->value === $postId ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$excludedPost = [
|
||||
'value' => $post->ID,
|
||||
'type' => $post->post_type,
|
||||
'label' => $post->post_title,
|
||||
'link' => get_permalink( $post )
|
||||
];
|
||||
|
||||
$excludedPosts[] = wp_json_encode( $excludedPost );
|
||||
aioseo()->options->deprecated->searchAppearance->advanced->excludePosts = $excludedPosts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the traditional post meta table with the new data.
|
||||
*
|
||||
* @since 4.1.0
|
||||
*
|
||||
* @param int $postId The post ID.
|
||||
* @param array $newMeta The new meta data.
|
||||
* @return void
|
||||
*/
|
||||
protected function updateLocalizedPostMeta( $postId, $newMeta ) {
|
||||
$localizedFields = [
|
||||
'title',
|
||||
'description',
|
||||
'keywords',
|
||||
'og_title',
|
||||
'og_description',
|
||||
'og_article_section',
|
||||
'og_article_tags',
|
||||
'twitter_title',
|
||||
'twitter_description'
|
||||
];
|
||||
|
||||
foreach ( $newMeta as $k => $v ) {
|
||||
if ( ! in_array( $k, $localizedFields, true ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( in_array( $k, [ 'keywords', 'og_article_tags' ], true ) ) {
|
||||
$v = ! empty( $v ) ? aioseo()->helpers->jsonTagsToCommaSeparatedList( $v ) : '';
|
||||
}
|
||||
|
||||
update_post_meta( $postId, "_aioseo_{$k}", $v );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates additional post meta data.
|
||||
*
|
||||
* @since 4.0.2
|
||||
*
|
||||
* @param int $postId The post ID.
|
||||
* @return void
|
||||
*/
|
||||
public function migrateAdditionalPostMeta( $postId ) {
|
||||
static $disabled = null;
|
||||
|
||||
if ( null === $disabled ) {
|
||||
$disabled = (
|
||||
! aioseo()->options->sitemap->general->enable ||
|
||||
(
|
||||
aioseo()->options->sitemap->general->advancedSettings->enable &&
|
||||
aioseo()->options->sitemap->general->advancedSettings->excludeImages
|
||||
)
|
||||
);
|
||||
}
|
||||
if ( $disabled ) {
|
||||
return;
|
||||
}
|
||||
|
||||
aioseo()->sitemap->image->scanPost( $postId );
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps the old Open Graph meta to the social meta columns in V4.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @param array $ogMeta The old V3 Open Graph meta.
|
||||
* @return array $meta The mapped meta.
|
||||
*/
|
||||
public function convertOpenGraphMeta( $ogMeta ) {
|
||||
$ogMeta = aioseo()->helpers->maybeUnserialize( $ogMeta );
|
||||
|
||||
if ( ! is_array( $ogMeta ) ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$mappedSocialMeta = [
|
||||
'aioseop_opengraph_settings_title' => 'og_title',
|
||||
'aioseop_opengraph_settings_desc' => 'og_description',
|
||||
'aioseop_opengraph_settings_image' => 'og_image_custom_url',
|
||||
'aioseop_opengraph_settings_imagewidth' => 'og_image_width',
|
||||
'aioseop_opengraph_settings_imageheight' => 'og_image_height',
|
||||
'aioseop_opengraph_settings_video' => 'og_video',
|
||||
'aioseop_opengraph_settings_videowidth' => 'og_video_width',
|
||||
'aioseop_opengraph_settings_videoheight' => 'og_video_height',
|
||||
'aioseop_opengraph_settings_category' => 'og_object_type',
|
||||
'aioseop_opengraph_settings_section' => 'og_article_section',
|
||||
'aioseop_opengraph_settings_tag' => 'og_article_tags',
|
||||
'aioseop_opengraph_settings_setcard' => 'twitter_card',
|
||||
'aioseop_opengraph_settings_customimg_twitter' => 'twitter_image_custom_url',
|
||||
];
|
||||
|
||||
$meta = [];
|
||||
foreach ( $ogMeta as $name => $value ) {
|
||||
if ( ! in_array( $name, array_keys( $mappedSocialMeta ), true ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch ( $name ) {
|
||||
case 'aioseop_opengraph_settings_desc':
|
||||
case 'aioseop_opengraph_settings_title':
|
||||
$meta[ $mappedSocialMeta[ $name ] ] = aioseo()->helpers->sanitizeOption( aioseo()->migration->helpers->macrosToSmartTags( $value ) );
|
||||
break;
|
||||
case 'aioseop_opengraph_settings_image':
|
||||
$value = strval( $value );
|
||||
if ( empty( $value ) ) {
|
||||
break;
|
||||
}
|
||||
|
||||
$meta['og_image_type'] = 'custom_image';
|
||||
$meta[ $mappedSocialMeta[ $name ] ] = strval( $value );
|
||||
break;
|
||||
case 'aioseop_opengraph_settings_video':
|
||||
$meta[ $mappedSocialMeta[ $name ] ] = esc_url( $value );
|
||||
break;
|
||||
case 'aioseop_opengraph_settings_customimg_twitter':
|
||||
$value = strval( $value );
|
||||
if ( empty( $value ) ) {
|
||||
break;
|
||||
}
|
||||
$meta['twitter_image_type'] = 'custom_image';
|
||||
$meta['twitter_use_og'] = false;
|
||||
$meta[ $mappedSocialMeta[ $name ] ] = strval( $value );
|
||||
break;
|
||||
case 'aioseop_opengraph_settings_imagewidth':
|
||||
case 'aioseop_opengraph_settings_imageheight':
|
||||
case 'aioseop_opengraph_settings_videowidth':
|
||||
case 'aioseop_opengraph_settings_videoheight':
|
||||
$value = intval( $value );
|
||||
if ( ! $value || $value <= 0 ) {
|
||||
break;
|
||||
}
|
||||
$meta[ $mappedSocialMeta[ $name ] ] = $value;
|
||||
break;
|
||||
case 'aioseop_opengraph_settings_tag':
|
||||
$meta[ $mappedSocialMeta[ $name ] ] = aioseo()->migration->helpers->oldKeywordsToNewKeywords( $value );
|
||||
break;
|
||||
default:
|
||||
$meta[ $mappedSocialMeta[ $name ] ] = esc_html( strval( $value ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $meta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the title as it was in V3.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @param int $postId The post ID.
|
||||
* @param string $seoTitle The old SEO title.
|
||||
* @return string The title.
|
||||
*/
|
||||
protected function getPostTitle( $postId, $seoTitle = '' ) {
|
||||
$post = get_post( $postId );
|
||||
if ( ! is_object( $post ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$postType = $post->post_type;
|
||||
$oldOptions = get_option( 'aioseo_options_v3' );
|
||||
$titleFormat = isset( $oldOptions[ "aiosp_{$postType}_title_format" ] ) ? $oldOptions[ "aiosp_{$postType}_title_format" ] : '';
|
||||
|
||||
$seoTitle = aioseo()->helpers->pregReplace( '/(%post_title%|%page_title%)/', $seoTitle, $titleFormat );
|
||||
|
||||
return aioseo()->helpers->sanitizeOption( aioseo()->migration->helpers->macrosToSmartTags( $seoTitle ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,244 @@
|
||||
<?php
|
||||
namespace AIOSEO\Plugin\Common\Migration;
|
||||
|
||||
// Exit if accessed directly.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
// phpcs:disable WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound
|
||||
|
||||
/**
|
||||
* Handles the migration from V3 to V4.
|
||||
*/
|
||||
class Migration {
|
||||
/**
|
||||
* The old V3 options.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $oldOptions = [];
|
||||
|
||||
/**
|
||||
* Meta class instance.
|
||||
*
|
||||
* @since 4.2.7
|
||||
*
|
||||
* @var Meta
|
||||
*/
|
||||
public $meta = null;
|
||||
|
||||
/**
|
||||
* Helpers class instance.
|
||||
*
|
||||
* @since 4.2.7
|
||||
*
|
||||
* @var Helpers
|
||||
*/
|
||||
public $helpers = null;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->meta = new Meta();
|
||||
$this->helpers = new Helpers();
|
||||
|
||||
// NOTE: This needs to go above the is_admin check in order for it to run at all.
|
||||
add_action( 'aioseo_migrate_post_meta', [ $this->meta, 'migratePostMeta' ] );
|
||||
|
||||
if ( ! is_admin() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( wp_doing_ajax() || wp_doing_cron() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
add_action( 'init', [ $this, 'init' ], 2000 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the class.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init() {
|
||||
// Since the version numbers may vary, we only want to compare the first 3 numbers.
|
||||
$lastActiveVersion = aioseo()->internalOptions->internal->lastActiveVersion;
|
||||
$lastActiveVersion = $lastActiveVersion ? explode( '-', $lastActiveVersion ) : null;
|
||||
|
||||
if ( version_compare( $lastActiveVersion[0], '4.0.0', '<' ) ) {
|
||||
aioseo()->internalOptions->internal->migratedVersion = $lastActiveVersion[0];
|
||||
add_action( 'wp_loaded', [ $this, 'doMigration' ] );
|
||||
}
|
||||
|
||||
// Run our migration again for V4 users between v4.0.0 and v4.0.4.
|
||||
if (
|
||||
version_compare( $lastActiveVersion[0], '4.0.0', '>=' ) &&
|
||||
version_compare( $lastActiveVersion[0], '4.0.4', '<' ) &&
|
||||
get_option( 'aioseop_options' )
|
||||
) {
|
||||
add_action( 'wp_loaded', [ $this, 'redoMetaMigration' ] );
|
||||
}
|
||||
|
||||
// Stop migration for new v4 users where it was incorrectly triggered.
|
||||
if ( version_compare( $lastActiveVersion[0], '4.0.4', '=' ) && ! get_option( 'aioseop_options' ) ) {
|
||||
aioseo()->core->cache->delete( 'v3_migration_in_progress_posts' );
|
||||
aioseo()->core->cache->delete( 'v3_migration_in_progress_terms' );
|
||||
|
||||
try {
|
||||
aioseo()->actionScheduler->unschedule( 'aioseo_migrate_post_meta' );
|
||||
aioseo()->actionScheduler->unschedule( 'aioseo_migrate_term_meta' );
|
||||
} catch ( \Exception $e ) {
|
||||
// Do nothing.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the migration.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function doMigration() {
|
||||
// If our tables do not exist, create them now.
|
||||
if ( ! aioseo()->core->db->tableExists( 'aioseo_posts' ) ) {
|
||||
aioseo()->updates->addInitialCustomTablesForV4();
|
||||
}
|
||||
|
||||
$this->oldOptions = ( new OldOptions() )->oldOptions;
|
||||
|
||||
if (
|
||||
! $this->oldOptions ||
|
||||
! is_array( $this->oldOptions ) ||
|
||||
! count( $this->oldOptions )
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
update_option( 'aioseo_options_v3', $this->oldOptions );
|
||||
|
||||
aioseo()->core->cache->update( 'v3_migration_in_progress_posts', time(), WEEK_IN_SECONDS );
|
||||
|
||||
$this->migrateSettings();
|
||||
$this->meta->migrateMeta();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reruns the post meta migration.
|
||||
*
|
||||
* This is meant for users on v4.0.0, v4.0.1 or v4.0.2 where the migration might have failed.
|
||||
*
|
||||
* @since 4.0.3
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function redoMetaMigration() {
|
||||
aioseo()->core->cache->update( 'v3_migration_in_progress_posts', time(), WEEK_IN_SECONDS );
|
||||
$this->meta->migrateMeta();
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates the plugin settings.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @param array $oldOptions The old options. We pass it in directly via the Importer/Exporter.
|
||||
* @return void
|
||||
*/
|
||||
public function migrateSettings( $oldOptions = [] ) {
|
||||
if ( empty( $this->oldOptions ) && ! empty( $oldOptions ) ) {
|
||||
$this->oldOptions = ( new OldOptions( $oldOptions ) )->oldOptions;
|
||||
|
||||
if (
|
||||
! $this->oldOptions ||
|
||||
! is_array( $this->oldOptions ) ||
|
||||
! count( $this->oldOptions )
|
||||
) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
aioseo()->core->cache->update( 'v3_migration_in_progress_settings', time() );
|
||||
|
||||
new GeneralSettings();
|
||||
|
||||
if ( ! isset( $this->oldOptions['modules']['aiosp_feature_manager_options'] ) ) {
|
||||
new Sitemap();
|
||||
aioseo()->core->cache->delete( 'v3_migration_in_progress_settings' );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->migrateFeatureManager();
|
||||
|
||||
if ( isset( $this->oldOptions['modules']['aiosp_feature_manager_options']['aiosp_feature_manager_enable_opengraph'] ) ) {
|
||||
new SocialMeta();
|
||||
}
|
||||
|
||||
if ( isset( $this->oldOptions['modules']['aiosp_feature_manager_options']['aiosp_feature_manager_enable_sitemap'] ) ) {
|
||||
new Sitemap();
|
||||
}
|
||||
|
||||
if ( isset( $this->oldOptions['modules']['aiosp_feature_manager_options']['aiosp_feature_manager_enable_robots'] ) ) {
|
||||
new RobotsTxt();
|
||||
}
|
||||
|
||||
if ( ! empty( $this->oldOptions['modules']['aiosp_feature_manager_options']['aiosp_feature_manager_enable_bad_robots'] ) ) {
|
||||
new BadRobots();
|
||||
}
|
||||
|
||||
if ( aioseo()->helpers->isWpmlActive() ) {
|
||||
new Wpml();
|
||||
}
|
||||
|
||||
aioseo()->core->cache->delete( 'v3_migration_in_progress_settings' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates the Feature Manager settings.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function migrateFeatureManager() {
|
||||
if ( empty( $this->oldOptions['modules']['aiosp_feature_manager_options'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( empty( $this->oldOptions['modules']['aiosp_feature_manager_options']['aiosp_feature_manager_enable_opengraph'] ) ) {
|
||||
aioseo()->options->social->facebook->general->enable = false;
|
||||
aioseo()->options->social->twitter->general->enable = false;
|
||||
}
|
||||
|
||||
if ( empty( $this->oldOptions['modules']['aiosp_feature_manager_options']['aiosp_feature_manager_enable_sitemap'] ) ) {
|
||||
aioseo()->options->sitemap->general->enable = false;
|
||||
aioseo()->options->sitemap->rss->enable = false;
|
||||
}
|
||||
|
||||
if ( ! empty( $this->oldOptions['modules']['aiosp_feature_manager_options']['aiosp_feature_manager_enable_robots'] ) ) {
|
||||
aioseo()->options->tools->robots->enable = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the V3 migration is running.
|
||||
*
|
||||
* @since 4.1.8
|
||||
*
|
||||
* @return bool Whether the V3 migration is running.
|
||||
*/
|
||||
public function isMigrationRunning() {
|
||||
return aioseo()->core->cache->get( 'v3_migration_in_progress_settings' ) || aioseo()->core->cache->get( 'v3_migration_in_progress_posts' );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,269 @@
|
||||
<?php
|
||||
namespace AIOSEO\Plugin\Common\Migration;
|
||||
|
||||
// Exit if accessed directly.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates and holds the old options from V3.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
class OldOptions {
|
||||
/**
|
||||
* The old options from V3.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $oldOptions = [];
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @param array $oldOptions The old options. We pass it in directly via the Importer/Exporter.
|
||||
*/
|
||||
public function __construct( $oldOptions = [] ) {
|
||||
$this->oldOptions = ! empty( $oldOptions ) ? $oldOptions : get_option( 'aioseop_options' );
|
||||
|
||||
if (
|
||||
! $this->oldOptions ||
|
||||
! is_array( $this->oldOptions ) ||
|
||||
! count( $this->oldOptions )
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->runPreV4Migrations();
|
||||
$this->fixSettingValues();
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs all pre-V4 migrations to update the old options to the latest state.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function runPreV4Migrations() {
|
||||
$lastActiveVersion = aioseo()->internalOptions->internal->lastActiveVersion;
|
||||
if ( version_compare( $lastActiveVersion, aioseo()->version, '<' ) ) {
|
||||
|
||||
$this->doVersionUpdates( $lastActiveVersion );
|
||||
aioseo()->internalOptions->internal->lastActiveVersion = aioseo()->version;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs all pre-V4 version-based migrations.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @param string $oldVersion The old version number to compare against.
|
||||
* @return void
|
||||
*/
|
||||
protected function doVersionUpdates( $oldVersion ) {
|
||||
if ( version_compare( $oldVersion, '3.0', '<' ) ) {
|
||||
$this->removeBadBots();
|
||||
$this->sitemapExclTerms201905();
|
||||
}
|
||||
|
||||
if ( version_compare( $oldVersion, '3.1', '<' ) ) {
|
||||
$this->resetFlushRewriteRules201906();
|
||||
}
|
||||
|
||||
if (
|
||||
version_compare( $oldVersion, '3.2', '<' ) ||
|
||||
version_compare( $oldVersion, '3.2.6', '<' )
|
||||
) {
|
||||
$this->updateSchemaMarkup201907();
|
||||
}
|
||||
|
||||
if ( version_compare( $oldVersion, '4.0.0', '<' ) ) {
|
||||
$this->updateArchiveNoIndexSettings20200413();
|
||||
$this->updateArchiveTitleFormatSettings20200413();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes various entries from the bad bots list.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function removeBadBots() {
|
||||
if (
|
||||
empty( $this->oldOptions['modules']['aiosp_bad_robots_options'] ) ||
|
||||
empty( $this->oldOptions['modules']['aiosp_bad_robots_options']['aiosp_bad_robots_blocklist'] )
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->oldOptions['modules']['aiosp_bad_robots_options']['aiosp_bad_robots_blocklist'] = str_replace(
|
||||
[
|
||||
"DOC\r\n",
|
||||
"DOC\n",
|
||||
"yandex\r\n",
|
||||
"yandex\n",
|
||||
"SeznamBot\r\n",
|
||||
"SeznamBot\n",
|
||||
"SemrushBot\r\n",
|
||||
"SemrushBot\n",
|
||||
"Exabot\r\n",
|
||||
"Exabot\n",
|
||||
],
|
||||
'',
|
||||
$this->oldOptions['modules']['aiosp_bad_robots_options']['aiosp_bad_robots_blocklist']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts "excl_categories" to "excl_terms".
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function sitemapExclTerms201905() {
|
||||
if (
|
||||
empty( $this->oldOptions['modules'] ) ||
|
||||
empty( $this->oldOptions['modules']['aiosp_sitemap_options'] )
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
$options = $this->oldOptions['modules']['aiosp_sitemap_options'];
|
||||
if ( ! empty( $options['aiosp_sitemap_excl_categories'] ) ) {
|
||||
$options['aiosp_sitemap_excl_terms']['category']['taxonomy'] = 'category';
|
||||
$options['aiosp_sitemap_excl_terms']['category']['terms'] = $options['aiosp_sitemap_excl_categories'];
|
||||
unset( $options['aiosp_sitemap_excl_categories'] );
|
||||
|
||||
$this->oldOptions['modules']['aiosp_sitemap_options'] = $options;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushes rewrite rules for XML Sitemap URL changes.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function resetFlushRewriteRules201906() {
|
||||
add_action( 'shutdown', 'flush_rewrite_rules' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a number of schema markup settings.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function updateSchemaMarkup201907() {
|
||||
$updateValues = [
|
||||
'aiosp_schema_markup' => '1',
|
||||
'aiosp_schema_search_results_page' => '1',
|
||||
'aiosp_schema_social_profile_links' => '',
|
||||
'aiosp_schema_site_represents' => 'organization',
|
||||
'aiosp_schema_organization_name' => '',
|
||||
'aiosp_schema_organization_logo' => '',
|
||||
'aiosp_schema_person_user' => '1',
|
||||
'aiosp_schema_phone_number' => '',
|
||||
'aiosp_schema_contact_type' => 'none',
|
||||
];
|
||||
|
||||
if ( isset( $this->oldOptions['aiosp_schema_markup'] ) ) {
|
||||
if ( empty( $this->oldOptions['aiosp_schema_markup'] ) || 'off' === $this->oldOptions['aiosp_schema_markup'] ) {
|
||||
$updateValues['aiosp_schema_markup'] = '0';
|
||||
}
|
||||
}
|
||||
if ( isset( $this->oldOptions['aiosp_google_sitelinks_search'] ) ) {
|
||||
if ( empty( $this->oldOptions['aiosp_google_sitelinks_search'] ) || 'off' === $this->oldOptions['aiosp_google_sitelinks_search'] ) {
|
||||
$updateValues['aiosp_schema_search_results_page'] = '0';
|
||||
}
|
||||
}
|
||||
if ( isset( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_profile_links'] ) ) {
|
||||
$updateValues['aiosp_schema_social_profile_links'] = $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_profile_links'];
|
||||
}
|
||||
if ( isset( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_person_or_org'] ) ) {
|
||||
if ( 'person' === $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_person_or_org'] ) {
|
||||
$updateValues['aiosp_schema_site_represents'] = 'person';
|
||||
}
|
||||
}
|
||||
if ( isset( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_social_name'] ) ) {
|
||||
$updateValues['aiosp_schema_organization_name'] = $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_social_name'];
|
||||
}
|
||||
|
||||
foreach ( $updateValues as $k => $v ) {
|
||||
$this->oldOptions[ $k ] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate setting for noindex archives.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function updateArchiveNoIndexSettings20200413() {
|
||||
if ( isset( $this->oldOptions['aiosp_archive_noindex'] ) ) {
|
||||
$this->oldOptions['aiosp_archive_date_noindex'] = $this->oldOptions['aiosp_archive_noindex'];
|
||||
$this->oldOptions['aiosp_archive_author_noindex'] = $this->oldOptions['aiosp_archive_noindex'];
|
||||
unset( $this->oldOptions['aiosp_archive_noindex'] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate settings for archive title formats.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function updateArchiveTitleFormatSettings20200413() {
|
||||
if (
|
||||
isset( $this->oldOptions['aiosp_archive_title_format'] ) &&
|
||||
empty( $this->oldOptions['aiosp_date_title_format'] )
|
||||
) {
|
||||
$this->oldOptions['aiosp_date_title_format'] = $this->oldOptions['aiosp_archive_title_format'];
|
||||
unset( $this->oldOptions['aiosp_archive_title_format'] );
|
||||
}
|
||||
|
||||
if (
|
||||
isset( $this->oldOptions['aiosp_archive_title_format'] ) &&
|
||||
'%date% | %site_title%' === $this->oldOptions['aiosp_archive_title_format']
|
||||
) {
|
||||
unset( $this->oldOptions['aiosp_archive_title_format'] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Corrects the value of a number of settings in V3 that are illogical.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function fixSettingValues() {
|
||||
$settingsToFix = [
|
||||
'aiosp_togglekeywords'
|
||||
];
|
||||
foreach ( $settingsToFix as $settingToFix ) {
|
||||
if ( isset( $this->oldOptions[ $settingToFix ] ) ) {
|
||||
if ( '1' === (string) $this->oldOptions[ $settingToFix ] ) {
|
||||
$this->oldOptions[ $settingToFix ] = '';
|
||||
continue;
|
||||
}
|
||||
$this->oldOptions[ $settingToFix ] = 'on';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
namespace AIOSEO\Plugin\Common\Migration;
|
||||
|
||||
// Exit if accessed directly.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
// phpcs:disable WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound
|
||||
|
||||
/**
|
||||
* Migrates the Robots.txt settings from V3.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
class RobotsTxt {
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public function __construct() {
|
||||
$oldOptions = aioseo()->migration->oldOptions;
|
||||
|
||||
$rules = aioseo()->options->tools->robots->rules;
|
||||
|
||||
if (
|
||||
! empty( $oldOptions['modules']['aiosp_robots_options'] ) &&
|
||||
! empty( $oldOptions['modules']['aiosp_robots_options']['aiosp_robots_rules'] )
|
||||
) {
|
||||
$rules += $this->convertRules( $oldOptions['modules']['aiosp_robots_options']['aiosp_robots_rules'] );
|
||||
}
|
||||
|
||||
aioseo()->options->tools->robots->rules = $rules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the old Robots.txt rules to the new format.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @param array $oldRules The old rules.
|
||||
* @return array $newRules The converted rules.
|
||||
*/
|
||||
private function convertRules( $oldRules ) {
|
||||
$newRules = [];
|
||||
foreach ( $oldRules as $oldRule ) {
|
||||
$newRule = new \stdClass();
|
||||
$newRule->userAgent = aioseo()->helpers->sanitizeOption( $oldRule['agent'] );
|
||||
$newRule->rule = aioseo()->helpers->sanitizeOption( lcfirst( $oldRule['type'] ) );
|
||||
$newRule->directoryPath = aioseo()->helpers->sanitizeOption( $oldRule['path'] );
|
||||
|
||||
array_push( $newRules, wp_json_encode( $newRule ) );
|
||||
}
|
||||
|
||||
return $newRules;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,414 @@
|
||||
<?php
|
||||
namespace AIOSEO\Plugin\Common\Migration;
|
||||
|
||||
// Exit if accessed directly.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
// phpcs:disable WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound
|
||||
|
||||
/**
|
||||
* Migrates the XML Sitemap settings from V3.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
class Sitemap {
|
||||
/**
|
||||
* The old V3 options.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $oldOptions = [];
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->oldOptions = aioseo()->migration->oldOptions;
|
||||
|
||||
if ( empty( $this->oldOptions['modules']['aiosp_sitemap_options'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->checkIfStatic();
|
||||
$this->migrateLinksPerIndex();
|
||||
$this->migrateIncludedObjects();
|
||||
$this->migratePrioFreq();
|
||||
$this->migrateAdditionalPages();
|
||||
$this->migrateExcludedPages();
|
||||
$this->regenerateSitemap();
|
||||
|
||||
$settings = [
|
||||
'aiosp_sitemap_indexes' => [ 'type' => 'boolean', 'newOption' => [ 'sitemap', 'general', 'indexes' ] ],
|
||||
'aiosp_sitemap_archive' => [ 'type' => 'boolean', 'newOption' => [ 'sitemap', 'general', 'date' ] ],
|
||||
'aiosp_sitemap_author' => [ 'type' => 'boolean', 'newOption' => [ 'sitemap', 'general', 'author' ] ],
|
||||
'aiosp_sitemap_images' => [ 'type' => 'boolean', 'newOption' => [ 'sitemap', 'general', 'advancedSettings', 'excludeImages' ] ],
|
||||
'aiosp_sitemap_rss_sitemap' => [ 'type' => 'boolean', 'newOption' => [ 'sitemap', 'rss', 'enable' ] ],
|
||||
'aiosp_sitemap_filename' => [ 'type' => 'string', 'newOption' => [ 'sitemap', 'general', 'filename' ] ],
|
||||
'aiosp_sitemap_publication_name' => [ 'type' => 'boolean', 'newOption' => [ 'sitemap', 'news', 'publicationName' ] ],
|
||||
'aiosp_sitemap_rewrite' => [ 'type' => 'boolean', 'newOption' => [ 'deprecated', 'sitemap', 'general', 'advancedSettings', 'dynamic' ] ]
|
||||
];
|
||||
|
||||
aioseo()->migration->helpers->mapOldToNew( $settings, $this->oldOptions['modules']['aiosp_sitemap_options'] );
|
||||
|
||||
if (
|
||||
aioseo()->options->sitemap->general->advancedSettings->excludePosts ||
|
||||
aioseo()->options->sitemap->general->advancedSettings->excludeTerms ||
|
||||
aioseo()->options->sitemap->general->advancedSettings->excludeImages ||
|
||||
( in_array( 'staticSitemap', aioseo()->internalOptions->internal->deprecatedOptions, true ) && ! aioseo()->options->deprecated->sitemap->general->advancedSettings->dynamic )
|
||||
) {
|
||||
aioseo()->options->sitemap->general->advancedSettings->enable = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the sitemap is statically generated.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function checkIfStatic() {
|
||||
if (
|
||||
isset( $this->oldOptions['modules']['aiosp_sitemap_options']['aiosp_sitemap_rewrite'] ) &&
|
||||
empty( $this->oldOptions['modules']['aiosp_sitemap_options']['aiosp_sitemap_rewrite'] )
|
||||
) {
|
||||
$deprecatedOptions = aioseo()->internalOptions->internal->deprecatedOptions;
|
||||
array_push( $deprecatedOptions, 'staticSitemap' );
|
||||
aioseo()->internalOptions->internal->deprecatedOptions = $deprecatedOptions;
|
||||
|
||||
aioseo()->options->deprecated->sitemap->general->advancedSettings->dynamic = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates the amount of links per sitemap index.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function migrateLinksPerIndex() {
|
||||
if ( ! empty( $this->oldOptions['modules']['aiosp_sitemap_options']['aiosp_sitemap_max_posts'] ) ) {
|
||||
$value = intval( $this->oldOptions['modules']['aiosp_sitemap_options']['aiosp_sitemap_max_posts'] );
|
||||
if ( ! $value ) {
|
||||
return;
|
||||
}
|
||||
$value = $value > 50000 ? 50000 : $value;
|
||||
aioseo()->options->sitemap->general->linksPerIndex = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates the excluded object settings.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function migrateExcludedPages() {
|
||||
if (
|
||||
empty( $this->oldOptions['modules']['aiosp_sitemap_options']['aiosp_sitemap_excl_terms'] ) &&
|
||||
empty( $this->oldOptions['modules']['aiosp_sitemap_options']['aiosp_sitemap_excl_pages'] )
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
$excludedPosts = aioseo()->options->sitemap->general->advancedSettings->excludePosts;
|
||||
if ( ! empty( $this->oldOptions['modules']['aiosp_sitemap_options']['aiosp_sitemap_excl_pages'] ) ) {
|
||||
$pages = explode( ',', $this->oldOptions['modules']['aiosp_sitemap_options']['aiosp_sitemap_excl_pages'] );
|
||||
if ( count( $pages ) ) {
|
||||
foreach ( $pages as $page ) {
|
||||
$page = trim( $page );
|
||||
$id = intval( $page );
|
||||
if ( ! $id ) {
|
||||
$post = get_page_by_path( $page, OBJECT, aioseo()->helpers->getPublicPostTypes( true ) );
|
||||
if ( $post && is_object( $post ) ) {
|
||||
$id = $post->ID;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $id ) {
|
||||
$post = get_post( $id );
|
||||
if ( ! is_object( $post ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$excludedPost = new \stdClass();
|
||||
$excludedPost->value = $id;
|
||||
$excludedPost->type = $post->post_type;
|
||||
$excludedPost->label = $post->post_title;
|
||||
$excludedPost->link = get_permalink( $id );
|
||||
|
||||
array_push( $excludedPosts, wp_json_encode( $excludedPost ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
aioseo()->options->sitemap->general->advancedSettings->excludePosts = $excludedPosts;
|
||||
|
||||
$excludedTerms = aioseo()->options->sitemap->general->advancedSettings->excludeTerms;
|
||||
if ( ! empty( $this->oldOptions['modules']['aiosp_sitemap_options']['aiosp_sitemap_excl_terms'] ) ) {
|
||||
foreach ( $this->oldOptions['modules']['aiosp_sitemap_options']['aiosp_sitemap_excl_terms'] as $taxonomy ) {
|
||||
foreach ( $taxonomy['terms'] as $id ) {
|
||||
$term = get_term( $id );
|
||||
if ( ! is_a( $term, 'WP_Term' ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$excludedTerm = new \stdClass();
|
||||
$excludedTerm->value = $id;
|
||||
$excludedTerm->type = $term->taxonomy;
|
||||
$excludedTerm->label = $term->name;
|
||||
$excludedTerm->link = get_term_link( $term );
|
||||
|
||||
array_push( $excludedTerms, wp_json_encode( $excludedTerm ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
aioseo()->options->sitemap->general->advancedSettings->excludeTerms = $excludedTerms;
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates the objects that are included in the sitemap.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function migrateIncludedObjects() {
|
||||
if (
|
||||
! isset( $this->oldOptions['modules']['aiosp_sitemap_options']['aiosp_sitemap_posttypes'] ) &&
|
||||
! isset( $this->oldOptions['modules']['aiosp_sitemap_options']['aiosp_sitemap_taxonomies'] )
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! is_array( $this->oldOptions['modules']['aiosp_sitemap_options']['aiosp_sitemap_posttypes'] ) ) {
|
||||
$this->oldOptions['modules']['aiosp_sitemap_options']['aiosp_sitemap_posttypes'] = [];
|
||||
}
|
||||
|
||||
if ( ! is_array( $this->oldOptions['modules']['aiosp_sitemap_options']['aiosp_sitemap_taxonomies'] ) ) {
|
||||
$this->oldOptions['modules']['aiosp_sitemap_options']['aiosp_sitemap_taxonomies'] = [];
|
||||
}
|
||||
|
||||
$publicPostTypes = aioseo()->helpers->getPublicPostTypes( true );
|
||||
$publicTaxonomies = aioseo()->helpers->getPublicTaxonomies( true );
|
||||
|
||||
if ( in_array( 'all', $this->oldOptions['modules']['aiosp_sitemap_options']['aiosp_sitemap_posttypes'], true ) ) {
|
||||
aioseo()->options->sitemap->general->postTypes->all = true;
|
||||
aioseo()->options->sitemap->general->postTypes->included = array_values( $publicPostTypes );
|
||||
} else {
|
||||
$allPostTypes = true;
|
||||
foreach ( $publicPostTypes as $postType ) {
|
||||
if ( ! in_array( $postType, $this->oldOptions['modules']['aiosp_sitemap_options']['aiosp_sitemap_posttypes'], true ) ) {
|
||||
$allPostTypes = false;
|
||||
}
|
||||
}
|
||||
|
||||
aioseo()->options->sitemap->general->postTypes->all = $allPostTypes;
|
||||
aioseo()->options->sitemap->general->postTypes->included = array_values(
|
||||
array_intersect( $publicPostTypes, $this->oldOptions['modules']['aiosp_sitemap_options']['aiosp_sitemap_posttypes'] )
|
||||
);
|
||||
}
|
||||
|
||||
if ( in_array( 'all', $this->oldOptions['modules']['aiosp_sitemap_options']['aiosp_sitemap_taxonomies'], true ) ) {
|
||||
aioseo()->options->sitemap->general->taxonomies->all = true;
|
||||
aioseo()->options->sitemap->general->taxonomies->included = array_values( $publicTaxonomies );
|
||||
} else {
|
||||
$allTaxonomies = true;
|
||||
foreach ( $publicTaxonomies as $taxonomy ) {
|
||||
if ( ! in_array( $taxonomy, $this->oldOptions['modules']['aiosp_sitemap_options']['aiosp_sitemap_taxonomies'], true ) ) {
|
||||
$allTaxonomies = false;
|
||||
}
|
||||
}
|
||||
|
||||
aioseo()->options->sitemap->general->taxonomies->all = $allTaxonomies;
|
||||
aioseo()->options->sitemap->general->taxonomies->included = array_values(
|
||||
array_intersect( $publicTaxonomies, $this->oldOptions['modules']['aiosp_sitemap_options']['aiosp_sitemap_taxonomies'] )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates the additional pages that are included in the sitemap.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function migrateAdditionalPages() {
|
||||
if ( empty( $this->oldOptions['modules']['aiosp_sitemap_options']['aiosp_sitemap_addl_pages'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$pages = [];
|
||||
foreach ( $this->oldOptions['modules']['aiosp_sitemap_options']['aiosp_sitemap_addl_pages'] as $url => $values ) {
|
||||
$page = new \stdClass();
|
||||
$page->url = esc_url( wp_strip_all_tags( $url ) );
|
||||
$page->priority = [ 'label' => $values['prio'], 'value' => $values['prio'] ];
|
||||
$page->frequency = [ 'label' => $values['freq'], 'value' => $values['freq'] ];
|
||||
$page->lastModified = gmdate( 'm/d/Y', strtotime( $values['mod'] ) );
|
||||
|
||||
$pages[] = wp_json_encode( $page );
|
||||
}
|
||||
|
||||
aioseo()->options->sitemap->general->additionalPages->enable = true;
|
||||
aioseo()->options->sitemap->general->additionalPages->pages = $pages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates the priority/frequency settings.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function migratePrioFreq() {
|
||||
$settings = [
|
||||
'aiosp_sitemap_prio_homepage' => [ 'type' => 'float', 'newOption' => [ 'sitemap', 'general', 'advancedSettings', 'priority', 'homePage', 'priority' ] ],
|
||||
'aiosp_sitemap_freq_homepage' => [ 'type' => 'string', 'newOption' => [ 'sitemap', 'general', 'advancedSettings', 'priority', 'homePage', 'frequency' ] ],
|
||||
'aiosp_sitemap_prio_post' => [ 'type' => 'float', 'newOption' => [ 'sitemap', 'general', 'advancedSettings', 'priority', 'postTypes', 'priority' ] ],
|
||||
'aiosp_sitemap_freq_post' => [ 'type' => 'string', 'newOption' => [ 'sitemap', 'general', 'advancedSettings', 'priority', 'postTypes', 'frequency' ] ],
|
||||
'aiosp_sitemap_prio_post_post' => [ 'type' => 'float', 'newOption' => [ 'sitemap', 'priority', 'postTypes', 'post', 'priority' ], 'dynamic' => true ],
|
||||
'aiosp_sitemap_freq_post_post' => [ 'type' => 'string', 'newOption' => [ 'sitemap', 'priority', 'postTypes', 'post', 'frequency' ], 'dynamic' => true ],
|
||||
'aiosp_sitemap_prio_taxonomies' => [ 'type' => 'float', 'newOption' => [ 'sitemap', 'general', 'advancedSettings', 'priority', 'taxonomies', 'priority' ] ],
|
||||
'aiosp_sitemap_freq_taxonomies' => [ 'type' => 'string', 'newOption' => [ 'sitemap', 'general', 'advancedSettings', 'priority', 'taxonomies', 'frequency' ] ],
|
||||
'aiosp_sitemap_prio_archive' => [ 'type' => 'float', 'newOption' => [ 'sitemap', 'general', 'advancedSettings', 'priority', 'archive', 'priority' ] ],
|
||||
'aiosp_sitemap_freq_archive' => [ 'type' => 'string', 'newOption' => [ 'sitemap', 'general', 'advancedSettings', 'priority', 'archive', 'frequency' ] ],
|
||||
'aiosp_sitemap_prio_author' => [ 'type' => 'float', 'newOption' => [ 'sitemap', 'general', 'advancedSettings', 'priority', 'author', 'priority' ] ],
|
||||
'aiosp_sitemap_freq_author' => [ 'type' => 'string', 'newOption' => [ 'sitemap', 'general', 'advancedSettings', 'priority', 'author', 'frequency' ] ],
|
||||
];
|
||||
|
||||
foreach ( $this->oldOptions['modules']['aiosp_sitemap_options'] as $name => $value ) {
|
||||
// Ignore fixed settings.
|
||||
if ( in_array( $name, array_keys( $settings ), true ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$type = false;
|
||||
$slug = '';
|
||||
if ( preg_match( '#aiosp_sitemap_prio_(.*)#', (string) $name, $slug ) ) {
|
||||
$type = 'priority';
|
||||
} elseif ( preg_match( '#aiosp_sitemap_freq_(.*)#', (string) $name, $slug ) ) {
|
||||
$type = 'frequency';
|
||||
}
|
||||
|
||||
if ( empty( $slug ) || empty( $slug[1] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$objectSlug = aioseo()->helpers->pregReplace( '#post_(?!tag)|taxonomies_#', '', $slug[1] );
|
||||
|
||||
if ( in_array( $objectSlug, aioseo()->helpers->getPublicPostTypes( true ), true ) ) {
|
||||
$settings[ $name ] = [
|
||||
'type' => 'priority' === $type ? 'float' : 'string',
|
||||
'newOption' => [ 'sitemap', 'priority', 'postTypes', $objectSlug, $type ],
|
||||
'dynamic' => true
|
||||
];
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( in_array( $objectSlug, aioseo()->helpers->getPublicTaxonomies( true ), true ) ) {
|
||||
$settings[ $name ] = [
|
||||
'type' => 'priority' === $type ? 'float' : 'string',
|
||||
'newOption' => [ 'sitemap', 'priority', 'taxonomies', $objectSlug, $type ],
|
||||
'dynamic' => true
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$mainOptions = aioseo()->options->noConflict();
|
||||
$dynamicOptions = aioseo()->dynamicOptions->noConflict();
|
||||
foreach ( $settings as $name => $values ) {
|
||||
// If setting is set to default, do nothing.
|
||||
if (
|
||||
empty( $this->oldOptions['modules']['aiosp_sitemap_options'][ $name ] ) ||
|
||||
'no' === $this->oldOptions['modules']['aiosp_sitemap_options'][ $name ]
|
||||
) {
|
||||
unset( $settings[ $name ] );
|
||||
continue;
|
||||
}
|
||||
|
||||
// If value is "Select Individual", set grouped to false.
|
||||
$value = $this->oldOptions['modules']['aiosp_sitemap_options'][ $name ];
|
||||
if ( 'sel' === $value ) {
|
||||
if ( preg_match( '#post$#', (string) $name ) ) {
|
||||
aioseo()->options->sitemap->general->advancedSettings->priority->postTypes->grouped = false;
|
||||
} else {
|
||||
aioseo()->options->sitemap->general->advancedSettings->priority->taxonomies->grouped = false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
$object = new \stdClass();
|
||||
$object->label = $value;
|
||||
$object->value = $value;
|
||||
|
||||
$error = false;
|
||||
$options = ! empty( $values['dynamic'] ) ? $dynamicOptions : $mainOptions;
|
||||
$lastOption = '';
|
||||
for ( $i = 0; $i < count( $values['newOption'] ); $i++ ) {
|
||||
$lastOption = $values['newOption'][ $i ];
|
||||
if ( ! $options->has( $lastOption, false ) ) {
|
||||
$error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( count( $values['newOption'] ) - 1 !== $i ) {
|
||||
$options = $options->$lastOption;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $error ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$options->$lastOption = wp_json_encode( $object );
|
||||
}
|
||||
|
||||
if ( count( $settings ) ) {
|
||||
$mainOptions->sitemap->general->advancedSettings->enable = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Regenerates the sitemap if it is static.
|
||||
*
|
||||
* We need to do this since the stylesheet URLs have changed.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function regenerateSitemap() {
|
||||
if (
|
||||
isset( $this->oldOptions['modules']['aiosp_sitemap_options']['aiosp_sitemap_rewrite'] ) &&
|
||||
empty( $this->oldOptions['modules']['aiosp_sitemap_options']['aiosp_sitemap_rewrite'] )
|
||||
) {
|
||||
$files = aioseo()->sitemap->file->files();
|
||||
$detectedFiles = [];
|
||||
foreach ( $files as $filename ) {
|
||||
// We don't want to delete the video sitemap here at all.
|
||||
$isVideoSitemap = preg_match( '#.*video.*#', (string) $filename ) ? true : false;
|
||||
if ( ! $isVideoSitemap ) {
|
||||
$detectedFiles[] = $filename;
|
||||
}
|
||||
}
|
||||
|
||||
$fs = aioseo()->core->fs;
|
||||
if ( count( $detectedFiles ) && $fs->isWpfsValid() ) {
|
||||
foreach ( $detectedFiles as $file ) {
|
||||
$fs->fs->delete( $file, false, 'f' );
|
||||
}
|
||||
}
|
||||
|
||||
aioseo()->sitemap->file->generate( true );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,493 @@
|
||||
<?php
|
||||
namespace AIOSEO\Plugin\Common\Migration;
|
||||
|
||||
// Exit if accessed directly.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
use AIOSEO\Plugin\Common\Models;
|
||||
|
||||
// phpcs:disable WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound
|
||||
|
||||
/**
|
||||
* Migrates the Social Meta settings from V3.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
class SocialMeta {
|
||||
/**
|
||||
* The old V3 options.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $oldOptions = [];
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->oldOptions = aioseo()->migration->oldOptions;
|
||||
|
||||
if ( empty( $this->oldOptions['modules']['aiosp_opengraph_options'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->migrateHomePageOgTitle();
|
||||
$this->migrateHomePageOgDescription();
|
||||
$this->migrateTwitterUsername();
|
||||
$this->migrateTwitterCardType();
|
||||
$this->migrateSocialPostImageSettings();
|
||||
$this->migrateDefaultObjectTypes();
|
||||
$this->migrateAdvancedSettings();
|
||||
$this->migrateProfileSocialUrls();
|
||||
|
||||
if ( ! empty( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_sitename'] ) ) {
|
||||
aioseo()->options->social->facebook->general->siteName = aioseo()->helpers->sanitizeOption( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_sitename'] );
|
||||
}
|
||||
|
||||
$settings = [
|
||||
'aiosp_opengraph_facebook_author' => [ 'type' => 'boolean', 'newOption' => [ 'social', 'facebook', 'general', 'showAuthor' ] ],
|
||||
'aiosp_opengraph_twitter_creator' => [ 'type' => 'boolean', 'newOption' => [ 'social', 'twitter', 'general', 'showAuthor' ] ],
|
||||
];
|
||||
|
||||
aioseo()->migration->helpers->mapOldToNew( $settings, $this->oldOptions['modules']['aiosp_opengraph_options'] );
|
||||
|
||||
$this->maybeShowOgNotices();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if we need to add a notice about the OG deprecated settings.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function maybeShowOgNotices() {
|
||||
$include = [];
|
||||
|
||||
// Check if any of thw following are set to true.
|
||||
if ( ! empty( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_generate_descriptions'] ) ) {
|
||||
$include[] = __( 'Use Content for Autogenerated Descriptions', 'all-in-one-seo-pack' );
|
||||
}
|
||||
|
||||
if ( ! empty( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_description_shortcodes'] ) ) {
|
||||
$include[] = __( 'Run Shortcodes in Description', 'all-in-one-seo-pack' );
|
||||
}
|
||||
|
||||
if ( ! empty( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_title_shortcodes'] ) ) {
|
||||
$include[] = __( 'Run Shortcodes in Title', 'all-in-one-seo-pack' );
|
||||
}
|
||||
|
||||
if ( empty( $include ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$content = __( 'Due to some changes in how our Open Graph integration works, your Facebook Titles and Descriptions may have changed. You were using the following options that have been removed:', 'all-in-one-seo-pack' ) . '<ul>'; // phpcs:ignore Generic.Files.LineLength.MaxExceeded
|
||||
|
||||
foreach ( $include as $setting ) {
|
||||
$content .= '<li><strong>' . $setting . '</strong></li>';
|
||||
}
|
||||
|
||||
$content .= '</ul>';
|
||||
|
||||
$notification = Models\Notification::getNotificationByName( 'v3-migration-deprecated-opengraph' );
|
||||
if ( $notification->notification_name ) {
|
||||
return;
|
||||
}
|
||||
|
||||
Models\Notification::addNotification( [
|
||||
'slug' => uniqid(),
|
||||
'notification_name' => 'v3-migration-deprecated-opengraph',
|
||||
'title' => __( 'Review Your Facebook Open Graph Titles and Descriptions', 'all-in-one-seo-pack' ),
|
||||
'content' => $content,
|
||||
'type' => 'warning',
|
||||
'level' => [ 'all' ],
|
||||
'button1_label' => __( 'Learn More', 'all-in-one-seo-pack' ),
|
||||
'button1_action' => aioseo()->helpers->utmUrl( AIOSEO_MARKETING_URL . 'docs/deprecated-opengraph-settings', 'notifications-center', 'v3-migration-deprecated-opengraph' ),
|
||||
'start' => gmdate( 'Y-m-d H:i:s' )
|
||||
] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates the Open Graph homepage title.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function migrateHomePageOgTitle() {
|
||||
$showOnFront = get_option( 'show_on_front' );
|
||||
$pageOnFront = (int) get_option( 'page_on_front' );
|
||||
$useHomePageMeta = ! empty( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_setmeta'] );
|
||||
$format = $this->oldOptions['aiosp_home_page_title_format'];
|
||||
|
||||
// Latest Posts.
|
||||
if ( 'posts' === $showOnFront ) {
|
||||
$ogTitle = aioseo()->helpers->pregReplace( '#%page_title%#', '#site_title', $format );
|
||||
if ( ! $useHomePageMeta ) {
|
||||
if ( ! empty( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_hometitle'] ) ) {
|
||||
$ogTitle = $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_hometitle'];
|
||||
}
|
||||
aioseo()->options->social->facebook->homePage->title = aioseo()->helpers->sanitizeOption( aioseo()->migration->helpers->macrosToSmartTags( $ogTitle ) );
|
||||
aioseo()->options->social->twitter->homePage->title = aioseo()->helpers->sanitizeOption( aioseo()->migration->helpers->macrosToSmartTags( $ogTitle ) );
|
||||
|
||||
return;
|
||||
}
|
||||
$title = aioseo()->options->searchAppearance->global->siteTitle;
|
||||
$ogTitle = $title ? $title : $ogTitle;
|
||||
aioseo()->options->social->facebook->homePage->title = aioseo()->helpers->sanitizeOption( $ogTitle );
|
||||
aioseo()->options->social->twitter->homePage->title = aioseo()->helpers->sanitizeOption( $ogTitle );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Static Home Page.
|
||||
$post = 'page' === $showOnFront && $pageOnFront ? aioseo()->helpers->getPost( $pageOnFront ) : '';
|
||||
$aioseoPost = Models\Post::getPost( $post->ID );
|
||||
$seoTitle = get_post_meta( $post->ID, '_aioseop_title', true );
|
||||
$ogMeta = get_post_meta( $post->ID, '_aioseop_opengraph_settings', true );
|
||||
|
||||
if ( ! $ogMeta ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$ogMeta = aioseo()->helpers->maybeUnserialize( $ogMeta );
|
||||
|
||||
$ogTitle = '';
|
||||
if ( ! $useHomePageMeta ) {
|
||||
if ( empty( $this->oldOptions['aiosp_use_static_home_info'] ) ) {
|
||||
$ogTitle = ! empty( $this->oldOptions['aiosp_home_title'] ) ? $this->oldOptions['aiosp_home_title'] : $ogTitle;
|
||||
if ( ! empty( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_hometitle'] ) ) {
|
||||
$ogTitle = $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_hometitle'];
|
||||
}
|
||||
if ( ! empty( $ogMeta['aioseop_opengraph_settings_title'] ) ) {
|
||||
$ogTitle = $ogMeta['aioseop_opengraph_settings_title'];
|
||||
} elseif ( ! empty( $seoTitle ) ) {
|
||||
if ( empty( $ogTitle ) ) {
|
||||
$ogTitle = $seoTitle;
|
||||
} elseif ( empty( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_hometitle'] ) ) {
|
||||
$ogTitle = $seoTitle;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( empty( $this->oldOptions['aiosp_use_static_home_info'] ) ) {
|
||||
$ogTitle = $aioseoPost->title;
|
||||
if ( ! empty( $ogMeta['aioseop_opengraph_settings_title'] ) ) {
|
||||
$ogTitle = $ogMeta['aioseop_opengraph_settings_title'];
|
||||
}
|
||||
$ogTitle = ! empty( $this->oldOptions['aiosp_home_title'] ) ? $this->oldOptions['aiosp_home_title'] : $ogTitle;
|
||||
if ( ! empty( $seoTitle ) ) {
|
||||
$ogTitle = $seoTitle;
|
||||
}
|
||||
} else {
|
||||
$ogTitle = ! empty( $seoTitle ) ? $seoTitle : $ogTitle;
|
||||
}
|
||||
}
|
||||
|
||||
$ogTitle = aioseo()->helpers->sanitizeOption( aioseo()->migration->helpers->macrosToSmartTags( $ogTitle ) );
|
||||
$aioseoPost->set( [
|
||||
'post_id' => $post->ID,
|
||||
'og_title' => $ogTitle,
|
||||
'twitter_title' => $ogTitle
|
||||
] );
|
||||
$aioseoPost->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates the Open Graph homepage description.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function migrateHomePageOgDescription() {
|
||||
$showOnFront = get_option( 'show_on_front' );
|
||||
$pageOnFront = (int) get_option( 'page_on_front' );
|
||||
$useHomePageMeta = ! empty( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_setmeta'] );
|
||||
$format = $this->oldOptions['aiosp_description_format'];
|
||||
|
||||
if ( 'posts' === $showOnFront ) {
|
||||
$ogDescription = aioseo()->helpers->pregReplace( '#%description%#', '#tagline', $format );
|
||||
if ( ! $useHomePageMeta ) {
|
||||
if ( ! empty( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_description'] ) ) {
|
||||
$ogDescription = $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_description'];
|
||||
}
|
||||
aioseo()->options->social->facebook->homePage->description = aioseo()->helpers->sanitizeOption( aioseo()->migration->helpers->macrosToSmartTags( $ogDescription ) );
|
||||
aioseo()->options->social->twitter->homePage->description = aioseo()->helpers->sanitizeOption( aioseo()->migration->helpers->macrosToSmartTags( $ogDescription ) );
|
||||
|
||||
return;
|
||||
}
|
||||
$description = aioseo()->options->searchAppearance->global->metaDescription;
|
||||
$ogDescription = $description ? $description : $ogDescription;
|
||||
aioseo()->options->social->facebook->homePage->description = aioseo()->helpers->sanitizeOption( $ogDescription );
|
||||
aioseo()->options->social->twitter->homePage->description = aioseo()->helpers->sanitizeOption( $ogDescription );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$post = 'page' === $showOnFront && $pageOnFront ? aioseo()->helpers->getPost( $pageOnFront ) : '';
|
||||
$aioseoPost = Models\Post::getPost( $post->ID );
|
||||
$seoDescription = get_post_meta( $post->ID, '_aioseop_description', true );
|
||||
$ogMeta = get_post_meta( $post->ID, '_aioseop_opengraph_settings', true );
|
||||
|
||||
if ( ! $ogMeta ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$ogMeta = aioseo()->helpers->maybeUnserialize( $ogMeta );
|
||||
|
||||
$ogDescription = '';
|
||||
if ( ! $useHomePageMeta ) {
|
||||
if ( empty( $this->oldOptions['aiosp_use_static_home_info'] ) ) {
|
||||
$ogDescription = ! empty( $this->oldOptions['aiosp_home_description'] ) ? $this->oldOptions['aiosp_home_description'] : $ogDescription;
|
||||
if ( ! empty( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_description'] ) ) {
|
||||
$ogDescription = $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_description'];
|
||||
}
|
||||
if ( ! empty( $ogMeta['aioseop_opengraph_settings_desc'] ) ) {
|
||||
$ogDescription = $ogMeta['aioseop_opengraph_settings_desc'];
|
||||
} elseif ( ! empty( $seoDescription ) ) {
|
||||
if ( empty( $ogDescription ) ) {
|
||||
$ogDescription = $seoDescription;
|
||||
} elseif ( empty( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_description'] ) ) {
|
||||
$ogDescription = $seoDescription;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( empty( $this->oldOptions['aiosp_use_static_home_info'] ) ) {
|
||||
$ogDescription = $aioseoPost->description;
|
||||
if ( ! empty( $ogMeta['aioseop_opengraph_settings_desc'] ) ) {
|
||||
$ogDescription = $ogMeta['aioseop_opengraph_settings_desc'];
|
||||
}
|
||||
$ogDescription = ! empty( $this->oldOptions['aiosp_home_description'] ) ? $this->oldOptions['aiosp_home_description'] : $ogDescription;
|
||||
if ( ! empty( $seoDescription ) ) {
|
||||
$ogDescription = $seoDescription;
|
||||
}
|
||||
} else {
|
||||
$ogDescription = ! empty( $seoDescription ) ? $seoDescription : $ogDescription;
|
||||
}
|
||||
}
|
||||
|
||||
$ogDescription = aioseo()->helpers->sanitizeOption( aioseo()->migration->helpers->macrosToSmartTags( $ogDescription ) );
|
||||
$aioseoPost->set( [
|
||||
'post_id' => $post->ID,
|
||||
'og_description' => $ogDescription,
|
||||
'twitter_description' => $ogDescription
|
||||
] );
|
||||
$aioseoPost->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates the Open Graph default post images.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function migrateSocialPostImageSettings() {
|
||||
if ( ! empty( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_homeimage'] ) ) {
|
||||
$value = esc_url( wp_strip_all_tags( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_homeimage'] ) );
|
||||
aioseo()->options->social->facebook->homePage->image = $value;
|
||||
aioseo()->options->social->twitter->homePage->image = $value;
|
||||
}
|
||||
|
||||
if ( ! empty( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_defimg'] ) ) {
|
||||
$value = aioseo()->helpers->sanitizeOption( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_defimg'] );
|
||||
aioseo()->options->social->facebook->general->defaultImageSourcePosts = $value;
|
||||
aioseo()->options->social->twitter->general->defaultImageSourcePosts = $value;
|
||||
}
|
||||
|
||||
if (
|
||||
! empty( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_dimg'] ) &&
|
||||
! preg_match( '/default-user-image.png$/', (string) $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_dimg'] )
|
||||
) {
|
||||
$value = esc_url( wp_strip_all_tags( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_dimg'] ) );
|
||||
aioseo()->options->social->facebook->general->defaultImagePosts = $value;
|
||||
aioseo()->options->social->twitter->general->defaultImagePosts = $value;
|
||||
} else {
|
||||
aioseo()->options->social->facebook->general->defaultImagePosts = '';
|
||||
aioseo()->options->social->twitter->general->defaultImagePosts = '';
|
||||
}
|
||||
|
||||
if (
|
||||
! empty( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_dimgwidth'] ) ||
|
||||
! empty( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_dimgheight'] )
|
||||
) {
|
||||
aioseo()->options->social->facebook->general->defaultImageWidthPosts =
|
||||
aioseo()->helpers->sanitizeOption( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_dimgwidth'] );
|
||||
aioseo()->options->social->facebook->general->defaultImageHeightPosts =
|
||||
aioseo()->helpers->sanitizeOption( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_dimgheight'] );
|
||||
}
|
||||
|
||||
if ( ! empty( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_meta_key'] ) ) {
|
||||
$value = aioseo()->helpers->sanitizeOption( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_meta_key'] );
|
||||
aioseo()->options->social->facebook->general->customFieldImagePosts = $value;
|
||||
aioseo()->options->social->twitter->general->customFieldImagePosts = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates the Twitter username.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function migrateTwitterUsername() {
|
||||
if (
|
||||
! empty( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_twitter_site'] ) &&
|
||||
! aioseo()->options->social->profiles->urls->twitterUrl
|
||||
) {
|
||||
$username = ltrim( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_twitter_site'], '@' );
|
||||
aioseo()->options->social->profiles->urls->twitterUrl =
|
||||
esc_url( 'https://x.com/' . aioseo()->social->twitter->prepareUsername( aioseo()->helpers->sanitizeOption( $username ), false ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates the Twitter card type.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function migrateTwitterCardType() {
|
||||
if ( ! empty( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_defcard'] ) ) {
|
||||
aioseo()->options->social->twitter->general->defaultCardType =
|
||||
aioseo()->helpers->sanitizeOption( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_defcard'] );
|
||||
aioseo()->options->social->twitter->homePage->cardType =
|
||||
aioseo()->helpers->sanitizeOption( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_defcard'] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates the default object types.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function migrateDefaultObjectTypes() {
|
||||
foreach ( aioseo()->helpers->getPublicPostTypes( true ) as $postType ) {
|
||||
$settingName = "aiosp_opengraph_{$postType}_fb_object_type";
|
||||
if ( ! in_array( $settingName, array_keys( $this->oldOptions['modules']['aiosp_opengraph_options'] ), true ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$dynamicOptions = aioseo()->dynamicOptions->noConflict();
|
||||
if ( $dynamicOptions->social->facebook->general->postTypes->has( $postType ) ) {
|
||||
aioseo()->dynamicOptions->social->facebook->general->postTypes->$postType->objectType =
|
||||
aioseo()->helpers->sanitizeOption( $this->oldOptions['modules']['aiosp_opengraph_options'][ $settingName ] );
|
||||
}
|
||||
|
||||
if ( 'post' === $postType ) {
|
||||
aioseo()->options->social->facebook->homePage->objectType =
|
||||
aioseo()->helpers->sanitizeOption( $this->oldOptions['modules']['aiosp_opengraph_options'][ $settingName ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates a number of advanced settings.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function migrateAdvancedSettings() {
|
||||
$advancedEnabled = false;
|
||||
|
||||
if ( ! empty( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_key'] ) ) {
|
||||
$advancedEnabled = true;
|
||||
aioseo()->options->social->facebook->advanced->adminId = aioseo()->helpers->sanitizeOption( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_key'] );
|
||||
}
|
||||
|
||||
if ( ! empty( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_appid'] ) ) {
|
||||
$advancedEnabled = true;
|
||||
aioseo()->options->social->facebook->advanced->appId = aioseo()->helpers->sanitizeOption( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_appid'] );
|
||||
}
|
||||
|
||||
if ( ! empty( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_gen_tags'] ) ) {
|
||||
$advancedEnabled = true;
|
||||
aioseo()->options->social->facebook->advanced->generateArticleTags = true;
|
||||
} else {
|
||||
aioseo()->options->social->facebook->advanced->generateArticleTags = false;
|
||||
}
|
||||
|
||||
if ( ! empty( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_gen_keywords'] ) ) {
|
||||
$advancedEnabled = true;
|
||||
aioseo()->options->social->facebook->advanced->useKeywordsInTags = true;
|
||||
} else {
|
||||
aioseo()->options->social->facebook->advanced->useKeywordsInTags = false;
|
||||
}
|
||||
|
||||
if ( ! empty( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_gen_categories'] ) ) {
|
||||
$advancedEnabled = true;
|
||||
aioseo()->options->social->facebook->advanced->useCategoriesInTags = true;
|
||||
} else {
|
||||
aioseo()->options->social->facebook->advanced->useCategoriesInTags = false;
|
||||
}
|
||||
|
||||
if ( ! empty( $this->oldOptions['modules']['aiosp_opengraph_options']['aiosp_opengraph_gen_post_tags'] ) ) {
|
||||
$advancedEnabled = true;
|
||||
aioseo()->options->social->facebook->advanced->usePostTagsInTags = true;
|
||||
} else {
|
||||
aioseo()->options->social->facebook->advanced->usePostTagsInTags = false;
|
||||
}
|
||||
|
||||
aioseo()->options->social->facebook->advanced->enable = $advancedEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates the social URLs for the author users.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function migrateProfileSocialUrls() {
|
||||
$records = aioseo()->core->db
|
||||
->start( aioseo()->core->db->db->usermeta, true )
|
||||
->select( '*' )
|
||||
->where( 'meta_key', 'facebook' )
|
||||
->run()
|
||||
->result();
|
||||
|
||||
if ( count( $records ) ) {
|
||||
foreach ( $records as $record ) {
|
||||
if ( ! empty( $record->user_id ) && ! empty( $record->meta_value ) ) {
|
||||
update_user_meta(
|
||||
(int) $record->user_id,
|
||||
'aioseo_facebook',
|
||||
esc_url( $record->meta_value )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$records = aioseo()->core->db
|
||||
->start( aioseo()->core->db->db->usermeta, true )
|
||||
->select( '*' )
|
||||
->where( 'meta_key', 'twitter' )
|
||||
->run()
|
||||
->result();
|
||||
|
||||
if ( count( $records ) ) {
|
||||
foreach ( $records as $record ) {
|
||||
if ( ! empty( $record->user_id ) && ! empty( $record->meta_value ) ) {
|
||||
update_user_meta(
|
||||
(int) $record->user_id,
|
||||
'aioseo_twitter',
|
||||
sanitize_text_field( $record->meta_value )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
namespace AIOSEO\Plugin\Common\Migration;
|
||||
|
||||
// Exit if accessed directly.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates the WPML settings from V3.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
class Wpml {
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public function __construct() {
|
||||
// If the tables don't exist (could happen), return early.
|
||||
if ( ! aioseo()->core->db->tableExists( 'icl_strings' ) && ! aioseo()->core->db->tableExists( 'icl_string_translations' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$strings = [
|
||||
'[aioseop_options]aiosp_home_title' => '[aioseo_options_localized]searchAppearance_global_siteTitle',
|
||||
'[aioseop_options]aiosp_home_description' => '[aioseo_options_localized]searchAppearance_global_metaDescription',
|
||||
'[aioseop_options]aiosp_home_keywords' => '[aioseo_options_localized]searchAppearance_global_keywords'
|
||||
];
|
||||
|
||||
try {
|
||||
$v3Results = aioseo()->core->db->start( 'icl_strings' )
|
||||
->where( 'context', 'admin_texts_aioseop_options' )
|
||||
->whereIn( 'name', array_keys( $strings ) )
|
||||
->run()
|
||||
->result();
|
||||
|
||||
$v4Results = aioseo()->core->db->start( 'icl_strings' )
|
||||
->where( 'context', 'admin_texts_aioseo_options_localized' )
|
||||
->whereIn( 'name', array_values( $strings ) )
|
||||
->run()
|
||||
->result();
|
||||
|
||||
if ( ! empty( $v3Results ) ) {
|
||||
foreach ( $v3Results as $result ) {
|
||||
$translations = aioseo()->core->db->start( 'icl_string_translations' )
|
||||
->where( 'string_id', $result->id )
|
||||
->run()
|
||||
->result();
|
||||
|
||||
if ( empty( $translations ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$v4ResultId = null;
|
||||
if ( ! empty( $v4Results ) ) {
|
||||
foreach ( $v4Results as $r ) {
|
||||
if ( $r->name === $strings[ $result->name ] ) {
|
||||
$v4ResultId = $r->id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $v4ResultId ) {
|
||||
$v4ResultId = aioseo()->core->db
|
||||
->insert( 'icl_strings' )
|
||||
->set( [
|
||||
'language' => $result->language,
|
||||
'context' => 'admin_texts_aioseo_options_localized',
|
||||
'name' => $strings[ $result->name ],
|
||||
'value' => $result->value,
|
||||
'string_package_id' => $result->string_package_id,
|
||||
'location' => $result->location,
|
||||
'wrap_tag' => $result->wrap_tag,
|
||||
'type' => $result->type,
|
||||
'title' => $result->title,
|
||||
'status' => $result->status,
|
||||
'gettext_context' => $result->gettext_context,
|
||||
'domain_name_context_md5' => md5( 'admin_texts_aioseo_options_localized' . $strings[ $result->name ] ),
|
||||
'translation_priority' => $result->translation_priority,
|
||||
'word_count' => $result->word_count
|
||||
] )
|
||||
->run()
|
||||
->insertId();
|
||||
}
|
||||
|
||||
foreach ( $translations as $translation ) {
|
||||
// Check if the translation exists first or we'll get a DB error.
|
||||
$v4Translation = aioseo()->core->db->start( 'icl_string_translations' )
|
||||
->where( 'string_id', $v4ResultId )
|
||||
->where( 'language', $translation->language )
|
||||
->run()
|
||||
->result();
|
||||
|
||||
if ( ! empty( $v4Translation ) ) {
|
||||
aioseo()->core->db->update( 'icl_string_translations' )
|
||||
->where( 'string_id', $v4ResultId )
|
||||
->where( 'language', $translation->language )
|
||||
->set( [
|
||||
'value' => $translation->value
|
||||
] )
|
||||
->run();
|
||||
continue;
|
||||
}
|
||||
|
||||
aioseo()->core->db
|
||||
->insert( 'icl_string_translations' )
|
||||
->set( [
|
||||
'string_id' => $v4ResultId,
|
||||
'language' => $translation->language,
|
||||
'status' => $translation->status,
|
||||
'value' => $translation->value,
|
||||
'mo_string' => $translation->mo_string,
|
||||
'translator_id' => $translation->translator_id,
|
||||
'translation_service' => $translation->translation_service,
|
||||
'batch_id' => $translation->batch_id,
|
||||
'translation_date' => $translation->translation_date
|
||||
] )
|
||||
->run();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch ( \Exception $e ) {
|
||||
// If there are any errors, let's just abort. We dont' want to do anything more.
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user