Initial commit: Atomaste website
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
namespace AIOSEO\Plugin\Common\Options;
|
||||
|
||||
// Exit if accessed directly.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class that holds all the cache for the AIOSEO options.
|
||||
*
|
||||
* @since 4.1.4
|
||||
*/
|
||||
class Cache {
|
||||
/**
|
||||
* The DB options cache.
|
||||
*
|
||||
* @since 4.1.4
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $db = [];
|
||||
|
||||
/**
|
||||
* The options cache.
|
||||
*
|
||||
* @since 4.1.4
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $options = [];
|
||||
|
||||
/**
|
||||
* Sets the cache for the DB option.
|
||||
*
|
||||
* @since 4.1.4
|
||||
*
|
||||
* @param string $name The cache name.
|
||||
* @param array $value The value.
|
||||
* @return void
|
||||
*/
|
||||
public function setDb( $name, $value ) {
|
||||
self::$db[ $name ] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cache for the DB option.
|
||||
*
|
||||
* @since 4.1.4
|
||||
*
|
||||
* @param string $name The cache name.
|
||||
* @return array The data from the cache.
|
||||
*/
|
||||
public function getDb( $name ) {
|
||||
return ! empty( self::$db[ $name ] ) ? self::$db[ $name ] : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cache for the options.
|
||||
*
|
||||
* @since 4.1.4
|
||||
*
|
||||
* @param string $name The cache name.
|
||||
* @param array $value The value.
|
||||
* @return void
|
||||
*/
|
||||
public function setOptions( $name, $value ) {
|
||||
self::$options[ $name ] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cache for the options.
|
||||
*
|
||||
* @since 4.1.4
|
||||
*
|
||||
* @param string $name The cache name.
|
||||
* @return array The data from the cache.
|
||||
*/
|
||||
public function getOptions( $name ) {
|
||||
return ! empty( self::$options[ $name ] ) ? self::$options[ $name ] : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the DB cache.
|
||||
*
|
||||
* @since 4.1.4
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function resetDb() {
|
||||
self::$db = [];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,311 @@
|
||||
<?php
|
||||
namespace AIOSEO\Plugin\Common\Options;
|
||||
|
||||
// Exit if accessed directly.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the dynamic backup.
|
||||
*
|
||||
* @since 4.1.3
|
||||
*/
|
||||
class DynamicBackup {
|
||||
/**
|
||||
* A the name of the option to save dynamic backups to.
|
||||
*
|
||||
* @since 4.1.3
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $optionsName = 'aioseo_dynamic_settings_backup';
|
||||
|
||||
/**
|
||||
* The dynamic backup.
|
||||
*
|
||||
* @since 4.1.3
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $backup = [];
|
||||
|
||||
/**
|
||||
* Whether the backup should be updated.
|
||||
*
|
||||
* @since 4.1.3
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $shouldBackup = false;
|
||||
|
||||
/**
|
||||
* The options from the DB.
|
||||
*
|
||||
* @since 4.1.3
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $options = [];
|
||||
|
||||
/**
|
||||
* The public post types.
|
||||
*
|
||||
* @since 4.1.5
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $postTypes = [];
|
||||
|
||||
/**
|
||||
* The public taxonomies.
|
||||
*
|
||||
* @since 4.1.5
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $taxonomies = [];
|
||||
|
||||
/**
|
||||
* The public archives.
|
||||
*
|
||||
* @since 4.1.5
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $archives = [];
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @since 4.1.3
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'wp_loaded', [ $this, 'init' ], 5000 );
|
||||
add_action( 'shutdown', [ $this, 'updateBackup' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the backup after restoring options.
|
||||
*
|
||||
* @since 4.1.3
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function updateBackup() {
|
||||
if ( $this->shouldBackup ) {
|
||||
$this->shouldBackup = false;
|
||||
$backup = aioseo()->dynamicOptions->convertOptionsToValues( $this->backup, 'value' );
|
||||
update_option( $this->optionsName, wp_json_encode( $backup ), 'no' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether data from the backup has to be restored.
|
||||
*
|
||||
* @since 4.1.3
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init() {
|
||||
$this->postTypes = wp_list_pluck( aioseo()->helpers->getPublicPostTypes( false, false, true ), 'name' );
|
||||
$this->taxonomies = wp_list_pluck( aioseo()->helpers->getPublicTaxonomies( false, true ), 'name' );
|
||||
$this->archives = wp_list_pluck( aioseo()->helpers->getPublicPostTypes( false, true, true ), 'name' );
|
||||
|
||||
$backup = json_decode( get_option( $this->optionsName ), true );
|
||||
if ( empty( $backup ) ) {
|
||||
update_option( $this->optionsName, '{}', 'no' );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->backup = $backup;
|
||||
$this->options = aioseo()->dynamicOptions->getDefaults();
|
||||
|
||||
$this->restorePostTypes();
|
||||
$this->restoreTaxonomies();
|
||||
$this->restoreArchives();
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores the dynamic Post Types options.
|
||||
*
|
||||
* @since 4.1.3
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function restorePostTypes() {
|
||||
foreach ( $this->postTypes as $postType ) {
|
||||
// Restore the post types for Search Appearance.
|
||||
if ( ! empty( $this->backup['postTypes'][ $postType ]['searchAppearance'] ) ) {
|
||||
$this->restoreOptions( $this->backup['postTypes'][ $postType ]['searchAppearance'], [ 'searchAppearance', 'postTypes', $postType ] );
|
||||
unset( $this->backup['postTypes'][ $postType ]['searchAppearance'] );
|
||||
$this->shouldBackup = true;
|
||||
}
|
||||
|
||||
// Restore the post types for Social Networks.
|
||||
if ( ! empty( $this->backup['postTypes'][ $postType ]['social']['facebook'] ) ) {
|
||||
$this->restoreOptions( $this->backup['postTypes'][ $postType ]['social']['facebook'], [ 'social', 'facebook', 'general', 'postTypes', $postType ] );
|
||||
unset( $this->backup['postTypes'][ $postType ]['social']['facebook'] );
|
||||
$this->shouldBackup = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores the dynamic Taxonomies options.
|
||||
*
|
||||
* @since 4.1.3
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function restoreTaxonomies() {
|
||||
foreach ( $this->taxonomies as $taxonomy ) {
|
||||
// Restore the taxonomies for Search Appearance.
|
||||
if ( ! empty( $this->backup['taxonomies'][ $taxonomy ]['searchAppearance'] ) ) {
|
||||
$this->restoreOptions( $this->backup['taxonomies'][ $taxonomy ]['searchAppearance'], [ 'searchAppearance', 'taxonomies', $taxonomy ] );
|
||||
unset( $this->backup['taxonomies'][ $taxonomy ]['searchAppearance'] );
|
||||
$this->shouldBackup = true;
|
||||
}
|
||||
|
||||
// Restore the taxonomies for Social Networks.
|
||||
if ( ! empty( $this->backup['taxonomies'][ $taxonomy ]['social']['facebook'] ) ) {
|
||||
$this->restoreOptions( $this->backup['taxonomies'][ $taxonomy ]['social']['facebook'], [ 'social', 'facebook', 'general', 'taxonomies', $taxonomy ] );
|
||||
unset( $this->backup['taxonomies'][ $taxonomy ]['social']['facebook'] );
|
||||
$this->shouldBackup = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores the dynamic Archives options.
|
||||
*
|
||||
* @since 4.1.3
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function restoreArchives() {
|
||||
foreach ( $this->archives as $postType ) {
|
||||
// Restore the archives for Search Appearance.
|
||||
if ( ! empty( $this->backup['archives'][ $postType ]['searchAppearance'] ) ) {
|
||||
$this->restoreOptions( $this->backup['archives'][ $postType ]['searchAppearance'], [ 'searchAppearance', 'archives', $postType ] );
|
||||
unset( $this->backup['archives'][ $postType ]['searchAppearance'] );
|
||||
$this->shouldBackup = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores the backuped options.
|
||||
*
|
||||
* @since 4.1.3
|
||||
*
|
||||
* @param array $backupOptions The options to be restored.
|
||||
* @param array $groups The group that the option should be restored.
|
||||
* @return void
|
||||
*/
|
||||
protected function restoreOptions( $backupOptions, $groups ) {
|
||||
$groupPath = $this->options;
|
||||
foreach ( $groups as $group ) {
|
||||
if ( ! isset( $groupPath[ $group ] ) ) {
|
||||
return false;
|
||||
}
|
||||
$groupPath = $groupPath[ $group ];
|
||||
}
|
||||
|
||||
$options = aioseo()->dynamicOptions->noConflict();
|
||||
foreach ( $backupOptions as $setting => $value ) {
|
||||
// Check if the option exists by checking if the type is defined.
|
||||
$type = ! empty( $groupPath[ $setting ]['type'] ) ? $groupPath[ $setting ]['type'] : '';
|
||||
if ( ! $type ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ( $groups as $group ) {
|
||||
$options = $options->$group;
|
||||
}
|
||||
|
||||
$options->$setting = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maybe backup the options if it has disappeared.
|
||||
*
|
||||
* @since 4.1.3
|
||||
*
|
||||
* @param array $newOptions An array of options to check.
|
||||
* @return void
|
||||
*/
|
||||
public function maybeBackup( $newOptions ) {
|
||||
$this->maybeBackupPostType( $newOptions );
|
||||
$this->maybeBackupTaxonomy( $newOptions );
|
||||
$this->maybeBackupArchives( $newOptions );
|
||||
}
|
||||
|
||||
/**
|
||||
* Maybe backup the Post Types.
|
||||
*
|
||||
* @since 4.1.3
|
||||
*
|
||||
* @param array $newOptions An array of options to check.
|
||||
* @return void
|
||||
*/
|
||||
protected function maybeBackupPostType( $newOptions ) {
|
||||
// Maybe backup the post types for Search Appearance.
|
||||
foreach ( $newOptions['searchAppearance']['postTypes'] as $dynamicPostTypeName => $dynamicPostTypeSettings ) {
|
||||
$found = in_array( $dynamicPostTypeName, $this->postTypes, true );
|
||||
if ( ! $found ) {
|
||||
$this->backup['postTypes'][ $dynamicPostTypeName ]['searchAppearance'] = $dynamicPostTypeSettings;
|
||||
$this->shouldBackup = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Maybe backup the post types for Social Networks.
|
||||
foreach ( $newOptions['social']['facebook']['general']['postTypes'] as $dynamicPostTypeName => $dynamicPostTypeSettings ) {
|
||||
$found = in_array( $dynamicPostTypeName, $this->postTypes, true );
|
||||
if ( ! $found ) {
|
||||
$this->backup['postTypes'][ $dynamicPostTypeName ]['social']['facebook'] = $dynamicPostTypeSettings;
|
||||
$this->shouldBackup = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maybe backup the Taxonomies.
|
||||
*
|
||||
* @since 4.1.3
|
||||
*
|
||||
* @param array $newOptions An array of options to check.
|
||||
* @return void
|
||||
*/
|
||||
protected function maybeBackupTaxonomy( $newOptions ) {
|
||||
// Maybe backup the taxonomies for Search Appearance.
|
||||
foreach ( $newOptions['searchAppearance']['taxonomies'] as $dynamicTaxonomyName => $dynamicTaxonomySettings ) {
|
||||
$found = in_array( $dynamicTaxonomyName, $this->taxonomies, true );
|
||||
if ( ! $found ) {
|
||||
$this->backup['taxonomies'][ $dynamicTaxonomyName ]['searchAppearance'] = $dynamicTaxonomySettings;
|
||||
$this->shouldBackup = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maybe backup the Archives.
|
||||
*
|
||||
* @since 4.1.3
|
||||
*
|
||||
* @param array $newOptions An array of options to check.
|
||||
* @return void
|
||||
*/
|
||||
protected function maybeBackupArchives( $newOptions ) {
|
||||
// Maybe backup the archives for Search Appearance.
|
||||
foreach ( $newOptions['searchAppearance']['archives'] as $archiveName => $archiveSettings ) {
|
||||
$found = in_array( $archiveName, $this->archives, true );
|
||||
if ( ! $found ) {
|
||||
$this->backup['archives'][ $archiveName ]['searchAppearance'] = $archiveSettings;
|
||||
$this->shouldBackup = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,412 @@
|
||||
<?php
|
||||
namespace AIOSEO\Plugin\Common\Options;
|
||||
|
||||
// Exit if accessed directly.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
use AIOSEO\Plugin\Common\Traits;
|
||||
|
||||
/**
|
||||
* Handles the dynamic options.
|
||||
*
|
||||
* @since 4.1.4
|
||||
*/
|
||||
class DynamicOptions {
|
||||
use Traits\Options;
|
||||
|
||||
/**
|
||||
* The default options.
|
||||
*
|
||||
* @since 4.1.4
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $defaults = [
|
||||
// phpcs:disable WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound
|
||||
'sitemap' => [
|
||||
'priority' => [
|
||||
'postTypes' => [],
|
||||
'taxonomies' => []
|
||||
]
|
||||
],
|
||||
'social' => [
|
||||
'facebook' => [
|
||||
'general' => [
|
||||
'postTypes' => []
|
||||
]
|
||||
]
|
||||
],
|
||||
'searchAppearance' => [
|
||||
'postTypes' => [],
|
||||
'taxonomies' => [],
|
||||
'archives' => []
|
||||
]
|
||||
// phpcs:enable WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound
|
||||
];
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @since 4.1.4
|
||||
*
|
||||
* @param string $optionsName The options name.
|
||||
*/
|
||||
public function __construct( $optionsName = 'aioseo_options_dynamic' ) {
|
||||
$this->optionsName = $optionsName;
|
||||
|
||||
// Load defaults in case this is a complete fresh install.
|
||||
$this->init();
|
||||
|
||||
add_action( 'shutdown', [ $this, 'save' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the options.
|
||||
*
|
||||
* @since 4.1.4
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function init() {
|
||||
$this->addDynamicDefaults();
|
||||
$this->setDbOptions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the DB options.
|
||||
*
|
||||
* @since 4.1.4
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setDbOptions() {
|
||||
$dbOptions = $this->getDbOptions( $this->optionsName );
|
||||
|
||||
// Refactor options.
|
||||
$this->defaultsMerged = array_replace_recursive( $this->defaults, $this->defaultsMerged );
|
||||
|
||||
$dbOptions = array_replace_recursive(
|
||||
$this->defaultsMerged,
|
||||
$this->addValueToValuesArray( $this->defaultsMerged, $dbOptions )
|
||||
);
|
||||
|
||||
// Remove any post types/taxonomies that are stored in the DB but that aren't active currently.
|
||||
// We only have to do this for the dynamic options.
|
||||
$dbOptions = $this->filterOptions( $this->defaultsMerged, $dbOptions );
|
||||
|
||||
aioseo()->core->optionsCache->setOptions( $this->optionsName, $dbOptions );
|
||||
|
||||
// Get the localized options.
|
||||
$dbOptionsLocalized = get_option( $this->optionsName . '_localized' );
|
||||
if ( empty( $dbOptionsLocalized ) ) {
|
||||
$dbOptionsLocalized = [];
|
||||
}
|
||||
$this->localized = $dbOptionsLocalized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes, then saves the options to the database.
|
||||
*
|
||||
* @since 4.1.4
|
||||
*
|
||||
* @param array $options An array of options to sanitize, then save.
|
||||
* @return void
|
||||
*/
|
||||
public function sanitizeAndSave( $options ) {
|
||||
if ( ! is_array( $options ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$cachedOptions = aioseo()->core->optionsCache->getOptions( $this->optionsName );
|
||||
|
||||
aioseo()->dynamicBackup->maybeBackup( $cachedOptions );
|
||||
|
||||
// First, recursively replace the new options into the cached state.
|
||||
// It's important we use the helper method since we want to replace populated arrays with empty ones if needed (when a setting was cleared out).
|
||||
$dbOptions = aioseo()->helpers->arrayReplaceRecursive(
|
||||
$cachedOptions,
|
||||
$this->addValueToValuesArray( $cachedOptions, $options, [], true )
|
||||
);
|
||||
|
||||
// Now, we must also intersect both arrays to delete any individual keys that were unset.
|
||||
// We must do this because, while arrayReplaceRecursive will update the values for keys or empty them out,
|
||||
// it will keys that aren't present in the replacement array unaffected in the target array.
|
||||
$dbOptions = aioseo()->helpers->arrayIntersectRecursive(
|
||||
$dbOptions,
|
||||
$this->addValueToValuesArray( $cachedOptions, $options, [], true ),
|
||||
'value'
|
||||
);
|
||||
|
||||
// Update the cache state.
|
||||
aioseo()->core->optionsCache->setOptions( $this->optionsName, $dbOptions );
|
||||
|
||||
// Update localized options.
|
||||
update_option( $this->optionsName . '_localized', $this->localized );
|
||||
|
||||
// Finally, save the new values to the DB.
|
||||
$this->save( true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds some defaults that are dynamically generated.
|
||||
*
|
||||
* @since 4.1.4
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addDynamicDefaults() {
|
||||
$this->addDynamicPostTypeDefaults();
|
||||
$this->addDynamicTaxonomyDefaults();
|
||||
$this->addDynamicArchiveDefaults();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the dynamic defaults for the public post types.
|
||||
*
|
||||
* @since 4.1.4
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function addDynamicPostTypeDefaults() {
|
||||
$postTypes = aioseo()->helpers->getPublicPostTypes( false, false, false, [ 'include' => [ 'buddypress' ] ] );
|
||||
foreach ( $postTypes as $postType ) {
|
||||
if ( 'type' === $postType['name'] ) {
|
||||
$postType['name'] = '_aioseo_type';
|
||||
}
|
||||
|
||||
$defaultTitle = '#post_title #separator_sa #site_title';
|
||||
if ( ! empty( $postType['defaultTitle'] ) ) {
|
||||
$defaultTitle = $postType['defaultTitle'];
|
||||
}
|
||||
$defaultDescription = ! empty( $postType['supports']['excerpt'] ) ? '#post_excerpt' : '#post_content';
|
||||
if ( ! empty( $postType['defaultDescription'] ) ) {
|
||||
$defaultDescription = $postType['defaultDescription'];
|
||||
}
|
||||
$defaultSchemaType = 'WebPage';
|
||||
$defaultWebPageType = 'WebPage';
|
||||
$defaultArticleType = 'BlogPosting';
|
||||
|
||||
switch ( $postType['name'] ) {
|
||||
case 'post':
|
||||
$defaultSchemaType = 'Article';
|
||||
break;
|
||||
case 'attachment':
|
||||
$defaultDescription = '#attachment_caption';
|
||||
$defaultSchemaType = 'ItemPage';
|
||||
$defaultWebPageType = 'ItemPage';
|
||||
break;
|
||||
case 'product':
|
||||
$defaultSchemaType = 'WebPage';
|
||||
$defaultWebPageType = 'ItemPage';
|
||||
break;
|
||||
case 'news':
|
||||
$defaultArticleType = 'NewsArticle';
|
||||
break;
|
||||
case 'web-story':
|
||||
$defaultWebPageType = 'WebPage';
|
||||
$defaultSchemaType = 'WebPage';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
$defaultOptions = array_replace_recursive(
|
||||
$this->getDefaultSearchAppearanceOptions(),
|
||||
[
|
||||
'title' => [
|
||||
'type' => 'string',
|
||||
'localized' => true,
|
||||
'default' => $defaultTitle
|
||||
],
|
||||
'metaDescription' => [
|
||||
'type' => 'string',
|
||||
'localized' => true,
|
||||
'default' => $defaultDescription
|
||||
],
|
||||
'schemaType' => [
|
||||
'type' => 'string',
|
||||
'default' => $defaultSchemaType
|
||||
],
|
||||
'webPageType' => [
|
||||
'type' => 'string',
|
||||
'default' => $defaultWebPageType
|
||||
],
|
||||
'articleType' => [
|
||||
'type' => 'string',
|
||||
'default' => $defaultArticleType
|
||||
],
|
||||
'customFields' => [ 'type' => 'html' ],
|
||||
'advanced' => [
|
||||
'bulkEditing' => [
|
||||
'type' => 'string',
|
||||
'default' => 'enabled'
|
||||
]
|
||||
]
|
||||
]
|
||||
);
|
||||
|
||||
if ( 'attachment' === $postType['name'] ) {
|
||||
$defaultOptions['redirectAttachmentUrls'] = [
|
||||
'type' => 'string',
|
||||
'default' => 'attachment'
|
||||
];
|
||||
}
|
||||
|
||||
$this->defaults['searchAppearance']['postTypes'][ $postType['name'] ] = $defaultOptions;
|
||||
$this->setDynamicSocialOptions( 'postTypes', $postType['name'] );
|
||||
$this->setDynamicSitemapOptions( 'postTypes', $postType['name'] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the dynamic defaults for the public taxonomies.
|
||||
*
|
||||
* @since 4.1.4
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function addDynamicTaxonomyDefaults() {
|
||||
$taxonomies = aioseo()->helpers->getPublicTaxonomies();
|
||||
foreach ( $taxonomies as $taxonomy ) {
|
||||
if ( 'type' === $taxonomy['name'] ) {
|
||||
$taxonomy['name'] = '_aioseo_type';
|
||||
}
|
||||
|
||||
$defaultOptions = array_replace_recursive(
|
||||
$this->getDefaultSearchAppearanceOptions(),
|
||||
[
|
||||
'title' => [
|
||||
'type' => 'string',
|
||||
'localized' => true,
|
||||
'default' => '#taxonomy_title #separator_sa #site_title'
|
||||
],
|
||||
'metaDescription' => [
|
||||
'type' => 'string',
|
||||
'localized' => true,
|
||||
'default' => '#taxonomy_description'
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->setDynamicSitemapOptions( 'taxonomies', $taxonomy['name'] );
|
||||
|
||||
$this->defaults['searchAppearance']['taxonomies'][ $taxonomy['name'] ] = $defaultOptions;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the dynamic defaults for the archive pages.
|
||||
*
|
||||
* @since 4.1.4
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function addDynamicArchiveDefaults() {
|
||||
$postTypes = aioseo()->helpers->getPublicPostTypes( false, true, false, [ 'include' => [ 'buddypress' ] ] );
|
||||
foreach ( $postTypes as $postType ) {
|
||||
if ( 'type' === $postType['name'] ) {
|
||||
$postType['name'] = '_aioseo_type';
|
||||
}
|
||||
|
||||
$defaultOptions = array_replace_recursive(
|
||||
$this->getDefaultSearchAppearanceOptions(),
|
||||
[
|
||||
'title' => [
|
||||
'type' => 'string',
|
||||
'localized' => true,
|
||||
'default' => '#archive_title #separator_sa #site_title'
|
||||
],
|
||||
'metaDescription' => [
|
||||
'type' => 'string',
|
||||
'localized' => true,
|
||||
'default' => ''
|
||||
],
|
||||
'customFields' => [ 'type' => 'html' ],
|
||||
'advanced' => [
|
||||
'keywords' => [
|
||||
'type' => 'string',
|
||||
'localized' => true
|
||||
]
|
||||
]
|
||||
]
|
||||
);
|
||||
|
||||
$this->defaults['searchAppearance']['archives'][ $postType['name'] ] = $defaultOptions;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the search appearance options for dynamic objects.
|
||||
*
|
||||
* @since 4.1.4
|
||||
*
|
||||
* @return array The default options.
|
||||
*/
|
||||
protected function getDefaultSearchAppearanceOptions() {
|
||||
return [ // phpcs:disable WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound
|
||||
'show' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'advanced' => [
|
||||
'robotsMeta' => [
|
||||
'default' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'noindex' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'nofollow' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'noarchive' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'noimageindex' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'notranslate' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'nosnippet' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'noodp' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'maxSnippet' => [ 'type' => 'number', 'default' => -1 ],
|
||||
'maxVideoPreview' => [ 'type' => 'number', 'default' => -1 ],
|
||||
'maxImagePreview' => [ 'type' => 'string', 'default' => 'large' ]
|
||||
],
|
||||
'showDateInGooglePreview' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'showPostThumbnailInSearch' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'showMetaBox' => [ 'type' => 'boolean', 'default' => true ]
|
||||
]
|
||||
]; // phpcs:enable WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the dynamic social settings for a given post type or taxonomy.
|
||||
*
|
||||
* @since 4.1.4
|
||||
*
|
||||
* @param string $objectType Whether the object belongs to the dynamic "postTypes" or "taxonomies".
|
||||
* @param string $objectName The object name.
|
||||
* @return void
|
||||
*/
|
||||
protected function setDynamicSocialOptions( $objectType, $objectName ) {
|
||||
$defaultOptions = [
|
||||
'objectType' => [
|
||||
'type' => 'string',
|
||||
'default' => 'article'
|
||||
]
|
||||
];
|
||||
|
||||
$this->defaults['social']['facebook']['general'][ $objectType ][ $objectName ] = $defaultOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the dynamic sitemap settings for a given post type or taxonomy.
|
||||
*
|
||||
* @since 4.1.4
|
||||
*
|
||||
* @param string $objectType Whether the object belongs to the dynamic "postTypes" or "taxonomies".
|
||||
* @param string $objectName The object name.
|
||||
* @return void
|
||||
*/
|
||||
protected function setDynamicSitemapOptions( $objectType, $objectName ) {
|
||||
$this->defaults['sitemap']['priority'][ $objectType ][ $objectName ] = [
|
||||
'priority' => [
|
||||
'type' => 'string',
|
||||
'default' => '{"label":"default","value":"default"}'
|
||||
],
|
||||
'frequency' => [
|
||||
'type' => 'string',
|
||||
'default' => '{"label":"default","value":"default"}'
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
namespace AIOSEO\Plugin\Common\Options;
|
||||
|
||||
// Exit if accessed directly.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
use AIOSEO\Plugin\Common\Traits;
|
||||
use AIOSEO\Plugin\Common\Utils;
|
||||
|
||||
/**
|
||||
* Class that holds all internal network options for AIOSEO.
|
||||
*
|
||||
* @since 4.2.5
|
||||
*/
|
||||
class InternalNetworkOptions {
|
||||
use Traits\Options;
|
||||
use Traits\NetworkOptions;
|
||||
|
||||
/**
|
||||
* Holds the helpers class.
|
||||
*
|
||||
* @since 4.2.5
|
||||
*
|
||||
* @var Utils\Helpers
|
||||
*/
|
||||
protected $helpers;
|
||||
|
||||
/**
|
||||
* All the default options.
|
||||
*
|
||||
* @since 4.2.5
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $defaults = [];
|
||||
|
||||
/**
|
||||
* The Construct method.
|
||||
*
|
||||
* @since 4.2.5
|
||||
*
|
||||
* @param string $optionsName The options name.
|
||||
*/
|
||||
public function __construct( $optionsName = 'aioseo_options_network_internal' ) {
|
||||
$this->helpers = new Utils\Helpers();
|
||||
$this->optionsName = $optionsName;
|
||||
|
||||
$this->init();
|
||||
|
||||
add_action( 'shutdown', [ $this, 'save' ] );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
<?php
|
||||
namespace AIOSEO\Plugin\Common\Options;
|
||||
|
||||
// Exit if accessed directly.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
use AIOSEO\Plugin\Common\Traits;
|
||||
|
||||
/**
|
||||
* Class that holds all internal options for AIOSEO.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
class InternalOptions {
|
||||
use Traits\Options;
|
||||
|
||||
/**
|
||||
* Holds a list of all the possible deprecated options.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $allDeprecatedOptions = [
|
||||
'autogenerateDescriptions',
|
||||
'badBotBlocker',
|
||||
'breadcrumbsEnable',
|
||||
'descriptionFormat',
|
||||
'enableSchemaMarkup',
|
||||
'excludePosts',
|
||||
'excludeTerms',
|
||||
'googleAnalytics',
|
||||
'noPaginationForCanonical',
|
||||
'staticSitemap',
|
||||
'staticVideoSitemap',
|
||||
'useContentForAutogeneratedDescriptions'
|
||||
];
|
||||
|
||||
/**
|
||||
* All the default options.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $defaults = [
|
||||
// phpcs:disable WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound
|
||||
'internal' => [
|
||||
'validLicenseKey' => [ 'type' => 'string' ],
|
||||
'lastActiveVersion' => [ 'type' => 'string', 'default' => '0.0' ],
|
||||
'migratedVersion' => [ 'type' => 'string' ],
|
||||
'siteAnalysis' => [
|
||||
'connectToken' => [ 'type' => 'string' ],
|
||||
'score' => [ 'type' => 'number', 'default' => 0 ],
|
||||
'results' => [ 'type' => 'string' ],
|
||||
'competitors' => [ 'type' => 'array', 'default' => [], 'preserveHtml' => true ]
|
||||
],
|
||||
'headlineAnalysis' => [
|
||||
'headlines' => [ 'type' => 'array', 'default' => [] ]
|
||||
],
|
||||
'wizard' => [ 'type' => 'string' ],
|
||||
'category' => [ 'type' => 'string' ],
|
||||
'categoryOther' => [ 'type' => 'string' ],
|
||||
'deprecatedOptions' => [ 'type' => 'array', 'default' => [] ],
|
||||
'searchStatistics' => [
|
||||
'profile' => [ 'type' => 'array', 'default' => [] ],
|
||||
'trustToken' => [ 'type' => 'string' ],
|
||||
'rolling' => [ 'type' => 'string', 'default' => 'last28Days' ],
|
||||
'site' => [
|
||||
'verified' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'lastFetch' => [ 'type' => 'number', 'default' => 0 ]
|
||||
],
|
||||
'sitemap' => [
|
||||
'list' => [ 'type' => 'array', 'default' => [] ],
|
||||
'ignored' => [ 'type' => 'array', 'default' => [] ],
|
||||
'lastFetch' => [ 'type' => 'number', 'default' => 0 ]
|
||||
]
|
||||
]
|
||||
],
|
||||
'integrations' => [
|
||||
'semrush' => [
|
||||
'accessToken' => [ 'type' => 'string' ],
|
||||
'tokenType' => [ 'type' => 'string' ],
|
||||
'expires' => [ 'type' => 'string' ],
|
||||
'refreshToken' => [ 'type' => 'string' ]
|
||||
]
|
||||
],
|
||||
'database' => [
|
||||
'installedTables' => [ 'type' => 'string' ]
|
||||
]
|
||||
// phpcs:enable WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound
|
||||
];
|
||||
|
||||
/**
|
||||
* The Construct method.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @param string $optionsName The options name.
|
||||
*/
|
||||
public function __construct( $optionsName = 'aioseo_options_internal' ) {
|
||||
$this->optionsName = $optionsName;
|
||||
|
||||
$this->init();
|
||||
|
||||
add_action( 'shutdown', [ $this, 'save' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the options.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function init() {
|
||||
// Options from the DB.
|
||||
$dbOptions = $this->getDbOptions( $this->optionsName );
|
||||
|
||||
// Refactor options.
|
||||
$this->defaultsMerged = array_replace_recursive( $this->defaults, $this->defaultsMerged );
|
||||
|
||||
$options = array_replace_recursive(
|
||||
$this->defaultsMerged,
|
||||
$this->addValueToValuesArray( $this->defaultsMerged, $dbOptions )
|
||||
);
|
||||
|
||||
aioseo()->core->optionsCache->setOptions( $this->optionsName, apply_filters( 'aioseo_get_options_internal', $options ) );
|
||||
|
||||
// Get the localized options.
|
||||
$dbOptionsLocalized = get_option( $this->optionsName . '_localized' );
|
||||
if ( empty( $dbOptionsLocalized ) ) {
|
||||
$dbOptionsLocalized = [];
|
||||
}
|
||||
$this->localized = $dbOptionsLocalized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the deprecated options.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @param bool $includeNamesAndValues Whether or not to include option names.
|
||||
* @return array An array of deprecated options.
|
||||
*/
|
||||
public function getAllDeprecatedOptions( $includeNamesAndValues = false ) {
|
||||
if ( ! $includeNamesAndValues ) {
|
||||
return $this->allDeprecatedOptions;
|
||||
}
|
||||
|
||||
$options = [];
|
||||
foreach ( $this->allDeprecatedOptions as $deprecatedOption ) {
|
||||
$options[] = [
|
||||
'label' => ucwords( str_replace( '_', ' ', aioseo()->helpers->toSnakeCase( $deprecatedOption ) ) ),
|
||||
'value' => $deprecatedOption,
|
||||
'enabled' => in_array( $deprecatedOption, aioseo()->internalOptions->internal->deprecatedOptions, true )
|
||||
];
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes, then saves the options to the database.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @param array $options An array of options to sanitize, then save.
|
||||
* @return void
|
||||
*/
|
||||
public function sanitizeAndSave( $options ) {
|
||||
if ( ! is_array( $options ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// First, recursively replace the new options into the cached state.
|
||||
// It's important we use the helper method since we want to replace populated arrays with empty ones if needed (when a setting was cleared out).
|
||||
$cachedOptions = aioseo()->core->optionsCache->getOptions( $this->optionsName );
|
||||
$dbOptions = aioseo()->helpers->arrayReplaceRecursive(
|
||||
$cachedOptions,
|
||||
$this->addValueToValuesArray( $cachedOptions, $options, [], true )
|
||||
);
|
||||
|
||||
// Now, we must also intersect both arrays to delete any individual keys that were unset.
|
||||
// We must do this because, while arrayReplaceRecursive will update the values for keys or empty them out,
|
||||
// it will keys that aren't present in the replacement array unaffected in the target array.
|
||||
$dbOptions = aioseo()->helpers->arrayIntersectRecursive(
|
||||
$dbOptions,
|
||||
$this->addValueToValuesArray( $cachedOptions, $options, [], true ),
|
||||
'value'
|
||||
);
|
||||
|
||||
// Update the cache state.
|
||||
aioseo()->core->optionsCache->setOptions( $this->optionsName, $dbOptions );
|
||||
|
||||
// Update localized options.
|
||||
update_option( $this->optionsName . '_localized', $this->localized );
|
||||
|
||||
// Finally, save the new values to the DB.
|
||||
$this->save( true );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
namespace AIOSEO\Plugin\Common\Options;
|
||||
|
||||
// Exit if accessed directly.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
use AIOSEO\Plugin\Common\Traits;
|
||||
use AIOSEO\Plugin\Common\Utils;
|
||||
|
||||
/**
|
||||
* Class that holds all network options for AIOSEO.
|
||||
*
|
||||
* @since 4.2.5
|
||||
*/
|
||||
class NetworkOptions {
|
||||
use Traits\Options;
|
||||
use Traits\NetworkOptions;
|
||||
|
||||
/**
|
||||
* Holds the helpers class.
|
||||
*
|
||||
* @since 4.2.5
|
||||
*
|
||||
* @var Utils\Helpers
|
||||
*/
|
||||
protected $helpers;
|
||||
|
||||
/**
|
||||
* All the default options.
|
||||
*
|
||||
* @since 4.2.5
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $defaults = [
|
||||
// phpcs:disable WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound
|
||||
'searchAppearance' => [
|
||||
'advanced' => [
|
||||
'unwantedBots' => [
|
||||
'all' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'settings' => [
|
||||
'googleAdsBot' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'openAiGptBot' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'commonCrawlCcBot' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'googleGeminiVertexAiBots' => [ 'type' => 'boolean', 'default' => false ]
|
||||
]
|
||||
],
|
||||
'searchCleanup' => [
|
||||
'settings' => [
|
||||
'preventCrawling' => [ 'type' => 'boolean', 'default' => false ]
|
||||
]
|
||||
]
|
||||
]
|
||||
],
|
||||
'tools' => [
|
||||
'robots' => [
|
||||
'enable' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'rules' => [ 'type' => 'array', 'default' => [] ],
|
||||
'robotsDetected' => [ 'type' => 'boolean', 'default' => true ],
|
||||
]
|
||||
]
|
||||
// phpcs:enable WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound
|
||||
];
|
||||
|
||||
/**
|
||||
* The Construct method.
|
||||
*
|
||||
* @since 4.2.5
|
||||
*
|
||||
* @param string $optionsName The options name.
|
||||
*/
|
||||
public function __construct( $optionsName = 'aioseo_options_network' ) {
|
||||
$this->helpers = new Utils\Helpers();
|
||||
$this->optionsName = $optionsName;
|
||||
|
||||
$this->init();
|
||||
|
||||
add_action( 'shutdown', [ $this, 'save' ] );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,829 @@
|
||||
<?php
|
||||
namespace AIOSEO\Plugin\Common\Options;
|
||||
|
||||
// Exit if accessed directly.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
use AIOSEO\Plugin\Common\Models;
|
||||
use AIOSEO\Plugin\Common\Traits;
|
||||
|
||||
/**
|
||||
* Class that holds all options for AIOSEO.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
class Options {
|
||||
use Traits\Options;
|
||||
|
||||
/**
|
||||
* All the default options.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $defaults = [
|
||||
// phpcs:disable WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound
|
||||
'internal' => [],
|
||||
'webmasterTools' => [
|
||||
'google' => [ 'type' => 'string' ],
|
||||
'bing' => [ 'type' => 'string' ],
|
||||
'yandex' => [ 'type' => 'string' ],
|
||||
'baidu' => [ 'type' => 'string' ],
|
||||
'pinterest' => [ 'type' => 'string' ],
|
||||
'microsoftClarityProjectId' => [ 'type' => 'string' ],
|
||||
'norton' => [ 'type' => 'string' ],
|
||||
'miscellaneousVerification' => [ 'type' => 'html' ]
|
||||
],
|
||||
'breadcrumbs' => [
|
||||
'separator' => [ 'type' => 'string', 'default' => '»' ],
|
||||
'homepageLink' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'homepageLabel' => [ 'type' => 'string', 'default' => 'Home' ],
|
||||
'breadcrumbPrefix' => [ 'type' => 'string', 'localized' => true, 'default' => '' ],
|
||||
'archiveFormat' => [ 'type' => 'string', 'default' => 'Archives for #breadcrumb_archive_post_type_name', 'localized' => true ],
|
||||
'searchResultFormat' => [ 'type' => 'string', 'default' => 'Search Results for \'#breadcrumb_search_string\'', 'localized' => true ],
|
||||
'errorFormat404' => [ 'type' => 'string', 'default' => '404 - Page Not Found', 'localized' => true ],
|
||||
'showCurrentItem' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'linkCurrentItem' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'categoryFullHierarchy' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'showBlogHome' => [ 'type' => 'boolean', 'default' => false ]
|
||||
],
|
||||
'rssContent' => [
|
||||
'before' => [ 'type' => 'html' ],
|
||||
'after' => [
|
||||
'type' => 'html',
|
||||
'default' => <<<TEMPLATE
|
||||
<p>The post #post_link first appeared on #site_link.</p>
|
||||
TEMPLATE
|
||||
]
|
||||
],
|
||||
'advanced' => [
|
||||
'truSeo' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'headlineAnalyzer' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'seoAnalysis' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'dashboardWidgets' => [ 'type' => 'array', 'default' => [ 'seoSetup', 'seoOverview', 'seoNews' ] ],
|
||||
'announcements' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'postTypes' => [
|
||||
'all' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'included' => [ 'type' => 'array', 'default' => [ 'post', 'page', 'product' ] ],
|
||||
],
|
||||
'taxonomies' => [
|
||||
'all' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'included' => [ 'type' => 'array', 'default' => [ 'category', 'post_tag', 'product_cat', 'product_tag' ] ],
|
||||
],
|
||||
'uninstall' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'emailSummary' => [
|
||||
'enable' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'recipients' => [ 'type' => 'array', 'default' => [] ]
|
||||
]
|
||||
],
|
||||
'sitemap' => [
|
||||
'general' => [
|
||||
'enable' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'filename' => [ 'type' => 'string', 'default' => 'sitemap' ],
|
||||
'indexes' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'linksPerIndex' => [ 'type' => 'number', 'default' => 1000 ],
|
||||
// @TODO: [V4+] Convert this to the dynamic options like in search appearance so we can have backups when plugins are deactivated.
|
||||
'postTypes' => [
|
||||
'all' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'included' => [ 'type' => 'array', 'default' => [ 'post', 'page', 'attachment', 'product' ] ],
|
||||
],
|
||||
// @TODO: [V4+] Convert this to the dynamic options like in search appearance so we can have backups when plugins are deactivated.
|
||||
'taxonomies' => [
|
||||
'all' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'included' => [ 'type' => 'array', 'default' => [ 'category', 'post_tag', 'product_cat', 'product_tag' ] ],
|
||||
],
|
||||
'author' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'date' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'additionalPages' => [
|
||||
'enable' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'pages' => [ 'type' => 'array', 'default' => [] ]
|
||||
],
|
||||
'advancedSettings' => [
|
||||
'enable' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'excludeImages' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'excludePosts' => [ 'type' => 'array', 'default' => [] ],
|
||||
'excludeTerms' => [ 'type' => 'array', 'default' => [] ],
|
||||
'priority' => [
|
||||
'homePage' => [
|
||||
'priority' => [ 'type' => 'string', 'default' => '{"label":"default","value":"default"}' ],
|
||||
'frequency' => [ 'type' => 'string', 'default' => '{"label":"default","value":"default"}' ]
|
||||
],
|
||||
'postTypes' => [
|
||||
'grouped' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'priority' => [ 'type' => 'string', 'default' => '{"label":"default","value":"default"}' ],
|
||||
'frequency' => [ 'type' => 'string', 'default' => '{"label":"default","value":"default"}' ]
|
||||
],
|
||||
'taxonomies' => [
|
||||
'grouped' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'priority' => [ 'type' => 'string', 'default' => '{"label":"default","value":"default"}' ],
|
||||
'frequency' => [ 'type' => 'string', 'default' => '{"label":"default","value":"default"}' ]
|
||||
],
|
||||
'archive' => [
|
||||
'priority' => [ 'type' => 'string', 'default' => '{"label":"default","value":"default"}' ],
|
||||
'frequency' => [ 'type' => 'string', 'default' => '{"label":"default","value":"default"}' ]
|
||||
],
|
||||
'author' => [
|
||||
'priority' => [ 'type' => 'string', 'default' => '{"label":"default","value":"default"}' ],
|
||||
'frequency' => [ 'type' => 'string', 'default' => '{"label":"default","value":"default"}' ]
|
||||
]
|
||||
]
|
||||
]
|
||||
],
|
||||
'rss' => [
|
||||
'enable' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'linksPerIndex' => [ 'type' => 'number', 'default' => 50 ],
|
||||
// @TODO: [V4+] Convert this to the dynamic options like in search appearance so we can have backups when plugins are deactivated.
|
||||
'postTypes' => [
|
||||
'all' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'included' => [ 'type' => 'array', 'default' => [ 'post', 'page', 'product' ] ],
|
||||
]
|
||||
],
|
||||
'html' => [
|
||||
'enable' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'pageUrl' => [ 'type' => 'string', 'default' => '' ],
|
||||
'postTypes' => [
|
||||
'all' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'included' => [ 'type' => 'array', 'default' => [ 'post', 'page', 'product' ] ],
|
||||
],
|
||||
'taxonomies' => [
|
||||
'all' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'included' => [ 'type' => 'array', 'default' => [ 'category', 'post_tag', 'product_cat', 'product_tag' ] ],
|
||||
],
|
||||
'sortOrder' => [ 'type' => 'string', 'default' => 'publish_date' ],
|
||||
'sortDirection' => [ 'type' => 'string', 'default' => 'asc' ],
|
||||
'publicationDate' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'compactArchives' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'advancedSettings' => [
|
||||
'enable' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'nofollowLinks' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'excludePosts' => [ 'type' => 'array', 'default' => [] ],
|
||||
'excludeTerms' => [ 'type' => 'array', 'default' => [] ]
|
||||
]
|
||||
],
|
||||
],
|
||||
'social' => [
|
||||
'profiles' => [
|
||||
'sameUsername' => [
|
||||
'enable' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'username' => [ 'type' => 'string' ],
|
||||
'included' => [ 'type' => 'array', 'default' => [ 'facebookPageUrl', 'twitterUrl', 'tiktokUrl', 'pinterestUrl', 'instagramUrl', 'youtubeUrl', 'linkedinUrl' ] ]
|
||||
],
|
||||
'urls' => [
|
||||
'facebookPageUrl' => [ 'type' => 'string' ],
|
||||
'twitterUrl' => [ 'type' => 'string' ],
|
||||
'instagramUrl' => [ 'type' => 'string' ],
|
||||
'tiktokUrl' => [ 'type' => 'string' ],
|
||||
'pinterestUrl' => [ 'type' => 'string' ],
|
||||
'youtubeUrl' => [ 'type' => 'string' ],
|
||||
'linkedinUrl' => [ 'type' => 'string' ],
|
||||
'tumblrUrl' => [ 'type' => 'string' ],
|
||||
'yelpPageUrl' => [ 'type' => 'string' ],
|
||||
'soundCloudUrl' => [ 'type' => 'string' ],
|
||||
'wikipediaUrl' => [ 'type' => 'string' ],
|
||||
'myspaceUrl' => [ 'type' => 'string' ],
|
||||
'googlePlacesUrl' => [ 'type' => 'string' ],
|
||||
'wordPressUrl' => [ 'type' => 'string' ],
|
||||
],
|
||||
'additionalUrls' => [ 'type' => 'string' ]
|
||||
],
|
||||
'facebook' => [
|
||||
'general' => [
|
||||
'enable' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'defaultImageSourcePosts' => [ 'type' => 'string', 'default' => 'default' ],
|
||||
'customFieldImagePosts' => [ 'type' => 'string' ],
|
||||
'defaultImagePosts' => [ 'type' => 'string', 'default' => '' ],
|
||||
'defaultImagePostsWidth' => [ 'type' => 'number', 'default' => '' ],
|
||||
'defaultImagePostsHeight' => [ 'type' => 'number', 'default' => '' ],
|
||||
'showAuthor' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'siteName' => [ 'type' => 'string', 'localized' => true, 'default' => '#site_title #separator_sa #tagline' ]
|
||||
],
|
||||
'homePage' => [
|
||||
'image' => [ 'type' => 'string', 'default' => '' ],
|
||||
'title' => [ 'type' => 'string', 'localized' => true, 'default' => '' ],
|
||||
'description' => [ 'type' => 'string', 'localized' => true, 'default' => '' ],
|
||||
'imageWidth' => [ 'type' => 'number', 'default' => '' ],
|
||||
'imageHeight' => [ 'type' => 'number', 'default' => '' ],
|
||||
'objectType' => [ 'type' => 'string', 'default' => 'website' ]
|
||||
],
|
||||
'advanced' => [
|
||||
'enable' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'adminId' => [ 'type' => 'string', 'default' => '' ],
|
||||
'appId' => [ 'type' => 'string', 'default' => '' ],
|
||||
'authorUrl' => [ 'type' => 'string', 'default' => '' ],
|
||||
'generateArticleTags' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'useKeywordsInTags' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'useCategoriesInTags' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'usePostTagsInTags' => [ 'type' => 'boolean', 'default' => true ]
|
||||
]
|
||||
],
|
||||
'twitter' => [
|
||||
'general' => [
|
||||
'enable' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'useOgData' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'defaultCardType' => [ 'type' => 'string', 'default' => 'summary_large_image' ],
|
||||
'defaultImageSourcePosts' => [ 'type' => 'string', 'default' => 'default' ],
|
||||
'customFieldImagePosts' => [ 'type' => 'string' ],
|
||||
'defaultImagePosts' => [ 'type' => 'string', 'default' => '' ],
|
||||
'showAuthor' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'additionalData' => [ 'type' => 'boolean', 'default' => false ]
|
||||
],
|
||||
'homePage' => [
|
||||
'image' => [ 'type' => 'string', 'default' => '' ],
|
||||
'title' => [ 'type' => 'string', 'localized' => true, 'default' => '' ],
|
||||
'description' => [ 'type' => 'string', 'localized' => true, 'default' => '' ],
|
||||
'cardType' => [ 'type' => 'string', 'default' => 'summary' ]
|
||||
],
|
||||
]
|
||||
],
|
||||
'searchAppearance' => [
|
||||
'global' => [
|
||||
'separator' => [ 'type' => 'string', 'default' => '-' ],
|
||||
'siteTitle' => [ 'type' => 'string', 'localized' => true, 'default' => '#site_title #separator_sa #tagline' ],
|
||||
'metaDescription' => [ 'type' => 'string', 'localized' => true, 'default' => '#tagline' ],
|
||||
'keywords' => [ 'type' => 'string', 'localized' => true ],
|
||||
'schema' => [
|
||||
'websiteName' => [ 'type' => 'string', 'default' => '#site_title' ],
|
||||
'websiteAlternateName' => [ 'type' => 'string' ],
|
||||
'siteRepresents' => [ 'type' => 'string', 'default' => 'organization' ],
|
||||
'person' => [ 'type' => 'string' ],
|
||||
'organizationName' => [ 'type' => 'string', 'default' => '#site_title' ],
|
||||
'organizationDescription' => [ 'type' => 'string', 'default' => '#tagline' ],
|
||||
'organizationLogo' => [ 'type' => 'string' ],
|
||||
'personName' => [ 'type' => 'string' ],
|
||||
'personLogo' => [ 'type' => 'string' ],
|
||||
'phone' => [ 'type' => 'string' ],
|
||||
'email' => [ 'type' => 'string' ],
|
||||
'foundingDate' => [ 'type' => 'string' ],
|
||||
'numberOfEmployees' => [
|
||||
'isRange' => [ 'type' => 'boolean' ],
|
||||
'from' => [ 'type' => 'number' ],
|
||||
'to' => [ 'type' => 'number' ],
|
||||
'number' => [ 'type' => 'number' ]
|
||||
]
|
||||
]
|
||||
],
|
||||
'advanced' => [
|
||||
'globalRobotsMeta' => [
|
||||
'default' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'noindex' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'nofollow' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'noindexPaginated' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'nofollowPaginated' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'noindexFeed' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'noarchive' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'noimageindex' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'notranslate' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'nosnippet' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'noodp' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'maxSnippet' => [ 'type' => 'number', 'default' => -1 ],
|
||||
'maxVideoPreview' => [ 'type' => 'number', 'default' => -1 ],
|
||||
'maxImagePreview' => [ 'type' => 'string', 'default' => 'large' ]
|
||||
],
|
||||
'noIndexEmptyCat' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'removeStopWords' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'useKeywords' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'keywordsLooking' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'useCategoriesForMetaKeywords' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'useTagsForMetaKeywords' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'dynamicallyGenerateKeywords' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'pagedFormat' => [ 'type' => 'string', 'default' => '#separator_sa Page #page_number', 'localized' => true ],
|
||||
'runShortcodes' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'crawlCleanup' => [
|
||||
'enable' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'feeds' => [
|
||||
'global' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'globalComments' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'staticBlogPage' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'authors' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'postComments' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'search' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'attachments' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'archives' => [
|
||||
'all' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'included' => [ 'type' => 'array', 'default' => [] ],
|
||||
],
|
||||
'taxonomies' => [
|
||||
'all' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'included' => [ 'type' => 'array', 'default' => [ 'category' ] ],
|
||||
],
|
||||
'atom' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'rdf' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'paginated' => [ 'type' => 'boolean', 'default' => false ]
|
||||
]
|
||||
],
|
||||
'unwantedBots' => [
|
||||
'all' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'settings' => [
|
||||
'googleAdsBot' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'openAiGptBot' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'commonCrawlCcBot' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'googleGeminiVertexAiBots' => [ 'type' => 'boolean', 'default' => false ]
|
||||
]
|
||||
],
|
||||
'searchCleanup' => [
|
||||
'enable' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'settings' => [
|
||||
'maxAllowedNumberOfChars' => [ 'type' => 'number', 'default' => 50 ],
|
||||
'emojisAndSymbols' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'commonPatterns' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'redirectPrettyUrls' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'preventCrawling' => [ 'type' => 'boolean', 'default' => false ]
|
||||
]
|
||||
],
|
||||
'blockArgs' => [
|
||||
'enable' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'optimizeUtmParameters' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'logsRetention' => [ 'type' => 'string', 'default' => '{"label":"1 week","value":"week"}' ]
|
||||
],
|
||||
'removeCategoryBase' => [ 'type' => 'boolean', 'default' => false ]
|
||||
],
|
||||
'archives' => [
|
||||
'author' => [
|
||||
'show' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'title' => [ 'type' => 'string', 'localized' => true, 'default' => '#author_name #separator_sa #site_title' ],
|
||||
'metaDescription' => [ 'type' => 'string', 'localized' => true, 'default' => '#author_bio' ],
|
||||
'advanced' => [
|
||||
'robotsMeta' => [
|
||||
'default' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'noindex' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'nofollow' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'noarchive' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'noimageindex' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'notranslate' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'nosnippet' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'noodp' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'maxSnippet' => [ 'type' => 'number', 'default' => -1 ],
|
||||
'maxVideoPreview' => [ 'type' => 'number', 'default' => -1 ],
|
||||
'maxImagePreview' => [ 'type' => 'string', 'default' => 'large' ]
|
||||
],
|
||||
'showDateInGooglePreview' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'showPostThumbnailInSearch' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'showMetaBox' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'keywords' => [ 'type' => 'string', 'localized' => true ]
|
||||
]
|
||||
],
|
||||
'date' => [
|
||||
'show' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'title' => [ 'type' => 'string', 'localized' => true, 'default' => '#archive_date #separator_sa #site_title' ],
|
||||
'metaDescription' => [ 'type' => 'string', 'localized' => true, 'default' => '' ],
|
||||
'advanced' => [
|
||||
'robotsMeta' => [
|
||||
'default' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'noindex' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'nofollow' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'noarchive' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'noimageindex' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'notranslate' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'nosnippet' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'noodp' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'maxSnippet' => [ 'type' => 'number', 'default' => -1 ],
|
||||
'maxVideoPreview' => [ 'type' => 'number', 'default' => -1 ],
|
||||
'maxImagePreview' => [ 'type' => 'string', 'default' => 'large' ]
|
||||
],
|
||||
'showDateInGooglePreview' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'showPostThumbnailInSearch' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'showMetaBox' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'keywords' => [ 'type' => 'string', 'localized' => true ]
|
||||
]
|
||||
],
|
||||
'search' => [
|
||||
'show' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'title' => [ 'type' => 'string', 'localized' => true, 'default' => '#search_term #separator_sa #site_title' ],
|
||||
'metaDescription' => [ 'type' => 'string', 'localized' => true, 'default' => '' ],
|
||||
'advanced' => [
|
||||
'robotsMeta' => [
|
||||
'default' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'noindex' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'nofollow' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'noarchive' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'noimageindex' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'notranslate' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'nosnippet' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'noodp' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'maxSnippet' => [ 'type' => 'number', 'default' => -1 ],
|
||||
'maxVideoPreview' => [ 'type' => 'number', 'default' => -1 ],
|
||||
'maxImagePreview' => [ 'type' => 'string', 'default' => 'large' ]
|
||||
],
|
||||
'showDateInGooglePreview' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'showPostThumbnailInSearch' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'showMetaBox' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'keywords' => [ 'type' => 'string', 'localized' => true ]
|
||||
]
|
||||
]
|
||||
]
|
||||
],
|
||||
'searchStatistics' => [
|
||||
'postTypes' => [
|
||||
'all' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'included' => [ 'type' => 'array', 'default' => [ 'post', 'page' ] ],
|
||||
]
|
||||
],
|
||||
'tools' => [
|
||||
'robots' => [
|
||||
'enable' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'rules' => [ 'type' => 'array', 'default' => [] ],
|
||||
'robotsDetected' => [ 'type' => 'boolean', 'default' => true ],
|
||||
],
|
||||
'importExport' => [
|
||||
'backup' => [
|
||||
'lastTime' => [ 'type' => 'string' ],
|
||||
'data' => [ 'type' => 'string' ],
|
||||
]
|
||||
]
|
||||
],
|
||||
'deprecated' => [
|
||||
'breadcrumbs' => [
|
||||
'enable' => [ 'type' => 'boolean', 'default' => true ]
|
||||
],
|
||||
'searchAppearance' => [
|
||||
'global' => [
|
||||
'descriptionFormat' => [ 'type' => 'string' ],
|
||||
'schema' => [
|
||||
'enableSchemaMarkup' => [ 'type' => 'boolean', 'default' => true ]
|
||||
]
|
||||
],
|
||||
'advanced' => [
|
||||
'autogenerateDescriptions' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'runShortcodesInDescription' => [ 'type' => 'boolean', 'default' => true ], // TODO: Remove this in a future update.
|
||||
'useContentForAutogeneratedDescriptions' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'excludePosts' => [ 'type' => 'array', 'default' => [] ],
|
||||
'excludeTerms' => [ 'type' => 'array', 'default' => [] ],
|
||||
'noPaginationForCanonical' => [ 'type' => 'boolean', 'default' => true ]
|
||||
]
|
||||
],
|
||||
'sitemap' => [
|
||||
'general' => [
|
||||
'advancedSettings' => [
|
||||
'dynamic' => [ 'type' => 'boolean', 'default' => true ]
|
||||
]
|
||||
]
|
||||
],
|
||||
'tools' => [
|
||||
'blocker' => [
|
||||
'blockBots' => [ 'type' => 'boolean' ],
|
||||
'blockReferer' => [ 'type' => 'boolean' ],
|
||||
'track' => [ 'type' => 'boolean' ],
|
||||
'custom' => [
|
||||
'enable' => [ 'type' => 'boolean' ],
|
||||
'bots' => [ 'type' => 'html', 'default' => '' ],
|
||||
'referer' => [ 'type' => 'html', 'default' => '' ]
|
||||
]
|
||||
]
|
||||
]
|
||||
],
|
||||
'writingAssistant' => [
|
||||
'postTypes' => [
|
||||
'all' => [ 'type' => 'boolean', 'default' => true ],
|
||||
'included' => [ 'type' => 'array', 'default' => [ 'post', 'page' ] ],
|
||||
]
|
||||
]
|
||||
// phpcs:enable WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound
|
||||
];
|
||||
|
||||
/**
|
||||
* The Construct method.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @param string $optionsName An array of options.
|
||||
*/
|
||||
public function __construct( $optionsName = 'aioseo_options' ) {
|
||||
$this->optionsName = $optionsName;
|
||||
|
||||
$this->init();
|
||||
|
||||
add_action( 'shutdown', [ $this, 'save' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the options.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init() {
|
||||
$this->setInitialDefaults();
|
||||
add_action( 'init', [ $this, 'translateDefaults' ] );
|
||||
|
||||
$this->setDbOptions();
|
||||
|
||||
add_action( 'wp_loaded', [ $this, 'maybeFlushRewriteRules' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the DB options to the class after merging in new defaults and dropping unknown values.
|
||||
*
|
||||
* @since 4.0.14
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setDbOptions() {
|
||||
// Refactor options.
|
||||
$this->defaultsMerged = array_replace_recursive( $this->defaults, $this->defaultsMerged );
|
||||
|
||||
$dbOptions = $this->getDbOptions( $this->optionsName );
|
||||
|
||||
$options = array_replace_recursive(
|
||||
$this->defaultsMerged,
|
||||
$this->addValueToValuesArray( $this->defaultsMerged, $dbOptions )
|
||||
);
|
||||
|
||||
aioseo()->core->optionsCache->setOptions( $this->optionsName, apply_filters( 'aioseo_get_options', $options ) );
|
||||
|
||||
// Get the localized options.
|
||||
$dbOptionsLocalized = get_option( $this->optionsName . '_localized' );
|
||||
if ( empty( $dbOptionsLocalized ) ) {
|
||||
$dbOptionsLocalized = [];
|
||||
}
|
||||
$this->localized = $dbOptionsLocalized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the initial defaults that can't be defined in the property because of PHP 5.4.
|
||||
*
|
||||
* @since 4.1.4
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setInitialDefaults() {
|
||||
static $hasInitialized = false;
|
||||
if ( $hasInitialized ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$hasInitialized = true;
|
||||
|
||||
$this->defaults['deprecated']['tools']['blocker']['custom']['bots']['default'] = implode( "\n", aioseo()->badBotBlocker->getBotList() );
|
||||
$this->defaults['deprecated']['tools']['blocker']['custom']['referer']['default'] = implode( "\n", aioseo()->badBotBlocker->getRefererList() );
|
||||
|
||||
$this->defaults['searchAppearance']['global']['schema']['organizationLogo']['default'] = aioseo()->helpers->getSiteLogoUrl() ? aioseo()->helpers->getSiteLogoUrl() : '';
|
||||
|
||||
$this->defaults['advanced']['emailSummary']['recipients']['default'] = [
|
||||
[
|
||||
'email' => get_bloginfo( 'admin_email' ),
|
||||
'frequency' => 'monthly',
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* For our defaults array, some options need to be translated, so we do that here.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function translateDefaults() {
|
||||
static $hasInitialized = false;
|
||||
if ( $hasInitialized ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$hasInitialized = true;
|
||||
|
||||
$default = sprintf( '{"label":"%1$s","value":"default"}', __( 'default', 'all-in-one-seo-pack' ) );
|
||||
$this->defaults['sitemap']['general']['advancedSettings']['priority']['homePage']['priority']['default'] = $default;
|
||||
$this->defaults['sitemap']['general']['advancedSettings']['priority']['homePage']['frequency']['default'] = $default;
|
||||
$this->defaults['sitemap']['general']['advancedSettings']['priority']['postTypes']['priority']['default'] = $default;
|
||||
$this->defaults['sitemap']['general']['advancedSettings']['priority']['postTypes']['frequency']['default'] = $default;
|
||||
$this->defaults['sitemap']['general']['advancedSettings']['priority']['taxonomies']['priority']['default'] = $default;
|
||||
$this->defaults['sitemap']['general']['advancedSettings']['priority']['taxonomies']['frequency']['default'] = $default;
|
||||
|
||||
$this->defaults['breadcrumbs']['homepageLabel']['default'] = __( 'Home', 'all-in-one-seo-pack' );
|
||||
$this->defaults['breadcrumbs']['archiveFormat']['default'] = sprintf( '%1$s #breadcrumb_archive_post_type_name', __( 'Archives for', 'all-in-one-seo-pack' ) );
|
||||
$this->defaults['breadcrumbs']['searchResultFormat']['default'] = sprintf( '%1$s \'#breadcrumb_search_string\'', __( 'Search Results for', 'all-in-one-seo-pack' ) );
|
||||
$this->defaults['breadcrumbs']['errorFormat404']['default'] = __( '404 - Page Not Found', 'all-in-one-seo-pack' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes, then saves the options to the database.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @param array $options An array of options to sanitize, then save.
|
||||
* @return void
|
||||
*/
|
||||
public function sanitizeAndSave( $options ) {
|
||||
$sitemapOptions = ! empty( $options['sitemap'] ) ? $options['sitemap'] : null;
|
||||
$oldSitemapOptions = aioseo()->options->sitemap->all();
|
||||
$generalSitemapOptions = ! empty( $options['sitemap']['general'] ) ? $options['sitemap']['general'] : null;
|
||||
$oldGeneralSitemapOptions = aioseo()->options->sitemap->general->all();
|
||||
$deprecatedGeneralSitemapOptions = ! empty( $options['deprecated']['sitemap']['general'] )
|
||||
? $options['deprecated']['sitemap']['general']
|
||||
: null;
|
||||
$oldDeprecatedGeneralSitemapOptions = aioseo()->options->deprecated->sitemap->general->all();
|
||||
$oldPhoneOption = aioseo()->options->searchAppearance->global->schema->phone;
|
||||
$phoneNumberOptions = isset( $options['searchAppearance']['global']['schema']['phone'] )
|
||||
? $options['searchAppearance']['global']['schema']['phone']
|
||||
: null;
|
||||
$oldHtmlSitemapUrl = aioseo()->options->sitemap->html->pageUrl;
|
||||
$logsRetention = isset( $options['searchAppearance']['advanced']['blockArgs']['logsRetention'] ) ? $options['searchAppearance']['advanced']['blockArgs']['logsRetention'] : null;
|
||||
$oldLogsRetention = aioseo()->options->searchAppearance->advanced->blockArgs->logsRetention;
|
||||
|
||||
// Remove category base.
|
||||
$removeCategoryBase = isset( $options['searchAppearance']['advanced']['removeCategoryBase'] ) ? $options['searchAppearance']['advanced']['removeCategoryBase'] : null;
|
||||
$removeCategoryBaseOld = aioseo()->options->searchAppearance->advanced->removeCategoryBase;
|
||||
|
||||
$options = $this->maybeRemoveUnfilteredHtmlFields( $options );
|
||||
|
||||
$this->init();
|
||||
|
||||
if ( ! is_array( $options ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->sanitizeEmailSummary( $options );
|
||||
|
||||
// First, recursively replace the new options into the cached state.
|
||||
// It's important we use the helper method since we want to replace populated arrays with empty ones if needed (when a setting was cleared out).
|
||||
$cachedOptions = aioseo()->core->optionsCache->getOptions( $this->optionsName );
|
||||
$dbOptions = aioseo()->helpers->arrayReplaceRecursive(
|
||||
$cachedOptions,
|
||||
$this->addValueToValuesArray( $cachedOptions, $options, [], true )
|
||||
);
|
||||
|
||||
// Now, we must also intersect both arrays to delete any individual keys that were unset.
|
||||
// We must do this because, while arrayReplaceRecursive will update the values for keys or empty them out,
|
||||
// it will keys that aren't present in the replacement array unaffected in the target array.
|
||||
$dbOptions = aioseo()->helpers->arrayIntersectRecursive(
|
||||
$dbOptions,
|
||||
$this->addValueToValuesArray( $cachedOptions, $options, [], true ),
|
||||
'value'
|
||||
);
|
||||
|
||||
if ( isset( $options['social']['profiles']['additionalUrls'] ) ) {
|
||||
$dbOptions['social']['profiles']['additionalUrls'] = preg_replace( '/\h/', "\n", (string) $options['social']['profiles']['additionalUrls'] );
|
||||
}
|
||||
|
||||
$newOptions = ! empty( $options['sitemap']['html'] ) ? $options['sitemap']['html'] : null;
|
||||
if ( ! empty( $newOptions ) && aioseo()->options->sitemap->html->enable ) {
|
||||
$newOptions = ! empty( $options['sitemap']['html'] ) ? $options['sitemap']['html'] : null;
|
||||
|
||||
$pageUrl = wp_parse_url( $newOptions['pageUrl'] );
|
||||
$path = ! empty( $pageUrl['path'] ) ? untrailingslashit( $pageUrl['path'] ) : '';
|
||||
if ( $path ) {
|
||||
$existingPage = get_page_by_path( $path, OBJECT );
|
||||
if ( is_object( $existingPage ) ) {
|
||||
// If the page exists, don't override the previous URL.
|
||||
$options['sitemap']['html']['pageUrl'] = $oldHtmlSitemapUrl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update the cache state.
|
||||
aioseo()->core->optionsCache->setOptions( $this->optionsName, $dbOptions );
|
||||
|
||||
// Update localized options.
|
||||
update_option( $this->optionsName . '_localized', $this->localized );
|
||||
|
||||
// Finally, save the new values to the DB.
|
||||
$this->save( true );
|
||||
|
||||
// If phone settings have changed, let's see if we need to dump the phone number notice.
|
||||
if (
|
||||
$phoneNumberOptions &&
|
||||
$phoneNumberOptions !== $oldPhoneOption
|
||||
) {
|
||||
$notification = Models\Notification::getNotificationByName( 'v3-migration-schema-number' );
|
||||
if ( $notification->exists() ) {
|
||||
Models\Notification::deleteNotificationByName( 'v3-migration-schema-number' );
|
||||
}
|
||||
}
|
||||
|
||||
// If sitemap settings were changed, static files need to be regenerated.
|
||||
if (
|
||||
! empty( $deprecatedGeneralSitemapOptions ) &&
|
||||
! empty( $generalSitemapOptions )
|
||||
) {
|
||||
if (
|
||||
(
|
||||
aioseo()->helpers->arraysDifferent( $oldGeneralSitemapOptions, $generalSitemapOptions ) ||
|
||||
aioseo()->helpers->arraysDifferent( $oldDeprecatedGeneralSitemapOptions, $deprecatedGeneralSitemapOptions )
|
||||
) &&
|
||||
$generalSitemapOptions['advancedSettings']['enable'] &&
|
||||
! $deprecatedGeneralSitemapOptions['advancedSettings']['dynamic']
|
||||
) {
|
||||
aioseo()->sitemap->scheduleRegeneration();
|
||||
}
|
||||
}
|
||||
|
||||
// Add or remove schedule for clearing crawl cleanup logs.
|
||||
if ( ! empty( $logsRetention ) && $oldLogsRetention !== $logsRetention ) {
|
||||
aioseo()->crawlCleanup->scheduleClearingLogs();
|
||||
}
|
||||
|
||||
if ( ! empty( $sitemapOptions ) ) {
|
||||
aioseo()->searchStatistics->sitemap->maybeSync( $oldSitemapOptions, $sitemapOptions );
|
||||
}
|
||||
|
||||
if (
|
||||
null !== $removeCategoryBase &&
|
||||
$removeCategoryBase !== $removeCategoryBaseOld
|
||||
) {
|
||||
aioseo()->options->flushRewriteRules();
|
||||
}
|
||||
|
||||
// This is required in order for the Pro options to be refreshed before they save data again.
|
||||
$this->refresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes the `emailSummary` option.
|
||||
*
|
||||
* @since 4.7.2
|
||||
*
|
||||
* @param array $options All options, passed by reference.
|
||||
* @return void
|
||||
*/
|
||||
private function sanitizeEmailSummary( &$options ) {
|
||||
foreach ( ( $options['advanced']['emailSummary']['recipients'] ?? [] ) as $k => &$recipient ) {
|
||||
$recipient['email'] = is_email( $recipient['email'] );
|
||||
|
||||
// Remove empty emails.
|
||||
if ( empty( $recipient['email'] ) ) {
|
||||
unset( $options['advanced']['emailSummary']['recipients'][ $k ] );
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove duplicate emails with the same frequency.
|
||||
foreach ( $options['advanced']['emailSummary']['recipients'] as $k2 => $recipient2 ) {
|
||||
if (
|
||||
$k !== $k2 &&
|
||||
$recipient['email'] === $recipient2['email'] &&
|
||||
$recipient['frequency'] === $recipient2['frequency']
|
||||
) {
|
||||
unset( $options['advanced']['emailSummary']['recipients'][ $k ] );
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the user does not have access to unfiltered HTML, we need to remove them from saving.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @param array $options An array of options.
|
||||
* @return array An array of options.
|
||||
*/
|
||||
private function maybeRemoveUnfilteredHtmlFields( $options ) {
|
||||
if ( current_user_can( 'unfiltered_html' ) ) {
|
||||
return $options;
|
||||
}
|
||||
|
||||
if (
|
||||
! empty( $options['webmasterTools'] ) &&
|
||||
isset( $options['webmasterTools']['miscellaneousVerification'] )
|
||||
) {
|
||||
unset( $options['webmasterTools']['miscellaneousVerification'] );
|
||||
}
|
||||
|
||||
if (
|
||||
! empty( $options['rssContent'] ) &&
|
||||
isset( $options['rssContent']['before'] )
|
||||
) {
|
||||
unset( $options['rssContent']['before'] );
|
||||
}
|
||||
|
||||
if (
|
||||
! empty( $options['rssContent'] ) &&
|
||||
isset( $options['rssContent']['after'] )
|
||||
) {
|
||||
unset( $options['rssContent']['after'] );
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate we need to flush rewrite rules on next load.
|
||||
*
|
||||
* @since 4.0.17
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function flushRewriteRules() {
|
||||
update_option( 'aioseo_flush_rewrite_rules_flag', true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush rewrite rules if needed.
|
||||
*
|
||||
* @since 4.0.17
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function maybeFlushRewriteRules() {
|
||||
if ( get_option( 'aioseo_flush_rewrite_rules_flag' ) ) {
|
||||
flush_rewrite_rules();
|
||||
delete_option( 'aioseo_flush_rewrite_rules_flag' );
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user