/home/lnzliplg/www/wp-content/plugins/aioseo-local-business/app/Import/Plugins/YoastSeo.php
<?php
namespace AIOSEO\Plugin\Addon\LocalBusiness\Import\Plugins;
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
use AIOSEO\Plugin\Common\Models;
use AIOSEO\Plugin\Addon\LocalBusiness\Import;
/**
* The YoastSEO importer class.
*
* @since 4.0.0
* @version 1.3.0 Moved from Pro.
*/
class YoastSeo extends Import\Importer {
/**
* List of options.
*
* @since 4.2.7
* @version 1.3.0 Moved from Pro.
*
* @var array
*/
private $options = [];
/**
* A list of plugins to look for to import.
*
* @since 1.3.0
*
* @var array
*/
public $plugins = [
[
'name' => 'Yoast SEO: Local',
'version' => '14.9',
'basename' => 'wpseo-local/local-seo.php',
'slug' => 'yoast-local-seo'
]
];
/**
* Import.
*
* @since 4.0.0
* @version 1.3.0 Moved from Pro.
*
* @return void
*/
public function doImport() {
$this->options = get_option( 'wpseo_local' );
if ( empty( $this->options ) ) {
return;
}
// Yoast SEO doesn't have a setting for this, so we'll use the Organization Name.
aioseo()->options->localBusiness->locations->business->name = aioseo()->options->searchAppearance->global->schema->organizationName;
if ( ! empty( $this->options['business_type'] ) ) {
$this->importLocalBusinessType( $this->options['business_type'] );
}
if ( ! empty( $this->options['location_country'] ) ) {
$this->importLocalBusinessCountry( $this->options['location_country'] );
}
if ( ! empty( $this->options['location_phone'] ) ) {
$this->importLocalBusinessPhoneNumber( $this->options['location_phone'] );
}
if ( ! empty( $this->options['location_fax'] ) ) {
$this->importLocalBusinessFaxNumber( $this->options['location_fax'] );
}
if ( ! empty( $this->options['location_currencies_accepted'] ) ) {
$currencies = array_filter( explode( ',', $this->options['location_currencies_accepted'] ) );
$this->importCurrencies( $currencies );
}
$settings = [
'location_email' => [
'type' => 'string',
'newOption' => [ 'localBusiness', 'locations', 'business', 'contact', 'email' ]
],
'location_address' => [
'type' => 'string',
'newOption' => [ 'localBusiness', 'locations', 'business', 'address', 'streetLine1' ]
],
'location_address_2' => [
'type' => 'string',
'newOption' => [ 'localBusiness', 'locations', 'business', 'address', 'streetLine2' ]
],
'location_city' => [
'type' => 'string',
'newOption' => [ 'localBusiness', 'locations', 'business', 'address', 'city' ]
],
'location_state' => [
'type' => 'string',
'newOption' => [ 'localBusiness', 'locations', 'business', 'address', 'state' ]
],
'location_zipcode' => [
'type' => 'string',
'newOption' => [ 'localBusiness', 'locations', 'business', 'address', 'zipCode' ]
],
'location_vat_id' => [
'type' => 'string',
'newOption' => [ 'localBusiness', 'locations', 'business', 'ids', 'vat' ]
],
'location_tax_id' => [
'type' => 'string',
'newOption' => [ 'localBusiness', 'locations', 'business', 'ids', 'tax' ]
],
'location_coc_id' => [
'type' => 'string',
'newOption' => [ 'localBusiness', 'locations', 'business', 'ids', 'chamberOfCommerce' ]
],
'location_price_range' => [
'type' => 'string',
'newOption' => [ 'localBusiness', 'locations', 'business', 'payment', 'priceRange' ]
],
'location_payment_accepted' => [
'type' => 'string',
'newOption' => [ 'localBusiness', 'locations', 'business', 'payment', 'methods' ]
],
'location_area_served' => [
'type' => 'string',
'newOption' => [ 'localBusiness', 'locations', 'business', 'areaServed' ]
],
];
$this->mapOldToNew( $settings, $this->options );
$this->importAddressFormat();
$this->importOpeningHourSettings();
$this->importMapSettings();
$this->importMultipleLocations();
}
/**
* Imports the Local Business opening hour settings.
*
* @since 4.0.0
* @version 1.3.0 Moved from Pro.
*
* @return void
*/
private function importOpeningHourSettings() {
if ( ! empty( $this->options['hide_opening_hours'] ) ) {
aioseo()->options->localBusiness->openingHours->show = 'off' === $this->options['hide_opening_hours'];
}
if ( ! empty( $this->options['open_247'] ) ) {
aioseo()->options->localBusiness->openingHours->alwaysOpen = 'on' === $this->options['open_247'];
}
if ( ! empty( $this->options['closed_label'] ) ) {
aioseo()->options->localBusiness->openingHours->labels->closed = $this->options['closed_label'];
}
if ( ! empty( $this->options['open_24h_label'] ) ) {
aioseo()->options->localBusiness->openingHours->labels->alwaysOpen = $this->options['open_24h_label'];
}
if ( ! empty( $this->options['opening_hours_24h'] ) ) {
aioseo()->options->localBusiness->openingHours->use24hFormat = 'on' === $this->options['opening_hours_24h'];
}
$days = $this->formatOpeningHoursDays( $this->options );
foreach ( $days as $day => $dayOptions ) {
foreach ( $dayOptions as $option => $value ) {
aioseo()->options->localBusiness->openingHours->days->$day->$option = $value;
}
}
}
/**
* Formats the opening hours.
*
* @since 1.3.0
*
* @param array $options The options array from Yoast.
* @return array The formatted opening hours.
*/
private function formatOpeningHoursDays( $options ) {
$openingHoursDays = [];
$days = aioseo()->options->localBusiness->openingHours->days->all();
foreach ( $days as $name => $values ) {
if ( ! empty( $options[ "opening_hours_{$name}_24h" ] ) ) {
$openingHoursDays[ $name ]['open24h'] = 'on' === $options[ "opening_hours_{$name}_24h" ];
}
if ( ! empty( $options[ "opening_hours_{$name}_from" ] ) ) {
if ( 'closed' === $options[ "opening_hours_{$name}_from" ] ) {
$openingHoursDays[ $name ]['closed'] = true;
continue;
}
$openingHoursDays[ $name ]['openTime'] = $options[ "opening_hours_{$name}_from" ];
}
if ( ! empty( $options[ "opening_hours_{$name}_to" ] ) ) {
if ( 'closed' === $options[ "opening_hours_{$name}_to" ] ) {
$openingHoursDays[ $name ]['closed'] = true;
continue;
}
$openingHoursDays[ $name ]['closeTime'] = $options[ "opening_hours_{$name}_to" ];
}
}
return $openingHoursDays;
}
/**
* Imports the Address format.
*
* @since 1.3.0
*
* @return void
*/
private function importAddressFormat() {
if ( empty( $this->options['address_format'] ) ) {
return;
}
$formatMap = [
'address-state-postal' => '#streetLineOne #streetLineTwo #city, #state #zipCode',
'address-state-postal-comma' => '#streetLineOne #streetLineTwo #city, #state, #zipCode',
'address-postal-city-state' => '#streetLineOne #streetLineTwo #zipCode #city, #state',
'address-postal' => '#streetLineOne #streetLineTwo #city #zipCode',
'address-postal-comma' => '#streetLineOne #streetLineTwo #city, #zipCode',
'address-city' => '#streetLineOne #streetLineTwo #city',
'postal-address' => '#zipCode #state #city #streetLineOne #streetLineTwo'
];
if ( empty( $formatMap[ $this->options['address_format'] ] ) ) {
return;
}
aioseo()->options->localBusiness->locations->business->address->addressFormat = $formatMap[ $this->options['address_format'] ];
}
/**
* Imports multiple locations.
*
* @since 1.3.0
*
* @return void
*/
private function importMultipleLocations() {
aioseo()->options->localBusiness->locations->general->multiple = ! empty( $this->options['use_multiple_locations'] ) && 'on' === $this->options['use_multiple_locations'];
if ( ! empty( $this->options['locations_label_singular'] ) ) {
aioseo()->options->localBusiness->locations->general->singleLabel = $this->options['locations_label_singular'];
}
if ( ! empty( $this->options['locations_label_plural'] ) ) {
aioseo()->options->localBusiness->locations->general->pluralLabel = $this->options['locations_label_plural'];
}
if ( ! empty( $this->options['locations_slug'] ) ) {
aioseo()->options->localBusiness->locations->general->useCustomSlug = true;
aioseo()->options->localBusiness->locations->general->customSlug = $this->options['locations_slug'];
}
if ( ! empty( $this->options['locations_taxo_slug'] ) ) {
aioseo()->options->localBusiness->locations->general->useCustomCategorySlug = true;
aioseo()->options->localBusiness->locations->general->customCategorySlug = $this->options['locations_taxo_slug'];
}
if ( ! empty( $this->options['local_enhanced_search'] ) && 'on' === $this->options['local_enhanced_search'] ) {
aioseo()->options->localBusiness->locations->general->enhancedSearch = true;
}
if ( aioseo()->options->localBusiness->locations->general->multiple ) {
// Query wpseo-local categories.
$importedCategories = $this->importTaxonomyTerms( 'wpseo_locations_category' );
// Query wpseo-local locations.
$locations = get_posts( [
'post_type' => 'wpseo_locations',
'posts_per_page' => -1,
'post_status' => 'any'
] );
foreach ( $locations as $location ) {
$this->importLocation( $location, $importedCategories );
}
}
}
/**
* Imports a Location.
*
* @since 1.3.0
*
* @param \WP_Post $yoastLocation The location to import.
* @param array $importedCategories The imported categories.
* @return void
*/
private function importLocation( $yoastLocation, $importedCategories ) {
// Get the Yoast meta.
$yoastMetaRaw = get_post_meta( $yoastLocation->ID );
// Filter only needed data.
$yoastMetaRaw = array_filter( $yoastMetaRaw, function ( $key ) {
return 0 === strpos( $key, '_wpseo_' );
}, ARRAY_FILTER_USE_KEY );
// Flatten the Yoast meta.
$yoastMetaRaw = array_map( function ( $n ) {
return $n[0];
}, $yoastMetaRaw );
// Normalize meta.
$yoastMeta = [];
foreach ( $yoastMetaRaw as $key => $value ) {
$yoastMeta[ preg_replace( '%^_wpseo_%', '', $key ) ] = $value;
}
// Location and business data.
$locationData = [
'business_name' => [ 'locations', 'business', 'name' ],
'business_type' => [ 'locations', 'business', 'businessType' ],
'business_location_logo' => [ 'locations', 'business', 'image' ],
'business_address' => [ 'locations', 'business', 'address', 'streetLine1' ],
'business_address_2' => [ 'locations', 'business', 'address', 'streetLine2' ],
'business_city' => [ 'locations', 'business', 'address', 'city' ],
'business_state' => [ 'locations', 'business', 'address', 'state' ],
'business_zipcode' => [ 'locations', 'business', 'address', 'zipCode' ],
'business_country' => [ 'locations', 'business', 'address', 'country' ],
'business_phone' => [ 'locations', 'business', 'contact', 'phone' ],
'business_fax' => [ 'locations', 'business', 'contact', 'fax' ],
'business_email' => [ 'locations', 'business', 'contact', 'email' ],
'business_vat_id' => [ 'locations', 'business', 'ids', 'vat' ],
'business_tax_id' => [ 'locations', 'business', 'ids', 'tax' ],
'business_coc_id' => [ 'locations', 'business', 'ids', 'chamberOfCommerce' ],
'business_price_range' => [ 'locations', 'business', 'payment', 'priceRange' ],
'business_currencies_accepted' => [ 'locations', 'business', 'payment', 'currenciesAccepted' ],
'business_payment_accepted' => [ 'locations', 'business', 'payment', 'methods' ],
'business_area_served' => [ 'locations', 'business', 'areaServed' ]
];
// Create the data array.
$dataArray = [];
foreach ( $locationData as $metaKey => $locationKeys ) {
$metaValue = ! empty( $yoastMeta[ $metaKey ] ) ? $yoastMeta[ $metaKey ] : null;
if ( ! empty( $metaValue ) ) {
// Treat currencies.
if ( 'business_currencies_accepted' === $metaKey ) {
$metaValue = array_filter( explode( ',', $metaValue ) );
$metaValue = $this->formatCurrencies( $metaValue );
if ( ! empty( $metaValue['supported'] ) ) {
$metaValue = wp_json_encode( $metaValue['supported'] );
}
}
$metaValue = aioseo()->helpers->createMultidimensionalArray( $locationKeys, $metaValue );
$dataArray = array_merge_recursive( $dataArray, $metaValue );
}
}
// Opening hours.
$dataArray['openingHours'] = [
'useDefaults' => false,
'show' => true,
'use24hFormat' => 'on' === $yoastMeta['format_24h'],
'alwaysOpen' => 'on' === $yoastMeta['open_247'],
'days' => $this->formatOpeningHoursDays( $yoastMeta )
];
// Maps.
if ( ! empty( $yoastMeta['coordinates_lat'] ) && ! empty( $yoastMeta['coordinates_long'] ) ) {
$dataArray['maps'] = [
'mapOptions' => [
'center' => [
'lat' => $yoastMeta['coordinates_lat'],
'lng' => $yoastMeta['coordinates_long']
]
],
'customMarker' => ! empty( $yoastMeta['business_location_custom_marker'] ) ? $yoastMeta['business_location_custom_marker'] : ''
];
}
// Check if the location already exists.
$wpPost = aioseoLocalBusiness()->locations->getLocationByName( $yoastLocation->post_name );
// Create the location if it doesn't exist.
if ( empty( $wpPost ) ) {
$wpPost = clone $yoastLocation;
$wpPost->ID = null;
$wpPost->post_type = aioseoLocalBusiness()->postType->getName();
$wpPost = wp_insert_post( $wpPost );
$wpPost = get_post( $wpPost );
}
// Set the location categories.
$categories = wp_get_post_terms( $yoastLocation->ID, 'wpseo_locations_category' );
$mappedCategories = [];
foreach ( $categories as $category ) {
if ( ! is_object( $category ) ) {
$category = (object) $category;
}
if ( empty( $category->term_id ) ) {
continue;
}
$importedCategory = ! empty( $importedCategories[ $category->term_id ] ) ? $importedCategories[ $category->term_id ] : null;
if ( $importedCategory ) {
$mappedCategories[] = $importedCategory->term_id;
}
}
wp_set_post_terms( $wpPost->ID, $mappedCategories, aioseoLocalBusiness()->taxonomy->getName() );
// Set AIOSEO's location data.
$aioseoLocation = Models\Post::getPost( $wpPost->ID );
$aioseoLocation->local_seo = $dataArray;
$aioseoLocation->save();
}
/**
* Imports the Local Business map settings.
*
* @since 1.3.0
*
* @return void
*/
private function importMapSettings() {
if ( ! empty( $this->options['googlemaps_api_key'] ) ) {
aioseo()->options->localBusiness->maps->apiKey = $this->options['googlemaps_api_key'];
aioseo()->options->localBusiness->maps->apiKeyValid = true;
}
if ( ! empty( $this->options['map_view_style'] ) ) {
aioseo()->options->localBusiness->maps->mapOptions->mapTypeId = strtolower( $this->options['map_view_style'] );
}
if ( ! empty( $this->options['location_coords_lat'] ) && ! empty( $this->options['location_coords_long'] ) ) {
aioseo()->options->localBusiness->maps->mapOptions->center->lat = $this->options['location_coords_lat'];
aioseo()->options->localBusiness->maps->mapOptions->center->lng = $this->options['location_coords_long'];
}
if ( ! empty( $this->options['local_custom_marker'] ) ) {
aioseo()->options->localBusiness->maps->customMarker = wp_get_attachment_image_url( $this->options['local_custom_marker'], 'full' );
}
}
}