| Current Path : /home/x/b/o/xbodynamge/namtation/wp-content/ |
| Current File : /home/x/b/o/xbodynamge/namtation/wp-content/Options.tar |
Options.php 0000666 00000106145 15112777666 0006745 0 ustar 00 <?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' ],
'blueskyUrl' => [ 'type' => 'string' ],
'threadsUrl' => [ '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 ]
]
]
]
],
'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['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' );
}
}
} InternalOptions.php 0000666 00000013205 15112777666 0010434 0 ustar 00 <?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',
'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' ],
],
'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 );
}
} Cache.php 0000666 00000003103 15114751332 0006263 0 ustar 00 <?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 = [];
}
} NetworkOptions.php 0000666 00000003622 15114751332 0010273 0 ustar 00 <?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' ] );
}
} DynamicOptions.php 0000666 00000026113 15114751332 0010226 0 ustar 00 <?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 )
);
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"}'
]
];
}
} DynamicBackup.php 0000666 00000021020 15114751332 0007770 0 ustar 00 <?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 option defaults.
*
* @since 4.1.3
*
* @var array
*/
protected $defaultOptions = [];
/**
* 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->defaultOptions = 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 to.
* @return void
*/
protected function restoreOptions( $backupOptions, $groups ) {
$defaultOptions = $this->defaultOptions;
foreach ( $groups as $group ) {
if ( ! isset( $defaultOptions[ $group ] ) ) {
return;
}
$defaultOptions = $defaultOptions[ $group ];
}
$dynamicOptions = aioseo()->dynamicOptions->noConflict();
foreach ( $backupOptions as $setting => $value ) {
// Check if the option exists before proceeding. If not, it might be a group.
$type = $defaultOptions[ $setting ]['type'] ?? '';
if (
! $type &&
is_array( $value ) &&
aioseo()->helpers->isArrayAssociative( $value )
) {
$nextGroups = array_merge( $groups, [ $setting ] );
$this->restoreOptions( $backupOptions[ $setting ], $nextGroups );
continue;
}
// If we still can't find the option, it might be a group.
if ( ! $type ) {
continue;
}
foreach ( $groups as $group ) {
$dynamicOptions = $dynamicOptions->$group;
}
$dynamicOptions->$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;
}
}
}
} InternalNetworkOptions.php 0000666 00000001622 15114751332 0011766 0 ustar 00 <?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' ] );
}
}