first commit

This commit is contained in:
2026-04-28 15:13:50 +02:00
commit a95acc355b
63745 changed files with 9487948 additions and 0 deletions

View File

@@ -0,0 +1,44 @@
<?php
namespace AIOSEO\Plugin\Pro\ImportExport\YoastSeo;
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
// phpcs:disable WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound
/**
* Migrates the General Settings.
*
* @since 4.0.0
*/
class GeneralSettings {
/**
* List of options.
*
* @since 4.2.7
*
* @var array
*/
private $options = [];
/**
* Class constructor.
*
* @since 4.0.0
*/
public function __construct() {
$this->options = get_option( 'wpseo' );
if ( empty( $this->options ) ) {
return;
}
$settings = [
'enable_admin_bar_menu' => [ 'type' => 'boolean', 'newOption' => [ 'advanced', 'adminBarMenu' ] ],
'tracking' => [ 'type' => 'boolean', 'newOption' => [ 'advanced', 'usageTracking' ] ],
];
aioseo()->importExport->yoastSeo->helpers->mapOldToNew( $settings, $this->options );
}
}

View File

@@ -0,0 +1,69 @@
<?php
namespace AIOSEO\Plugin\Pro\ImportExport\YoastSeo;
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
// phpcs:disable WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound
/**
* Migrates the News Sitemap settings.
*
* @since 4.0.0
*/
class NewsSitemap {
/**
* List of options.
*
* @since 4.2.7
*
* @var array
*/
private $options = [];
/**
* Class constructor.
*
* @since 4.0.0
*/
public function __construct() {
$this->options = get_option( 'wpseo_news' );
if ( empty( $this->options ) ) {
return;
}
$this->migrateIncludedPostTypes();
$settings = [
'news_sitemap_name' => [ 'type' => 'string', 'newOption' => [ 'sitemap', 'news', 'publicationName' ] ],
];
aioseo()->importExport->yoastSeo->helpers->mapOldToNew( $settings, $this->options );
}
/**
* Migrates the included post types.
*
* @since 4.0.0
*
* @return void
*/
private function migrateIncludedPostTypes() {
if ( isset( $this->options['news_sitemap_include_post_types'] ) ) {
$allowedPostTypes = array_diff(
aioseo()->helpers->getPublicPostTypes( true ), aioseo()->helpers->getNoindexedPostTypes(), [ 'attachment' ]
);
$includedPostTypes = array_values(
array_intersect( $allowedPostTypes, array_keys( $this->options['news_sitemap_include_post_types'] ) )
);
aioseo()->options->sitemap->news->postTypes->included = $includedPostTypes;
if ( count( $includedPostTypes ) !== count( $allowedPostTypes ) ) {
aioseo()->options->sitemap->news->postTypes->all = false;
}
}
}
}

View File

@@ -0,0 +1,87 @@
<?php
namespace AIOSEO\Plugin\Pro\ImportExport\YoastSeo;
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
// phpcs:disable WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound
/**
* Migrates the Search Appearance settings.
*
* @since 4.0.0
*/
class SearchAppearance {
/**
* List of options.
*
* @since 4.2.7
*
* @var array
*/
private $options = [];
/**
* Class constructor.
*
* @since 4.0.0
*/
public function __construct() {
$this->options = get_option( 'wpseo_titles' );
if ( empty( $this->options ) ) {
return;
}
$this->migrateTaxonomySettings();
}
/**
* Migrates the taxonomy settings.
*
* @since 4.0.0
*
* @return void
*/
private function migrateTaxonomySettings() {
$supportedSettings = [
'title',
'metadesc',
'noindex',
'display-metabox'
];
foreach ( aioseo()->helpers->getPublicTaxonomies( true ) as $taxonomy ) {
foreach ( $this->options as $name => $value ) {
preg_match( "#(.*)-tax-$taxonomy$#", (string) $name, $match );
if ( ! $match || ! in_array( $match[1], $supportedSettings, true ) ) {
continue;
}
switch ( $match[1] ) {
case 'title':
aioseo()->dynamicOptions->searchAppearance->taxonomies->$taxonomy->title =
aioseo()->helpers->sanitizeOption( aioseo()->importExport->yoastSeo->helpers->macrosToSmartTags( $value ) );
break;
case 'metadesc':
aioseo()->dynamicOptions->searchAppearance->taxonomies->$taxonomy->metaDescription =
aioseo()->helpers->sanitizeOption( aioseo()->importExport->yoastSeo->helpers->macrosToSmartTags( $value ) );
break;
case 'noindex':
aioseo()->dynamicOptions->searchAppearance->taxonomies->$taxonomy->show = empty( $value ) ? true : false;
aioseo()->dynamicOptions->searchAppearance->taxonomies->$taxonomy->advanced->robotsMeta->default = empty( $value ) ? true : false;
aioseo()->dynamicOptions->searchAppearance->taxonomies->$taxonomy->advanced->robotsMeta->noindex = empty( $value ) ? false : true;
break;
case 'display-metabox':
if ( empty( $value ) ) {
aioseo()->dynamicOptions->searchAppearance->taxonomies->$taxonomy->advanced->showMetaBox = false;
}
break;
default:
break;
}
}
}
}
}

View File

@@ -0,0 +1,58 @@
<?php
namespace AIOSEO\Plugin\Pro\ImportExport\YoastSeo;
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
// phpcs:disable WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound
/**
* Migrates the Social Meta.
*
* @since 4.0.0
*/
class SocialMeta {
/**
* List of options.
*
* @since 4.2.7
*
* @var array
*/
private $options = [];
/**
* Class constructor.
*
* @since 4.0.0
*/
public function __construct() {
$this->options = get_option( 'wpseo_social' );
if ( empty( $this->options ) ) {
return;
}
$this->migrateFacebookSettings();
}
/**
* Migrates the Facebook settings.
*
* @since 4.0.0
*
* @return void
*/
private function migrateFacebookSettings() {
if ( ! empty( $this->options['og_default_image'] ) ) {
$defaultImage = esc_url( $this->options['og_default_image'] );
aioseo()->options->social->facebook->general->defaultImageTerms = $defaultImage;
aioseo()->options->social->facebook->general->defaultImageSourceTerms = 'default';
aioseo()->options->social->twitter->general->defaultImageTerms = $defaultImage;
aioseo()->options->social->twitter->general->defaultImageSourceTerms = 'default';
}
}
}

View File

@@ -0,0 +1,197 @@
<?php
namespace AIOSEO\Plugin\Pro\ImportExport\YoastSeo;
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
use AIOSEO\Plugin\Pro\Models;
// phpcs:disable WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound
/**
* Imports the term meta from Yoast SEO.
*
* @since 4.0.0
*/
class TermMeta {
/**
* The term action name.
*
* @since 4.4.3
*
* @var string
*/
private $termActionName = 'aioseo_import_term_meta_yoast_seo';
/**
* Class constructor.
*
* @since 4.4.3
*
*/
public function __construct() {
add_action( $this->termActionName, [ $this, 'importTermMeta' ] );
}
/**
* Class constructor.
*
* @since 4.0.0
*/
public function scheduleImport() {
try {
if ( as_next_scheduled_action( $this->termActionName ) ) {
return;
}
if ( ! aioseo()->core->cache->get( 'import_term_meta_yoast_seo' ) ) {
aioseo()->core->cache->update( 'import_term_meta_yoast_seo', time(), WEEK_IN_SECONDS );
}
as_schedule_single_action( time(), $this->termActionName, [], 'aioseo' );
} catch ( \Exception $e ) {
// Do nothing.
}
}
/**
* Imports the term meta.
*
* @since 4.0.0
*
* @return void
*/
public function importTermMeta() {
if ( ! aioseo()->core->db->tableExists( 'yoast_indexable' ) ) {
aioseo()->core->cache->delete( 'import_term_meta_yoast_seo' );
return;
}
$termsPerAction = 100;
$publicTaxonomies = implode( "', '", aioseo()->helpers->getPublicTaxonomies( true ) );
$timeStarted = gmdate( 'Y-m-d H:i:s', aioseo()->core->cache->get( 'import_term_meta_yoast_seo' ) );
$terms = aioseo()->core->db
->start( 'yoast_indexable' . ' as yi' )
->select( 'yi.*' )
->leftJoin( 'aioseo_terms as at', '`yi`.`object_id` = `at`.`term_id`' )
->where( 'yi.object_type', 'term' )
->whereRaw( "( yi.object_sub_type IN ( '$publicTaxonomies' ) )" )
->whereRaw( "( at.term_id IS NULL OR at.updated < '$timeStarted' )" )
->orderBy( 'yi.object_id DESC' )
->limit( $termsPerAction )
->run()
->result();
if ( ! $terms || ! count( $terms ) ) {
aioseo()->core->cache->delete( 'import_term_meta_yoast_seo' );
return;
}
$mappedMeta = [
'title' => 'title',
'description' => 'description',
'canonical' => 'canonical_url',
'is_robots_noindex' => 'robots_noindex',
'is_robots_nofollow' => 'robots_nofollow',
'is_robots_noarchive' => 'robots_noarchive',
'is_robots_noimageindex' => 'robots_noimageindex',
'is_robots_nosnippet' => 'robots_nosnippet',
'open_graph_title' => 'og_title',
'open_graph_description' => 'og_description',
'open_graph_image' => 'og_image_custom_url',
'open_graph_image_meta' => '',
'twitter_title' => 'twitter_title',
'twitter_description' => 'twitter_description',
'twitter_image' => 'twitter_image_custom_url',
'twitter_image_source' => 'twitter_image_type',
];
foreach ( $terms as $term ) {
$meta = [
'term_id' => (int) $term->object_id,
'robots_default' => true,
'robots_noindex' => false,
'robots_nofollow' => false,
'robots_noarchive' => false,
'robots_noimageindex' => false,
'robots_nosnippet' => false,
'title' => '',
'description' => '',
'og_title' => '',
'og_description' => '',
'og_image_custom_url' => '',
'og_image_type' => 'default',
'twitter_use_og' => true,
'twitter_title' => '',
'twitter_description' => '',
'twitter_image_custom_url' => '',
'twitter_image_type' => 'default'
];
foreach ( $mappedMeta as $name => $mapping ) {
if ( empty( $term->$name ) ) {
continue;
}
$value = $term->$name;
switch ( $name ) {
case 'is_robots_noindex':
case 'is_robots_nofollow':
case 'is_robots_noarchive':
case 'is_robots_noimageindex':
case 'is_robots_nosnippet':
if ( (bool) $value ) {
$meta[ $mapping ] = true;
$meta['robots_default'] = false;
}
break;
case 'open_graph_image':
$meta['og_image_type'] = 'custom_image';
$meta[ $mapping ] = esc_url( $value );
break;
case 'twitter_image':
$meta['twitter_use_og'] = false;
$meta['twitter_image_type'] = 'custom_image';
$meta[ $mapping ] = esc_url( $value );
break;
case 'open_graph_image_meta':
$imageMeta = json_decode( $value );
if ( ! empty( $imageMeta->width ) && intval( $imageMeta->width ) ) {
$meta['og_image_width'] = intval( $imageMeta->width );
}
if ( ! empty( $imageMeta->height ) && intval( $imageMeta->height ) ) {
$meta['og_image_height'] = intval( $imageMeta->height );
}
break;
case 'title':
case 'description':
case 'open_graph_title':
case 'open_graph_description':
$value = aioseo()->importExport->yoastSeo->helpers->macrosToSmartTags( $value, null, 'term' );
default:
$meta[ $mapping ] = esc_html( wp_strip_all_tags( strval( $value ) ) );
break;
}
}
$aioseoTerm = Models\Term::getTerm( (int) $term->object_id );
$aioseoTerm->set( $meta );
$aioseoTerm->save();
}
if ( count( $terms ) === $termsPerAction ) {
try {
as_schedule_single_action( time() + 30, $this->termActionName, [], 'aioseo' );
} catch ( \Exception $e ) {
// Do nothing.
}
} else {
aioseo()->core->cache->delete( 'import_term_meta_yoast_seo' );
}
}
}

View File

@@ -0,0 +1,88 @@
<?php
namespace AIOSEO\Plugin\Pro\ImportExport\YoastSeo;
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
// phpcs:disable WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound
/**
* Migrates the Video Sitemap settings.
*
* @since 4.0.0
*/
class VideoSitemap {
/**
* List of options.
*
* @since 4.2.7
*
* @var array
*/
private $options = [];
/**
* Class constructor.
*
* @since 4.0.0
*/
public function __construct() {
$this->options = get_option( 'wpseo_video' );
if ( empty( $this->options ) ) {
return;
}
$this->migrateIncludedPostTypes();
$this->migrateIncludedTaxonomies();
}
/**
* Migrates the included post types.
*
* @since 4.0.0
*
* @return void
*/
private function migrateIncludedPostTypes() {
if ( isset( $this->options['videositemap_posttypes'] ) ) {
$allowedPostTypes = array_diff(
aioseo()->helpers->getPublicPostTypes( true ), aioseo()->helpers->getNoindexedPostTypes()
);
$includedPostTypes = array_values(
array_intersect( $allowedPostTypes, $this->options['videositemap_posttypes'] )
);
aioseo()->options->sitemap->video->postTypes->included = $includedPostTypes;
if ( count( $includedPostTypes ) !== count( $allowedPostTypes ) ) {
aioseo()->options->sitemap->video->postTypes->all = false;
}
}
}
/**
* Migrates the included taxonomies.
*
* @since 4.0.0
*
* @return void
*/
private function migrateIncludedTaxonomies() {
if ( isset( $this->options['videositemap_taxonomies'] ) ) {
$allowedTaxonomies = array_diff(
aioseo()->helpers->getPublicTaxonomies( true ), aioseo()->helpers->getNoindexedTaxonomies(), [ 'category', 'post_tag' ]
);
$includedTaxonomies = array_values(
array_intersect( $allowedTaxonomies, $this->options['videositemap_taxonomies'] )
);
aioseo()->options->sitemap->video->taxonomies->included = $includedTaxonomies;
if ( count( $includedTaxonomies ) !== count( $allowedTaxonomies ) ) {
aioseo()->options->sitemap->video->taxonomies->all = false;
}
}
}
}

View File

@@ -0,0 +1,70 @@
<?php
namespace AIOSEO\Plugin\Pro\ImportExport\YoastSeo;
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
use AIOSEO\Plugin\Common\ImportExport\YoastSeo as CommonYoastSeo;
use AIOSEO\Plugin\Pro\ImportExport;
// phpcs:disable WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound
class YoastSeo extends CommonYoastSeo\YoastSeo {
/**
* Class constructor.
*
* @since 4.0.0
*
* @param ImportExport\ImportExport $importer the ImportExport class.
*/
public function __construct( $importer ) {
parent::__construct( $importer );
$this->termMeta = new TermMeta();
}
/**
* Starts the import.
*
* @since 4.0.0
*
* @param array $options What the user wants to import.
* @return void
*/
public function doImport( $options = [] ) {
parent::doImport( $options );
if ( empty( $options ) ) {
$this->termMeta->scheduleImport();
return;
}
foreach ( $options as $optionName ) {
switch ( $optionName ) {
case 'termMeta':
$this->termMeta->scheduleImport();
break;
default:
break;
}
}
}
/**
* Imports the settings.
*
* @since 4.0.0
*
* @return void
*/
protected function importSettings() {
parent::importSettings();
new GeneralSettings();
new SearchAppearance();
new SocialMeta();
new VideoSitemap();
new NewsSitemap();
}
}