log_file = WP_CONTENT_DIR . '/all-in-one-seo-pack.log'; // PHP <5.3 compatibility, once we drop support we can use __DIR___.
if ( ! empty( $aioseop_options ) && isset( $aioseop_options['aiosp_do_log'] ) && $aioseop_options['aiosp_do_log'] ) {
$this->do_log = true;
} else {
$this->do_log = false;
}
/* translators: This is a header for the General Settings menu. %s is a placeholder and is replaced with the name of the plugin. */
$this->name = sprintf( __( '%s Plugin Options', 'all-in-one-seo-pack' ), AIOSEOP_PLUGIN_NAME );
/* translators: This is the main menu of the plugin. */
$this->menu_name = __( 'General Settings', 'all-in-one-seo-pack' );
$this->prefix = 'aiosp_'; // Option prefix.
$this->option_name = 'aioseop_options';
$this->store_option = true;
$this->file = __FILE__; // The current file.
$blog_name = esc_attr( get_bloginfo( 'name' ) );
parent::__construct();
$this->default_options = array(
'license_key' => array(
/* translators: This is the name of a setting where users can enter their license code for All in One SEO Pack Pro. */
'name' => __( 'License Key:', 'all-in-one-seo-pack' ),
'type' => 'text',
),
'home_title' => array(
/* translators: This is the name of a setting where users can enter the title for their homepage. */
'name' => __( 'Home Title:', 'all-in-one-seo-pack' ),
'default' => null,
'type' => 'text',
'sanitize' => 'text',
'count' => true,
'rows' => 1,
'cols' => 60,
'condshow' => array( 'aiosp_use_static_home_info' => 0 ),
),
'home_description' => array(
/* translators: This is the name of a setting where users can enter the description for their homepage. */
'name' => __( 'Home Description:', 'all-in-one-seo-pack' ),
'default' => '',
'type' => 'textarea',
'sanitize' => 'text',
'count' => true,
'cols' => 80,
'rows' => 2,
'condshow' => array( 'aiosp_use_static_home_info' => 0 ),
),
'togglekeywords' => array(
/* translators: This is the name of a setting where users can enable the use of meta keywords for their website. */
'name' => __( 'Use Keywords:', 'all-in-one-seo-pack' ),
'default' => 1,
'type' => 'radio',
'initial_options' => array(
/* translators: Some settings are either 'Enabled' or 'Disabled'. 'Activated' and 'Deactivated' mean the same. */
0 => __( 'Enabled', 'all-in-one-seo-pack' ),
/* translators: Some settings are either 'Enabled' or 'Disabled'. 'Activated' and 'Deactivated' mean the same. */
1 => __( 'Disabled', 'all-in-one-seo-pack' ),
),
),
'home_keywords' => array(
/* translators: This is the name of a setting where users can enter meta keywords for their homepage. */
'name' => __( 'Home Keywords (comma separated):', 'all-in-one-seo-pack' ),
'default' => null,
'type' => 'textarea',
'sanitize' => 'text',
'condshow' => array(
'aiosp_togglekeywords' => 0,
'aiosp_use_static_home_info' => 0,
),
),
'use_static_home_info' => array(
/* translators: This is the name of a setting where users can indicate that their using a static page for their homepage. */
'name' => __( 'Use Static Front Page Instead', 'all-in-one-seo-pack' ),
'default' => 0,
'type' => 'radio',
'initial_options' => array(
1 => __( 'Enabled', 'all-in-one-seo-pack' ),
0 => __( 'Disabled', 'all-in-one-seo-pack' ),
),
),
'can' => array(
/* translators: This is the name of a setting. Canonical URLs help users prevent duplicate content issues - https://en.wikipedia.org/wiki/Canonical_link_element. Leave "Canonical" in English if there is no such term in your language. */
'name' => __( 'Canonical URLs:', 'all-in-one-seo-pack' ),
'default' => 1,
),
'no_paged_canonical_links' => array(
/* translators: This is the name of a setting. Canonical URLs help users prevent duplicate content issues - https://en.wikipedia.org/wiki/Canonical_link_element. Leave "Canonical" in English if there is no such term in your language. Enabling this setting means the plugin will use the URL of the first page as the canonical URL for all subsequent paginated pages. */
'name' => __( 'No Pagination for Canonical URLs:', 'all-in-one-seo-pack' ),
'default' => 0,
'condshow' => array( 'aiosp_can' => 'on' ),
),
'force_rewrites' => array(
/* translators: This is the name of a setting. Enabling this option forces the plugin to use output buffering to ensure that the title tag will be rewritten. */
'name' => __( 'Force Rewrites:', 'all-in-one-seo-pack' ),
'default' => 1,
'type' => 'hidden',
'prefix' => $this->prefix,
'initial_options' => array(
1 => __( 'Enabled', 'all-in-one-seo-pack' ),
0 => __( 'Disabled', 'all-in-one-seo-pack' ),
),
),
'use_original_title' => array(
/* translators: This is the name of a setting. Enabling this option forces the plugin to use the wp_title() function to fetch the title tag. */
'name' => __( 'Use Original Title:', 'all-in-one-seo-pack' ),
'type' => 'radio',
'default' => 0,
'initial_options' => array(
1 => __( 'Enabled', 'all-in-one-seo-pack' ),
0 => __( 'Disabled', 'all-in-one-seo-pack' ),
),
),
'home_page_title_format' => array(
/* translators: This is a setting where users can enter the title format for the homepage. The title format is the format All in One SEO Pack uses to rewrite the title tag. */
'name' => __( 'Home Page Title Format:', 'all-in-one-seo-pack' ),
'type' => 'text',
'default' => '%page_title%',
),
'page_title_format' => array(
/* translators: This is a setting where users can enter the title format for Pages. The title format is the format All in One SEO Pack uses to rewrite the title tag. */
'name' => __( 'Page Title Format:', 'all-in-one-seo-pack' ),
'type' => 'text',
'default' => '%page_title% | %site_title%',
),
'post_title_format' => array(
/* translators: This is a setting where users can enter the title format for Posts. The title format is the format All in One SEO Pack uses to rewrite the title tag. */
'name' => __( 'Post Title Format:', 'all-in-one-seo-pack' ),
'type' => 'text',
'default' => '%post_title% | %site_title%',
),
'category_title_format' => array(
/* translators: This is a setting where users can enter the title format for categories. The title format is the format All in One SEO Pack uses to rewrite the title tag. */
'name' => __( 'Category Title Format:', 'all-in-one-seo-pack' ),
'type' => 'text',
'default' => '%category_title% | %site_title%',
),
'archive_title_format' => array(
/* translators: This is a setting where users can enter the title format for archive pages. The title format is the format All in One SEO Pack uses to rewrite the title tag. */
'name' => __( 'Archive Title Format:', 'all-in-one-seo-pack' ),
'type' => 'text',
'default' => '%archive_title% | %site_title%',
),
'date_title_format' => array(
/* translators: This is a setting where users can enter the title format for date archive pages. The title format is the format All in One SEO Pack uses to rewrite the title tag. */
'name' => __( 'Date Archive Title Format:', 'all-in-one-seo-pack' ),
'type' => 'text',
'default' => '%date% | %site_title%',
),
'author_title_format' => array(
/* translators: This is a setting where users can enter the title format for author archive pages. The title format is the format All in One SEO Pack uses to rewrite the title tag. */
'name' => __( 'Author Archive Title Format:', 'all-in-one-seo-pack' ),
'type' => 'text',
'default' => '%author% | %site_title%',
),
'tag_title_format' => array(
/* translators: This is a setting where users can enter the title format for tag archive pages. The title format is the format All in One SEO Pack uses to rewrite the title tag. */
'name' => __( 'Tag Title Format:', 'all-in-one-seo-pack' ),
'type' => 'text',
'default' => '%tag% | %site_title%',
),
'search_title_format' => array(
/* translators: This is a setting where users can enter the title format for the search page. The title format is the format All in One SEO Pack uses to rewrite the title tag. */
'name' => __( 'Search Title Format:', 'all-in-one-seo-pack' ),
'type' => 'text',
'default' => '%search% | %site_title%',
),
'description_format' => array(
/* translators: This is a setting where users can enter the description format. The description format is the format All in One SEO Pack uses to rewrite the meta description tag. */
'name' => __( 'Description Format', 'all-in-one-seo-pack' ),
'type' => 'text',
'default' => '%description%',
),
'404_title_format' => array(
/* translators: This is a setting where users can enter the title format for the 404 page. The title format is the format All in One SEO Pack uses to rewrite the title tag. */
'name' => __( '404 Title Format:', 'all-in-one-seo-pack' ),
'type' => 'text',
'default' => __( 'Nothing found for %request_words%', 'all-in-one-seo-pack' ),
),
'paged_format' => array(
/* translators: This is a setting where users can enter the title format for paginated pages. The title format is the format All in One SEO Pack uses to rewrite the title tag. */
'name' => __( 'Paged Format:', 'all-in-one-seo-pack' ),
'type' => 'text',
'default' => sprintf( ' - %s %%page%%', __( 'Part', 'all-in-one-seo-pack' ) ),
),
'cpostactive' => array(
/* translators: This is a setting where users can indicate which post types they want to use All in One SEO Pack with. */
'name' => __( 'SEO on only these Content Types:', 'all-in-one-seo-pack' ),
'type' => 'multicheckbox',
'default' => array( 'post', 'page' ),
),
'taxactive' => array(
/* translators: This is a setting where users can indicate which taxonomies they want to use All in One SEO Pack with. */
'name' => __( 'SEO on only these taxonomies:', 'all-in-one-seo-pack' ),
'type' => 'multicheckbox',
'default' => array( 'category', 'post_tag' ),
),
'cpostnoindex' => array(
/* translators: This is a setting where users can indicate which post types they want to NOINDEX by default. NOINDEX is a value of the HTML robots meta tag that asks search engines not to index the page. */
'name' => __( 'Default to NOINDEX:', 'all-in-one-seo-pack' ),
'type' => 'multicheckbox',
'default' => array(),
),
'cpostnofollow' => array(
/* translators: This is a setting where users can indicate which post types they want to NOFOLLOW by default. NOFOLLOW is a value of the HTML robots meta tag that asks search engines not to follow any links on the page. */
'name' => __( 'Default to NOFOLLOW:', 'all-in-one-seo-pack' ),
'type' => 'multicheckbox',
'default' => array(),
),
'posttypecolumns' => array(
/* translators: This is a setting where users can indicate for which post types they want to enable columns. Columns are added to the All Posts, All Pages, etc. list pages and allow users to quick-edit their title and description - https://semperplugins.com/documentation/display-settings/#show-column-labels-for-custom-post-types. */
'name' => __( 'Show Column Labels for Custom Post Types:', 'all-in-one-seo-pack' ),
'type' => 'multicheckbox',
'default' => array( 'post', 'page' ),
),
'google_verify' => array(
/* translators: This is a setting where users can add their Google Search Console verification code. Leave this in English if there is no translation for "Google Search Console". */
'name' => __( 'Google Search Console:', 'all-in-one-seo-pack' ),
'default' => '',
'type' => 'text',
),
'bing_verify' => array(
/* translators: This is a setting where users can add their Bing Webmaster Tools verification code. Leave this in English if there is no translation for "Bing Webmaster Tools". */
'name' => __( 'Bing Webmaster Tools:', 'all-in-one-seo-pack' ),
'default' => '',
'type' => 'text',
),
'pinterest_verify' => array(
/* translators: This is a setting where users can add their Pinterest website verification code. */
'name' => __( 'Pinterest Site Verification:', 'all-in-one-seo-pack' ),
'default' => '',
'type' => 'text',
),
'yandex_verify' => array(
/* translators: This is a setting where users can add their Yandex Webmaster Tools verification code. Leave this in English if there is no translation for "Yandex Webmaster Tools". */
'name' => __( 'Yandex Webmaster Tools:', 'all-in-one-seo-pack' ),
'default' => '',
'type' => 'text',
),
'baidu_verify' => array(
/* translators: This is a setting where users can add their Baidu Webmaster Tools verification code. Leave this in English if there is no translation for "Baidu Webmaster Tools". */
'name' => __( 'Baidu Webmaster Tools:', 'all-in-one-seo-pack' ),
'default' => '',
'type' => 'text',
),
'google_sitelinks_search' => array(
/* translators: This is a setting users can enable to add the basic markup code to their source code that is needed for Google to generate a Sitelinks Search Box - https://developers.google.com/search/docs/data-types/sitelinks-searchbox.*/
'name' => __( 'Display Sitelinks Search Box:', 'all-in-one-seo-pack' ),
),
// "google_connect"=>array( 'name' => __( 'Connect With Google Analytics', 'all-in-one-seo-pack' ), ),
'google_analytics_id' => array(
/* translators: This is a setting where users can add their Google Analytics verification code. Leave this in English if there is no translation for "Google Analytics". */
'name' => __( 'Google Analytics ID:', 'all-in-one-seo-pack' ),
'default' => null,
'type' => 'text',
'placeholder' => 'UA-########-#',
),
'ga_advanced_options' => array(
/* translators: This is a setting users can enable to display more advanced options for Google Analytics. */
'name' => __( 'Advanced Analytics Options:', 'all-in-one-seo-pack' ),
'default' => 'on',
'type' => 'radio',
'initial_options' => array(
'on' => __( 'Enabled', 'all-in-one-seo-pack' ),
0 => __( 'Disabled', 'all-in-one-seo-pack' ),
),
'condshow' => array(
'aiosp_google_analytics_id' => array(
'lhs' => 'aiosp_google_analytics_id',
'op' => '!=',
'rhs' => '',
),
),
),
'ga_domain' => array(
/* translators: This is a setting which allows users to set the cookie domain for their Google Analytics tracking code. */
'name' => __( 'Tracking Domain:', 'all-in-one-seo-pack' ),
'type' => 'text',
'condshow' => array(
'aiosp_google_analytics_id' => array(
'lhs' => 'aiosp_google_analytics_id',
'op' => '!=',
'rhs' => '',
),
'aiosp_ga_advanced_options' => 'on',
),
),
'ga_multi_domain' => array(
/* translators: This is a setting which allows users to enable Google Analytics tracking for multiple domain names. */
'name' => __( 'Track Multiple Domains:', 'all-in-one-seo-pack' ),
'default' => 0,
'condshow' => array(
'aiosp_google_analytics_id' => array(
'lhs' => 'aiosp_google_analytics_id',
'op' => '!=',
'rhs' => '',
),
'aiosp_ga_advanced_options' => 'on',
),
),
'ga_addl_domains' => array(
/* translators: This is a setting which allows users to enter additional domain names used for Google Analytics cross-domain tracking - https://support.google.com/analytics/answer/1034342?hl=en.*/
'name' => __( 'Additional Domains:', 'all-in-one-seo-pack' ),
'type' => 'textarea',
'condshow' => array(
'aiosp_google_analytics_id' => array(
'lhs' => 'aiosp_google_analytics_id',
'op' => '!=',
'rhs' => '',
),
'aiosp_ga_advanced_options' => 'on',
'aiosp_ga_multi_domain' => 'on',
),
),
'ga_anonymize_ip' => array(
/* translators: This is a setting which tells Google Analytics not to track and store the IP addresses of website visitors. This is required to be compliant with the GDPR for example. */
'name' => __( 'Anonymize IP Addresses:', 'all-in-one-seo-pack' ),
'type' => 'checkbox',
'condshow' => array(
'aiosp_google_analytics_id' => array(
'lhs' => 'aiosp_google_analytics_id',
'op' => '!=',
'rhs' => '',
),
'aiosp_ga_advanced_options' => 'on',
),
),
'ga_display_advertising' => array(
'name' => __( 'Display Advertiser Tracking:', 'all-in-one-seo-pack' ),
'type' => 'checkbox',
'condshow' => array(
'aiosp_google_analytics_id' => array(
'lhs' => 'aiosp_google_analytics_id',
'op' => '!=',
'rhs' => '',
),
'aiosp_ga_advanced_options' => 'on',
),
),
'ga_exclude_users' => array(
'name' => __( 'Exclude Users From Tracking:', 'all-in-one-seo-pack' ),
'type' => 'multicheckbox',
'condshow' => array(
'aiosp_google_analytics_id' => array(
'lhs' => 'aiosp_google_analytics_id',
'op' => '!=',
'rhs' => '',
),
'aiosp_ga_advanced_options' => 'on',
),
),
'ga_track_outbound_links' => array(
'name' => __( 'Track Outbound Links:', 'all-in-one-seo-pack' ),
'default' => 0,
'condshow' => array(
'aiosp_google_analytics_id' => array(
'lhs' => 'aiosp_google_analytics_id',
'op' => '!=',
'rhs' => '',
),
'aiosp_ga_advanced_options' => 'on',
),
),
'ga_link_attribution' => array(
'name' => __( 'Enhanced Link Attribution:', 'all-in-one-seo-pack' ),
'default' => 0,
'condshow' => array(
'aiosp_google_analytics_id' => array(
'lhs' => 'aiosp_google_analytics_id',
'op' => '!=',
'rhs' => '',
),
'aiosp_ga_advanced_options' => 'on',
),
),
'ga_enhanced_ecommerce' => array(
'name' => __( 'Enhanced Ecommerce:', 'all-in-one-seo-pack' ),
'default' => 0,
'condshow' => array(
'aiosp_google_analytics_id' => array(
'lhs' => 'aiosp_google_analytics_id',
'op' => '!=',
'rhs' => '',
),
'aiosp_ga_advanced_options' => 'on',
),
),
'use_categories' => array(
'name' => __( 'Use Categories for META keywords:', 'all-in-one-seo-pack' ),
'default' => 0,
'condshow' => array( 'aiosp_togglekeywords' => 0 ),
),
'use_tags_as_keywords' => array(
'name' => __( 'Use Tags for META keywords:', 'all-in-one-seo-pack' ),
'default' => 1,
'condshow' => array( 'aiosp_togglekeywords' => 0 ),
),
'dynamic_postspage_keywords' => array(
'name' => __( 'Dynamically Generate Keywords for Posts Page/Archives:', 'all-in-one-seo-pack' ),
'default' => 1,
'condshow' => array( 'aiosp_togglekeywords' => 0 ),
),
'category_noindex' => array(
'name' => __( 'Use noindex for Categories:', 'all-in-one-seo-pack' ),
'default' => 1,
),
'archive_date_noindex' => array(
'name' => __( 'Use noindex for Date Archives:', 'all-in-one-seo-pack' ),
'default' => 1,
),
'archive_author_noindex' => array(
'name' => __( 'Use noindex for Author Archives:', 'all-in-one-seo-pack' ),
'default' => 1,
),
'tags_noindex' => array(
'name' => __( 'Use noindex for Tag Archives:', 'all-in-one-seo-pack' ),
'default' => 0,
),
'search_noindex' => array(
'name' => __( 'Use noindex for the Search page:', 'all-in-one-seo-pack' ),
'default' => 0,
),
'404_noindex' => array(
'name' => __( 'Use noindex for the 404 page:', 'all-in-one-seo-pack' ),
'default' => 0,
),
'tax_noindex' => array(
'name' => __( 'Use noindex for Taxonomy Archives:', 'all-in-one-seo-pack' ),
'type' => 'multicheckbox',
'default' => array(),
),
'paginated_noindex' => array(
'name' => __( 'Use noindex for paginated pages/posts:', 'all-in-one-seo-pack' ),
'default' => 0,
),
'paginated_nofollow' => array(
'name' => __( 'Use nofollow for paginated pages/posts:', 'all-in-one-seo-pack' ),
'default' => 0,
),
'generate_descriptions' => array(
'name' => __( 'Autogenerate Descriptions:', 'all-in-one-seo-pack' ),
'default' => 0,
),
'skip_excerpt' => array(
'name' => __( 'Use Content For Autogenerated Descriptions:', 'all-in-one-seo-pack' ),
'default' => 0,
'condshow' => array( 'aiosp_generate_descriptions' => 'on' ),
),
'run_shortcodes' => array(
'name' => __( 'Run Shortcodes In Autogenerated Descriptions:', 'all-in-one-seo-pack' ),
'default' => 0,
'condshow' => array( 'aiosp_generate_descriptions' => 'on' ),
),
'hide_paginated_descriptions' => array(
'name' => __( 'Remove Descriptions For Paginated Pages:', 'all-in-one-seo-pack' ),
'default' => 0,
),
'dont_truncate_descriptions' => array(
'name' => __( 'Never Shorten Long Descriptions:', 'all-in-one-seo-pack' ),
'default' => 0,
),
'schema_markup' => array(
'name' => __( 'Use Schema.org Markup', 'all-in-one-seo-pack' ),
'default' => 1,
),
'unprotect_meta' => array(
'name' => __( 'Unprotect Post Meta Fields:', 'all-in-one-seo-pack' ),
'default' => 0,
),
'redirect_attachement_parent' => array(
'name' => __( 'Redirect Attachments to Post Parent:', 'all-in-one-seo-pack' ),
'default' => 0,
),
'ex_pages' => array(
'name' => __( 'Exclude Pages:', 'all-in-one-seo-pack' ),
'type' => 'textarea',
'default' => '',
),
'post_meta_tags' => array(
'name' => __( 'Additional Post Headers:', 'all-in-one-seo-pack' ),
'type' => 'textarea',
'default' => '',
'sanitize' => 'default',
),
'page_meta_tags' => array(
'name' => __( 'Additional Page Headers:', 'all-in-one-seo-pack' ),
'type' => 'textarea',
'default' => '',
'sanitize' => 'default',
),
'front_meta_tags' => array(
'name' => __( 'Additional Front Page Headers:', 'all-in-one-seo-pack' ),
'type' => 'textarea',
'default' => '',
'sanitize' => 'default',
),
'home_meta_tags' => array(
'name' => __( 'Additional Posts Page Headers:', 'all-in-one-seo-pack' ),
'type' => 'textarea',
'default' => '',
'sanitize' => 'default',
),
'do_log' => array(
'name' => __( 'Log important events:', 'all-in-one-seo-pack' ),
'default' => null,
),
);
if ( ! AIOSEOPPRO ) {
unset( $this->default_options['license_key'] );
unset( $this->default_options['taxactive'] );
}
$this->locations = array(
'default' => array(
'name' => $this->name,
'prefix' => 'aiosp_',
'type' => 'settings',
'options' => null,
),
'aiosp' => array(
'name' => $this->plugin_name,
'type' => 'metabox',
'prefix' => '',
'help_link' => 'https://semperplugins.com/documentation/post-settings/',
'options' => array(
'edit',
'nonce-aioseop-edit',
AIOSEOPPRO ? 'support' : 'upgrade',
'snippet',
'title',
'description',
'keywords',
'custom_link',
'noindex',
'nofollow',
'sitemap_exclude',
'disable',
'disable_analytics',
),
'default_options' => array(
'edit' => array(
'type' => 'hidden',
'default' => 'aiosp_edit',
'prefix' => true,
'nowrap' => 1,
),
'nonce-aioseop-edit' => array(
'type' => 'hidden',
'default' => null,
'prefix' => false,
'nowrap' => 1,
),
'upgrade' => array(
'type' => 'html',
'label' => 'none',
'default' => aiosp_common::get_upgrade_hyperlink( 'meta', sprintf( '%1$s %2$s Pro', __( 'Upgrade to', 'all-in-one-seo-pack' ), AIOSEOP_PLUGIN_NAME ), __( 'UPGRADE TO PRO VERSION', 'all-in-one-seo-pack' ), '_blank' ),
),
'support' => array(
'type' => 'html',
'label' => 'none',
'default' => '' . __( 'Support Forum', 'all-in-one-seo-pack' ) . '',
),
'snippet' => array(
'name' => __( 'Preview Snippet', 'all-in-one-seo-pack' ),
'type' => 'custom',
'label' => 'top',
'default' => '
' . __( 'Review Your Settings', 'all-in-one-seo-pack' )
. '
' . sprintf( __( 'Welcome to version %1$s. Thank you for running the latest and greatest %2$s ever! Please review your settings, as we\'re always adding new features for you!', 'all-in-one-seo-pack' ), AIOSEOP_VERSION, AIOSEOP_PLUGIN_NAME ) . '
',
'pointer_edge' => 'top',
'pointer_align' => 'left',
'pointer_scope' => 'global',
);
$this->filter_pointers();
}
*/
/**
* Add Page Hooks
*
* @since ?
*/
function add_page_hooks() {
global $aioseop_options;
$post_objs = get_post_types( '', 'objects' );
$pt = array_keys( $post_objs );
$rempost = array( 'revision', 'nav_menu_item', 'custom_css', 'customize_changeset' ); // Don't show these built-in types as options for CPT SEO.
$pt = array_diff( $pt, $rempost );
$post_types = array();
foreach ( $pt as $p ) {
if ( ! empty( $post_objs[ $p ]->label ) ) {
$post_types[ $p ] = $post_objs[ $p ]->label;
} else {
$post_types[ $p ] = $p;
}
}
foreach ( $pt as $p ) {
if ( ! empty( $post_objs[ $p ]->label ) ) {
$all_post_types[ $p ] = $post_objs[ $p ]->label;
}
}
if ( isset( $post_types['attachment'] ) ) {
$post_types['attachment'] = __( 'Media / Attachments', 'all-in-one-seo-pack' );
}
if ( isset( $all_post_types['attachment'] ) ) {
$all_post_types['attachment'] = __( 'Media / Attachments', 'all-in-one-seo-pack' );
}
$taxes = get_taxonomies( '', 'objects' );
$tx = array_keys( $taxes );
$remtax = array( 'nav_menu', 'link_category', 'post_format' );
$tx = array_diff( $tx, $remtax );
$tax_types = array();
foreach ( $tx as $t ) {
if ( ! empty( $taxes[ $t ]->label ) ) {
$tax_types[ $t ] = $taxes[ $t ]->label;
} else {
$taxes[ $t ] = $t;
}
}
/**
* Allows users to filter the taxonomies that are shown in the General Settings menu.
*
* @since 3.0.0
*
* @param array $tax_types All registered taxonomies.
*/
$tax_types = apply_filters( 'aioseop_pre_tax_types_setting', $tax_types );
$this->default_options['posttypecolumns']['initial_options'] = $post_types;
$this->default_options['cpostactive']['initial_options'] = $all_post_types;
$this->default_options['cpostnoindex']['initial_options'] = $post_types;
$this->default_options['cpostnofollow']['initial_options'] = $post_types;
if ( AIOSEOPPRO ) {
$this->default_options['taxactive']['initial_options'] = $tax_types;
}
foreach ( $all_post_types as $p => $pt ) {
$field = $p . '_title_format';
$name = $post_objs[ $p ]->labels->singular_name;
if ( ! isset( $this->default_options[ $field ] ) ) {
$this->default_options[ $field ] = array(
'name' => "$name " . __( 'Title Format:', 'all-in-one-seo-pack' ) . " ($p)",
'type' => 'text',
'default' => '%post_title% | %site_title%',
'condshow' => array(
'aiosp_cpostactive\[\]' => $p,
),
);
$this->layout['cpt']['options'][] = $field;
}
}
global $wp_roles;
if ( ! isset( $wp_roles ) ) {
$wp_roles = new WP_Roles();
}
$role_names = $wp_roles->get_names();
ksort( $role_names );
$this->default_options['ga_exclude_users']['initial_options'] = $role_names;
unset( $tax_types['category'] );
unset( $tax_types['post_tag'] );
$this->default_options['tax_noindex']['initial_options'] = $tax_types;
if ( empty( $tax_types ) ) {
unset( $this->default_options['tax_noindex'] );
}
if ( AIOSEOPPRO ) {
foreach ( $tax_types as $p => $pt ) {
$field = $p . '_tax_title_format';
$name = $pt;
if ( ! isset( $this->default_options[ $field ] ) ) {
$this->default_options[ $field ] = array(
'name' => "$name " . __( 'Taxonomy Title Format:', 'all-in-one-seo-pack' ),
'type' => 'text',
'default' => '%taxonomy_title% | %site_title%',
'condshow' => array(
'aiosp_taxactive\[\]' => $p,
),
);
$this->layout['cpt']['options'][] = $field;
}
}
}
$this->setting_options();
if ( AIOSEOPPRO ) {
global $aioseop_update_checker;
add_action( "{$this->prefix}update_options", array( $aioseop_update_checker, 'license_change_check' ), 10, 2 );
add_action( "{$this->prefix}settings_update", array( $aioseop_update_checker, 'update_check' ), 10, 2 );
}
add_filter( "{$this->prefix}display_options", array( $this, 'filter_options' ), 10, 2 );
parent::add_page_hooks();
}
function settings_page_init() {
add_filter( "{$this->prefix}submit_options", array( $this, 'filter_submit' ) );
}
/**
* Admin Enqueue Styles All (Screens)
*
* Enqueue style on all admin screens.
*
* @since 2.9
*
* @param $hook_suffix
*/
public function admin_enqueue_styles_all( $hook_suffix ) {
wp_enqueue_style(
'aiosp_admin_style',
AIOSEOP_PLUGIN_URL . 'css/aiosp_admin.css',
array(),
AIOSEOP_VERSION
);
}
/**
* Admin Enqueue Scripts
*
* @since 2.5.0
* @since 2.9 Refactor code to `admin_enqueue_scripts` hook, and move enqueue stylesheet to \All_in_One_SEO_Pack::admin_enqueue_styles_all().
*
* @uses All_in_One_SEO_Pack_Module::admin_enqueue_scripts();
*
* @param string $hook_suffix
*/
public function admin_enqueue_scripts( $hook_suffix ) {
add_filter( "{$this->prefix}display_settings", array( $this, 'filter_settings' ), 10, 3 );
add_filter( "{$this->prefix}display_options", array( $this, 'filter_options' ), 10, 2 );
// This ensures different JS files are enqueued only at the intended screens. Preventing unnecessary processes.
$extra_title_len = 0;
switch ( $hook_suffix ) {
// Screens `post.php`, `post-new.php`, & `../aioseop_class.php` share the same `count-char.js`.
case 'post.php':
case 'post-new.php':
$info = $this->get_page_snippet_info();
$title = $info['title'];
$title_format = $this->get_title_format( array( 'name' => 'aiosp_snippet' ) );
if ( ! empty( $title_format ) ) {
$replace_title = '' . esc_attr( wp_strip_all_tags( html_entity_decode( $title ) ) ) . '';
$extra_title_len = strlen( $this->html_entity_decode( str_replace( $replace_title, '', $title_format ) ) );
}
// Fall through.
case 'toplevel_page_' . AIOSEOP_PLUGIN_DIRNAME . '/aioseop_class':
wp_enqueue_script(
'aioseop-post-edit-script',
AIOSEOP_PLUGIN_URL . 'js/count-chars.js',
array(),
AIOSEOP_VERSION
);
$localize_post_edit = array(
'aiosp_title_extra' => (int) $extra_title_len,
);
wp_localize_script( 'aioseop-post-edit-script', 'aioseop_count_chars', $localize_post_edit );
break;
}
parent::admin_enqueue_scripts( $hook_suffix );
}
/**
* Filter Submit
*
* @since ?
*
* @param $submit
* @return mixed
*/
function filter_submit( $submit ) {
$submit['Submit_Default'] = array(
'type' => 'submit',
'class' => 'aioseop_reset_settings_button button-secondary',
'value' => __( 'Reset General Settings to Defaults', 'all-in-one-seo-pack' ) . ' »',
);
$submit['Submit_All_Default'] = array(
'type' => 'submit',
'class' => 'aioseop_reset_settings_button button-secondary',
'value' => __( 'Reset ALL Settings to Defaults', 'all-in-one-seo-pack' ) . ' »',
);
return $submit;
}
/**
* Reset Options
*
* Handle resetting options to defaults, but preserve the license key if pro.
*
* @since ?
*
* @param null $location
* @param bool $delete
*/
function reset_options( $location = null, $delete = false ) {
if ( AIOSEOPPRO ) {
global $aioseop_update_checker;
}
if ( $delete === true ) {
if ( AIOSEOPPRO ) {
$license_key = '';
if ( isset( $this->options ) && isset( $this->options['aiosp_license_key'] ) ) {
$license_key = $this->options['aiosp_license_key'];
}
}
$this->delete_class_option( $delete );
if ( AIOSEOPPRO ) {
$this->options = array( 'aiosp_license_key' => $license_key );
} else {
$this->options = array();
}
}
$default_options = $this->default_options( $location );
if ( AIOSEOPPRO ) {
foreach ( $default_options as $k => $v ) {
if ( $k != 'aiosp_license_key' ) {
$this->options[ $k ] = $v;
}
}
$aioseop_update_checker->license_key = $this->options['aiosp_license_key'];
} else {
foreach ( $default_options as $k => $v ) {
$this->options[ $k ] = $v;
}
}
$this->update_class_option( $this->options );
}
/**
* Filter Settings
*
* @since ?
* @since 2.3.16 Forces HTML entity decode on placeholder values.
*
* @param $settings
* @param $location
* @param $current
* @return mixed
*/
function filter_settings( $settings, $location, $current ) {
if ( $location == null ) {
$prefix = $this->prefix;
foreach ( array( 'seopostcol', 'seocustptcol', 'debug_info', 'max_words_excerpt' ) as $opt ) {
unset( $settings[ "{$prefix}$opt" ] );
}
if ( ! class_exists( 'DOMDocument' ) ) {
unset( $settings['{prefix}google_connect'] );
}
if ( AIOSEOPPRO ) {
if ( ! empty( $this->options['aiosp_license_key'] ) ) {
$settings['aiosp_license_key']['type'] = 'password';
$settings['aiosp_license_key']['size'] = 38;
}
}
} elseif ( $location == 'aiosp' ) {
global $post, $aioseop_sitemap;
$prefix = $this->get_prefix( $location ) . $location . '_';
if ( ! empty( $post ) ) {
$post_type = get_post_type( $post );
if ( ! empty( $this->options['aiosp_cpostnoindex'] ) && in_array( $post_type, $this->options['aiosp_cpostnoindex'] ) ) {
$settings[ "{$prefix}noindex" ]['type'] = 'select';
$settings[ "{$prefix}noindex" ]['initial_options'] = array(
'' => __( 'Default - noindex', 'all-in-one-seo-pack' ),
'off' => __( 'index', 'all-in-one-seo-pack' ),
'on' => __( 'noindex', 'all-in-one-seo-pack' ),
);
}
if ( ! empty( $this->options['aiosp_cpostnofollow'] ) && in_array( $post_type, $this->options['aiosp_cpostnofollow'] ) ) {
$settings[ "{$prefix}nofollow" ]['type'] = 'select';
$settings[ "{$prefix}nofollow" ]['initial_options'] = array(
'' => __( 'Default - nofollow', 'all-in-one-seo-pack' ),
'off' => __( 'follow', 'all-in-one-seo-pack' ),
'on' => __( 'nofollow', 'all-in-one-seo-pack' ),
);
}
global $post;
$info = $this->get_page_snippet_info();
$title = $info['title'];
$description = $info['description'];
$keywords = $info['keywords'];
$settings[ "{$prefix}title" ]['placeholder'] = $this->html_entity_decode( $title );
$settings[ "{$prefix}description" ]['placeholder'] = $this->html_entity_decode( $description );
$settings[ "{$prefix}keywords" ]['placeholder'] = $keywords;
}
if ( ! AIOSEOPPRO ) {
if ( ! current_user_can( 'update_plugins' ) ) {
unset( $settings[ "{$prefix}upgrade" ] );
}
}
if ( ! is_object( $aioseop_sitemap ) ) {
unset( $settings['aiosp_sitemap_exclude'] );
}
if ( ! empty( $this->options[ $this->prefix . 'togglekeywords' ] ) ) {
unset( $settings[ "{$prefix}keywords" ] );
unset( $settings[ "{$prefix}togglekeywords" ] );
} elseif ( ! empty( $current[ "{$prefix}togglekeywords" ] ) ) {
unset( $settings[ "{$prefix}keywords" ] );
}
if ( empty( $this->options['aiosp_can'] ) ) {
unset( $settings[ "{$prefix}custom_link" ] );
}
}
return $settings;
}
/**
* Filter Options
*
* @since ?
*
* @param $options
* @param $location
* @return mixed
*/
function filter_options( $options, $location ) {
if ( $location == 'aiosp' ) {
global $post;
if ( ! empty( $post ) ) {
$prefix = $this->prefix;
$post_type = get_post_type( $post );
foreach ( array( 'noindex', 'nofollow' ) as $no ) {
if ( empty( $this->options[ 'aiosp_cpost' . $no ] ) || ( ! in_array( $post_type, $this->options[ 'aiosp_cpost' . $no ] ) ) ) {
if ( isset( $options[ "{$prefix}{$no}" ] ) && ( $options[ "{$prefix}{$no}" ] != 'on' ) ) {
unset( $options[ "{$prefix}{$no}" ] );
}
}
}
}
}
if ( $location == null ) {
$prefix = $this->prefix;
if ( isset( $options[ "{$prefix}use_original_title" ] ) && ( $options[ "{$prefix}use_original_title" ] === '' ) ) {
$options[ "{$prefix}use_original_title" ] = 0;
}
}
return $options;
}
/**
* Template Redirect
*
* @since ?
*/
function template_redirect() {
global $aioseop_options;
$post = $this->get_queried_object();
if ( ! $this->is_page_included() ) {
return;
}
$force_rewrites = 1;
if ( isset( $aioseop_options['aiosp_force_rewrites'] ) ) {
$force_rewrites = $aioseop_options['aiosp_force_rewrites'];
}
if ( $force_rewrites ) {
ob_start( array( $this, 'output_callback_for_title' ) );
} else {
add_filter( 'wp_title', array( $this, 'wp_title' ), 20 );
}
}
/**
* Is Page Included
*
* @since ?
*
* @return bool
*/
function is_page_included() {
global $aioseop_options;
if ( is_feed() ) {
return false;
}
if ( aioseop_mrt_exclude_this_page() ) {
return false;
}
$post = $this->get_queried_object();
$post_type = '';
if ( ! empty( $post ) && ! empty( $post->post_type ) ) {
$post_type = $post->post_type;
}
$wp_post_types = $aioseop_options['aiosp_cpostactive'];
if ( empty( $wp_post_types ) ) {
$wp_post_types = array();
}
if ( AIOSEOPPRO ) {
if ( is_tax() ) {
if ( empty( $aioseop_options['aiosp_taxactive'] ) || ! is_tax( $aioseop_options['aiosp_taxactive'] ) ) {
return false;
}
} elseif ( is_category() ) {
if ( empty( $aioseop_options['aiosp_taxactive'] ) || ! in_array( 'category', $aioseop_options['aiosp_taxactive'] ) ) {
return false;
}
} elseif ( is_tag() ) {
if ( empty( $aioseop_options['aiosp_taxactive'] ) || ! in_array( 'post_tag', $aioseop_options['aiosp_taxactive'] ) ) {
return false;
}
} elseif ( ! in_array( $post_type, $wp_post_types ) && ! is_front_page() && ! is_post_type_archive( $wp_post_types ) && ! is_404() ) {
return false;
}
} else {
if ( is_singular() && ! in_array( $post_type, $wp_post_types ) && ! is_front_page() ) {
return false;
}
if ( is_post_type_archive() && ! is_post_type_archive( $wp_post_types ) ) {
return false;
}
}
$this->meta_opts = $this->get_current_options( array(), 'aiosp' );
$aiosp_disable = $aiosp_disable_analytics = false;
if ( ! empty( $this->meta_opts ) ) {
if ( isset( $this->meta_opts['aiosp_disable'] ) ) {
$aiosp_disable = $this->meta_opts['aiosp_disable'];
}
if ( isset( $this->meta_opts['aiosp_disable_analytics'] ) ) {
$aiosp_disable_analytics = $this->meta_opts['aiosp_disable_analytics'];
}
}
$aiosp_disable = apply_filters( 'aiosp_disable', $aiosp_disable ); // API filter to disable AIOSEOP.
if ( $aiosp_disable ) {
if ( ! $aiosp_disable_analytics ) {
if ( aioseop_option_isset( 'aiosp_google_analytics_id' ) ) {
remove_action( 'aioseop_modules_wp_head', array( $this, 'aiosp_google_analytics' ) );
add_action( 'wp_head', array( $this, 'aiosp_google_analytics' ) );
}
}
return false;
}
if ( ! empty( $this->meta_opts ) && $this->meta_opts['aiosp_disable'] == true ) {
return false;
}
return true;
}
/**
* Output Callback for Title
*
* @since ?
*
* @param $content
* @return mixed|string
*/
function output_callback_for_title( $content ) {
return $this->rewrite_title( $content );
}
/**
* Rewrite Title
*
* Used for forcing title rewrites.
*
* @since ?
*
* @param $header
* @return mixed|string
*/
function rewrite_title( $header ) {
global $wp_query;
if ( ! $wp_query ) {
$header .= "\n";
return $header;
}
// Check if we're in the main query to support bad themes and plugins.
$old_wp_query = null;
if ( ! $wp_query->is_main_query() ) {
$old_wp_query = $wp_query;
wp_reset_query();
}
$title = $this->wp_title();
if ( ! empty( $title ) ) {
$header = $this->replace_title( $header, $title );
}
if ( ! empty( $old_wp_query ) ) {
$GLOBALS['wp_query'] = $old_wp_query;
// Change the query back after we've finished.
unset( $old_wp_query );
}
return $header;
}
/**
* Replace Title
*
* @since ?
*
* @param $content
* @param $title
* @return mixed
*/
function replace_title( $content, $title ) {
// We can probably improve this... I'm not sure half of this is even being used.
$title = trim( strip_tags( $title ) );
$title_tag_start = 'strpos( $content, $title_tag_start, 0 );
$end = $this->strpos( $content, $title_tag_end, 0 );
$this->title_start = $start;
$this->title_end = $end;
$this->orig_title = $title;
return preg_replace( '/]*?)\s*>([^<]*?)<\/title\s*>/is', '' . preg_replace( '/(\$|\\\\)(?=\d)/', '\\\\\1', strip_tags( $title ) ) . '', $content, 1 );
}
/**
* Add Hooks
*
* Adds WordPress hooks.
*
* @since ?
* @since 2.3.13 #899 Adds filter:aioseop_description.
* @since 2.3.14 #593 Adds filter:aioseop_title.
* @since 2.4 #951 Increases filter:aioseop_description arguments number.
*/
function add_hooks() {
global $aioseop_options, $aioseop_update_checker;
if ( is_admin() ) {
// this checks if the settiongs options exist and if they dont, it sets the defaults.
// let's do this only in backend.
aioseop_update_settings_check();
}
add_filter( 'user_contactmethods', 'aioseop_add_contactmethods' );
if ( is_user_logged_in() && is_admin_bar_showing() && current_user_can( 'aiosp_manage_seo' ) ) {
add_action( 'admin_bar_menu', array( $this, 'admin_bar_menu' ), 1000 );
}
if ( is_admin() ) {
if ( is_multisite() ) {
add_action( 'network_admin_menu', array( $this, 'admin_menu' ) );
}
add_action( 'admin_menu', array( $this, 'admin_menu' ) );
add_action( 'admin_head', array( $this, 'add_page_icon' ) );
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_styles_all' ) );
add_action( 'admin_init', 'aioseop_addmycolumns', 1 );
add_action( 'admin_init', 'aioseop_handle_ignore_notice' );
add_action( 'shutdown', array( $this, 'check_recently_activated_modules' ), 99 );
if ( AIOSEOPPRO ) {
if ( current_user_can( 'update_plugins' ) ) {
add_action( 'admin_notices', array( $aioseop_update_checker, 'key_warning' ) );
}
add_action( 'after_plugin_row_' . AIOSEOP_PLUGIN_BASENAME, array( $aioseop_update_checker, 'add_plugin_row' ) );
}
} else {
if ( $aioseop_options['aiosp_can'] == '1' || $aioseop_options['aiosp_can'] == 'on' ) {
remove_action( 'wp_head', 'rel_canonical' );
}
// Analytics.
if ( aioseop_option_isset( 'aiosp_google_analytics_id' ) ) {
add_action( 'aioseop_modules_wp_head', array( $this, 'aiosp_google_analytics' ) );
}
add_action( 'wp_head', array( $this, 'wp_head' ), apply_filters( 'aioseop_wp_head_priority', 1 ) );
add_action( 'amp_post_template_head', array( $this, 'amp_head' ), 11 );
add_action( 'template_redirect', array( $this, 'template_redirect' ), 0 );
}
add_filter( 'aioseop_description', array( &$this, 'filter_description' ), 10, 3 );
add_filter( 'aioseop_title', array( &$this, 'filter_title' ) );
}
/**
* Visibility Warning
*
* Checks if 'Search Engine Visibility' is enabled in Settings > Reading.
*
* @todo Change to earlier hook. Before `admin_enqueue` if possible.
*
* @since ?
* @since 3.0 Changed to AIOSEOP_Notices class.
*
* @see `self::constructor()` with 'all_admin_notices' Filter Hook
*/
function visibility_warning() {
global $aioseop_notices;
if ( '0' === get_option( 'blog_public' ) ) {
$aioseop_notices->activate_notice( 'blog_public_disabled' );
} elseif ( '1' === get_option( 'blog_public' ) ) {
$aioseop_notices->deactivate_notice( 'blog_public_disabled' );
}
}
/**
* WooCommerce Upgrade Notice
*
* @since ?
* @since 3.0 Changed to AIOSEOP Notices.
*/
public function woo_upgrade_notice() {
global $aioseop_notices;
if ( class_exists( 'WooCommerce' ) && ! AIOSEOPPRO ) {
$aioseop_notices->activate_notice( 'woocommerce_detected' );
} else {
global $aioseop_notices;
$aioseop_notices->deactivate_notice( 'woocommerce_detected' );
}
}
/**
* Make Unique Attachment Description
*
* @since ?
*
* @param $description
* @return string
*/
function make_unique_att_desc( $description ) {
global $wp_query;
if ( is_attachment() ) {
$url = $this->aiosp_mrt_get_url( $wp_query );
$unique_desc = '';
if ( $url ) {
$matches = array();
preg_match_all( '/(\d+)/', $url, $matches );
if ( is_array( $matches ) ) {
$unique_desc = join( '', $matches[0] );
}
}
$description .= ' ' . $unique_desc;
}
return $description;
}
/**
* AMP Head
*
* Adds meta description to AMP pages.
*
* @todo Change void returns to empty string returns.
*
* @since 2.3.11.5
*
* @return string|void
*/
function amp_head() {
if ( ! $this->is_seo_enabled_for_cpt() ) {
return;
}
$post = $this->get_queried_object();
$description = apply_filters( 'aioseop_amp_description', $this->get_main_description( $post ) ); // Get the description.
// To disable AMP meta description just __return_false on the aioseop_amp_description filter.
if ( isset( $description ) && false == $description ) {
return;
}
global $aioseop_options;
// Handle the description format.
if ( isset( $description ) && ( $this->strlen( $description ) > $this->minimum_description_length ) && ! ( is_front_page() && is_paged() ) ) {
$description = $this->trim_description( $description );
if ( ! isset( $meta_string ) ) {
$meta_string = '';
}
// Description format.
$description = apply_filters( 'aioseop_amp_description_full', $this->apply_description_format( $description, $post ) );
$desc_attr = '';
if ( ! empty( $aioseop_options['aiosp_schema_markup'] ) ) {
$desc_attr = '';
}
$desc_attr = apply_filters( 'aioseop_amp_description_attributes', $desc_attr );
$meta_string .= sprintf( "\n", $desc_attr, $description );
}
if ( ! empty( $meta_string ) ) {
echo $meta_string;
}
}
/**
* Is SEO Enabled for CPT
*
* Checks whether the current CPT should show the SEO tags.
*
* @since 2.9
*
* @todo Remove this as it is only a simple boolean check.
*
* @return bool
*/
private function is_seo_enabled_for_cpt() {
global $aioseop_options;
return empty( $post_type ) || in_array( get_post_type(), $aioseop_options['aiosp_cpostactive'], true );
}
/**
* WP Head
*
* @since ?
* @since 2.3.14 #932 Removes filter "aioseop_description".
*/
function wp_head() {
// Check if we're in the main query to support bad themes and plugins.
global $wp_query;
$old_wp_query = null;
if ( ! $wp_query->is_main_query() ) {
$old_wp_query = $wp_query;
wp_reset_query();
}
if ( ! $this->is_page_included() ) {
// Handle noindex, nofollow - robots meta.
$robots_meta = apply_filters( 'aioseop_robots_meta', $this->get_robots_meta() );
if ( ! empty( $robots_meta ) ) {
// Should plugin & version details be added here as well?
echo '' . "\n";
}
if ( ! empty( $old_wp_query ) ) {
// Change the query back after we've finished.
$GLOBALS['wp_query'] = $old_wp_query;
unset( $old_wp_query );
}
return;
}
if ( ! $this->is_seo_enabled_for_cpt() ) {
return;
}
$opts = $this->meta_opts;
global $aioseop_update_checker, $wp_query, $aioseop_options, $posts;
static $aioseop_dup_counter = 0;
$aioseop_dup_counter ++;
if ( ! defined( 'AIOSEOP_UNIT_TESTING' ) && $aioseop_dup_counter > 1 ) {
/* translators: %1$s, %2$s and %3$s are placeholders and should not be translated. %1$s expands to the name of the plugin, All in One SEO Pack, %2$s to the name of a filter function and %3$s is replaced with a number. */
echo "\n\n";
if ( ! empty( $old_wp_query ) ) {
// Change the query back after we've finished.
$GLOBALS['wp_query'] = $old_wp_query;
unset( $old_wp_query );
}
return;
}
if ( is_home() && ! is_front_page() ) {
$post = aiosp_common::get_blog_page();
} else {
$post = $this->get_queried_object();
}
$meta_string = null;
$description = '';
// Logging - rewrite handler check for output buffering.
$this->check_rewrite_handler();
/* translators: The complete string is: "All in One SEO Pack by Michael Torbert of Semper Fi Web Design". The placeholders shouldn't be altered; only the words "by" and "of" should be translated. */
printf( "\n\n";
if ( AIOSEOPPRO ) {
echo '\n";
}
$blog_page = aiosp_common::get_blog_page( $post );
$save_posts = $posts;
// This outputs robots meta tags and custom canonical URl on WooCommerce product archive page.
// See Github issue https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/755.
if ( function_exists( 'wc_get_page_id' ) && is_post_type_archive( 'product' ) && ( $post_id = wc_get_page_id( 'shop' ) ) && ( $post = get_post( $post_id ) ) ) {
global $posts;
$opts = $this->meta_opts = $this->get_current_options( array(), 'aiosp', null, $post );
$posts = array();
$posts[] = $post;
}
$posts = $save_posts;
// Handle the description format.
// We are not going to mandate that post description needs to be present because the content could be derived from a custom field too.
if ( ! ( is_front_page() && is_paged() ) ) {
$description = $this->get_main_description( $post ); // Get the description.
$description = $this->trim_description( $description );
if ( ! isset( $meta_string ) ) {
$meta_string = '';
}
// Description format.
$description = apply_filters( 'aioseop_description_full', $this->apply_description_format( $description, $post ) );
$desc_attr = '';
if ( ! empty( $aioseop_options['aiosp_schema_markup'] ) ) {
$desc_attr = '';
}
$desc_attr = apply_filters( 'aioseop_description_attributes', $desc_attr );
if ( ! empty( $description ) ) {
$meta_string .= sprintf( "\n", $desc_attr, $description );
}
}
// Get the keywords.
$togglekeywords = 0;
if ( isset( $aioseop_options['aiosp_togglekeywords'] ) ) {
$togglekeywords = $aioseop_options['aiosp_togglekeywords'];
}
if ( $togglekeywords == 0 && ! ( is_front_page() && is_paged() ) ) {
$keywords = $this->get_main_keywords();
$keywords = $this->apply_cf_fields( $keywords );
$keywords = apply_filters( 'aioseop_keywords', $keywords );
if ( isset( $keywords ) && ! empty( $keywords ) ) {
if ( isset( $meta_string ) ) {
$meta_string .= "\n";
}
$keywords = wp_filter_nohtml_kses( str_replace( '"', '', $keywords ) );
$key_attr = apply_filters( 'aioseop_keywords_attributes', '' );
$meta_string .= sprintf( "\n", $key_attr, $keywords );
}
}
// Handle noindex, nofollow - robots meta.
$robots_meta = apply_filters( 'aioseop_robots_meta', $this->get_robots_meta() );
if ( ! empty( $robots_meta ) ) {
$meta_string .= '' . "\n";
}
// Handle site verification.
if ( is_front_page() ) {
foreach (
array(
'google' => 'google-site-verification',
'bing' => 'msvalidate.01',
'pinterest' => 'p:domain_verify',
'yandex' => 'yandex-verification',
'baidu' => 'baidu-site-verification',
) as $k => $v
) {
if ( ! empty( $aioseop_options[ "aiosp_{$k}_verify" ] ) ) {
$meta_string .= '' . "\n";
}
}
// Sitelinks search. Only show if "use schema.org markup is checked".
if ( ! empty( $aioseop_options['aiosp_schema_markup'] ) && ! empty( $aioseop_options['aiosp_google_sitelinks_search'] ) ) {
$meta_string .= $this->sitelinks_search_box() . "\n";
}
}
// Handle extra meta fields.
foreach ( array( 'page_meta', 'post_meta', 'home_meta', 'front_meta' ) as $meta ) {
if ( ! empty( $aioseop_options[ "aiosp_{$meta}_tags" ] ) ) {
$$meta = html_entity_decode( stripslashes( $aioseop_options[ "aiosp_{$meta}_tags" ] ), ENT_QUOTES );
} else {
$$meta = '';
}
}
if ( is_page() && isset( $page_meta ) && ! empty( $page_meta ) && ( ! is_front_page() || empty( $front_meta ) ) ) {
if ( isset( $meta_string ) ) {
$meta_string .= "\n";
}
$meta_string .= $page_meta;
}
if ( is_single() && isset( $post_meta ) && ! empty( $post_meta ) ) {
if ( isset( $meta_string ) ) {
$meta_string .= "\n";
}
$meta_string .= $post_meta;
}
if ( is_front_page() && ! empty( $front_meta ) ) {
if ( isset( $meta_string ) ) {
$meta_string .= "\n";
}
$meta_string .= $front_meta;
} else {
if ( is_home() && ! empty( $home_meta ) ) {
if ( isset( $meta_string ) ) {
$meta_string .= "\n";
}
$meta_string .= $home_meta;
}
}
$prev_next = $this->get_prev_next_links( $post );
$prev = apply_filters( 'aioseop_prev_link', $prev_next['prev'] );
$next = apply_filters( 'aioseop_next_link', $prev_next['next'] );
if ( ! empty( $prev ) ) {
$meta_string .= '\n";
}
if ( ! empty( $next ) ) {
$meta_string .= '\n";
}
if ( $meta_string != null ) {
echo "$meta_string\n";
}
// Handle canonical links.
$show_page = true;
if ( ! empty( $aioseop_options['aiosp_no_paged_canonical_links'] ) ) {
$show_page = false;
}
if ( isset( $aioseop_options['aiosp_can'] ) && $aioseop_options['aiosp_can'] ) {
$url = '';
if ( ! empty( $opts['aiosp_custom_link'] ) && ! is_home() ) {
$url = $opts['aiosp_custom_link'];
if ( apply_filters( 'aioseop_canonical_url_pagination', $show_page ) ) {
$url = $this->get_paged( $url );
}
}
if ( empty( $url ) ) {
$url = $this->aiosp_mrt_get_url( $wp_query, $show_page );
}
$url = $this->validate_url_scheme( $url );
$url = apply_filters( 'aioseop_canonical_url', $url );
if ( ! empty( $url ) ) {
echo '' . "\n";
}
}
do_action( 'aioseop_modules_wp_head' );
echo sprintf( "\n", AIOSEOP_PLUGIN_NAME );
if ( ! empty( $old_wp_query ) ) {
// Change the query back after we've finished.
$GLOBALS['wp_query'] = $old_wp_query;
unset( $old_wp_query );
}
}
/**
* Check Rewrite Handler
*
* @since ?
*/
function check_rewrite_handler() {
global $aioseop_options;
$force_rewrites = 1;
if ( isset( $aioseop_options['aiosp_force_rewrites'] ) ) {
$force_rewrites = $aioseop_options['aiosp_force_rewrites'];
}
if ( $force_rewrites ) {
// Make the title rewrite as short as possible.
if ( function_exists( 'ob_list_handlers' ) ) {
$active_handlers = ob_list_handlers();
} else {
$active_handlers = array();
}
if (
sizeof( $active_handlers ) > 0 &&
$this->strtolower( $active_handlers[ sizeof( $active_handlers ) - 1 ] ) == $this->strtolower( 'All_in_One_SEO_Pack::output_callback_for_title' )
) {
ob_end_flush();
} else {
$this->log( 'another plugin interfering?' );
// If we get here there *could* be trouble with another plugin :(.
$this->ob_start_detected = true;
// Try alternate method -- pdb.
add_filter( 'wp_title', array( $this, 'wp_title' ), 20 );
if ( function_exists( 'ob_list_handlers' ) ) {
foreach ( ob_list_handlers() as $handler ) {
$this->log( "detected output handler $handler" );
}
}
}
}
}
/**
* Trim Description
*
* @since ?
*
* @param $description
* @return mixed|string
*/
function trim_description( $description ) {
$description = trim( wp_strip_all_tags( $description ) );
$description = str_replace( '"', '"', $description );
$description = str_replace( "\r\n", ' ', $description );
$description = str_replace( "\n", ' ', $description );
return $description;
}
/**
* Apply Description Format
*
* @since ?
*
* @param $description
* @param null $post
* @return mixed
*/
function apply_description_format( $description, $post = null ) {
/**
* Runs before applying the formatting for the meta description.
*
* @since 3.0
*/
do_action( 'aioseop_before_apply_description_format' );
global $aioseop_options;
$description_format = $aioseop_options['aiosp_description_format'];
if ( ! isset( $description_format ) || empty( $description_format ) ) {
$description_format = '%description%';
}
$description = str_replace( '%description%', apply_filters( 'aioseop_description_override', $description ), $description_format );
if ( false !== strpos( $description, '%site_title%', 0 ) ) {
$description = str_replace( '%site_title%', get_bloginfo( 'name' ), $description );
}
if ( false !== strpos( $description, '%blog_title%', 0 ) ) {
$description = str_replace( '%blog_title%', get_bloginfo( 'name' ), $description );
}
if ( false !== strpos( $description, '%site_description%', 0 ) ) {
$description = str_replace( '%site_description%', get_bloginfo( 'description' ), $description );
}
if ( false !== strpos( $description, '%blog_description%', 0 ) ) {
$description = str_replace( '%blog_description%', get_bloginfo( 'description' ), $description );
}
if ( false !== strpos( $description, '%wp_title%', 0 ) ) {
$description = str_replace( '%wp_title%', $this->get_original_title(), $description );
}
if ( false !== strpos( $description, '%post_title%', 0 ) ) {
$description = str_replace( '%post_title%', $this->get_aioseop_title( $post, false ), $description );
}
if ( false !== strpos( $description, '%current_date%', 0 ) ) {
$description = str_replace( '%current_date%', date_i18n( get_option( 'date_format' ) ), $description );
}
if ( false !== strpos( $description, '%current_year%', 0 ) ) {
$description = str_replace( '%current_year%', date( 'Y' ), $description );
}
if ( false !== strpos( $description, '%post_date%', 0 ) ) {
$description = str_replace( '%post_date%', get_the_date(), $description );
}
if ( false !== strpos( $description, '%post_year%', 0 ) ) {
$description = str_replace( '%post_year%', get_the_date( 'Y' ), $description );
}
if ( false !== strpos( $description, '%post_month%', 0 ) ) {
$description = str_replace( '%post_month%', get_the_date( 'F' ), $description );
}
/*
* This was intended to make attachment descriptions unique if pulling from the parent... let's remove it and see if there are any problems
* on the roadmap is to have a better hierarchy for attachment description pulling
* if ($aioseop_options['aiosp_can']) $description = $this->make_unique_att_desc($description);
*/
$description = $this->apply_cf_fields( $description );
/**
* Runs after applying the formatting for the meta description.
*
* @since 3.0
*/
do_action( 'aioseop_after_apply_description_format' );
return $description;
}
/**
* Get Robots Meta
*
* @since 2.3.5
* @since 2.3.11.5 Added no index API filter hook for password protected posts.
*
* @return string
*/
function get_robots_meta() {
global $aioseop_options;
$opts = $this->meta_opts;
$page = $this->get_page_number();
$robots_meta = $tax_noindex = '';
if ( isset( $aioseop_options['aiosp_tax_noindex'] ) ) {
$tax_noindex = $aioseop_options['aiosp_tax_noindex'];
}
if ( empty( $tax_noindex ) || ! is_array( $tax_noindex ) ) {
$tax_noindex = array();
}
$aiosp_noindex = $aiosp_nofollow = '';
$noindex = 'index';
$nofollow = 'follow';
if ( ! empty( $opts ) ) {
$aiosp_noindex = htmlspecialchars( stripslashes( $opts['aiosp_noindex'] ) );
$aiosp_nofollow = htmlspecialchars( stripslashes( $opts['aiosp_nofollow'] ) );
}
if (
(
is_category() &&
! empty( $aioseop_options['aiosp_category_noindex'] )
) ||
(
! is_category() &&
is_archive() &&
! is_tag() &&
! is_tax() &&
(
(
is_date() &&
! empty( $aioseop_options['aiosp_archive_date_noindex'] )
) ||
(
is_author() &&
! empty( $aioseop_options['aiosp_archive_author_noindex'] )
)
)
) ||
(
is_tag() &&
! empty( $aioseop_options['aiosp_tags_noindex'] )
) ||
(
is_search() &&
! empty( $aioseop_options['aiosp_search_noindex'] )
) ||
(
is_404() &&
! empty( $aioseop_options['aiosp_404_noindex'] )
) ||
(
is_tax() &&
in_array( get_query_var( 'taxonomy' ), $tax_noindex )
)
) {
$noindex = 'noindex';
// #322: duplicating this code so that we don't step on some other entities' toes.
if (
( 'on' === $aiosp_nofollow ) ||
(
( ! empty( $aioseop_options['aiosp_paginated_nofollow'] ) ) &&
$page > 1
) ||
(
( '' === $aiosp_nofollow ) &&
( ! empty( $aioseop_options['aiosp_cpostnofollow'] ) ) &&
in_array( $post_type, $aioseop_options['aiosp_cpostnofollow'] )
)
) {
$nofollow = 'nofollow';
}
// #322: duplicating this code so that we don't step on some other entities' toes.
} elseif (
is_single() ||
is_page() ||
$this->is_static_posts_page() ||
is_attachment() ||
is_category() ||
is_tag() ||
is_tax() ||
( $page > 1 ) ||
$this->check_singular()
) {
$post_type = get_post_type();
if (
$aiosp_noindex ||
$aiosp_nofollow ||
! empty( $aioseop_options['aiosp_cpostnoindex'] ) ||
! empty( $aioseop_options['aiosp_cpostnofollow'] ) ||
! empty( $aioseop_options['aiosp_paginated_noindex'] ) ||
! empty( $aioseop_options['aiosp_paginated_nofollow'] )
) {
if (
( 'on' === $aiosp_noindex ) ||
(
( ! empty( $aioseop_options['aiosp_paginated_noindex'] ) )
&& $page > 1
) ||
(
( '' === $aiosp_noindex ) &&
( ! empty( $aioseop_options['aiosp_cpostnoindex'] ) ) &&
in_array( $post_type, $aioseop_options['aiosp_cpostnoindex'] )
)
) {
$noindex = 'noindex';
}
if (
( $aiosp_nofollow == 'on' ) ||
(
( ! empty( $aioseop_options['aiosp_paginated_nofollow'] ) ) &&
$page > 1
) ||
(
( $aiosp_nofollow == '' ) &&
( ! empty( $aioseop_options['aiosp_cpostnofollow'] ) ) &&
in_array( $post_type, $aioseop_options['aiosp_cpostnofollow'] )
)
) {
$nofollow = 'nofollow';
}
}
}
if ( is_singular() && $this->is_password_protected() && apply_filters( 'aiosp_noindex_password_posts', false ) ) {
$noindex = 'noindex';
}
$robots_meta = $noindex . ',' . $nofollow;
if ( $robots_meta == 'index,follow' ) {
$robots_meta = '';
}
return $robots_meta;
}
/**
* Check Singular
*
* Determine if the post is 'like' singular. In some specific instances, such as when the Reply post type of bbpress is loaded in its own page,
* it reflects as singular intead of single
*
* @since 2.4.2
*
* @return bool
*/
private function check_singular() {
global $wp_query, $post;
$is_singular = false;
if ( is_singular() ) {
// #1297 - support for bbpress 'reply' post type.
if ( $post && 'reply' === $post->post_type ) {
$is_singular = true;
}
}
return $is_singular;
}
/**
* Is Password Protected
*
* Determine if post is password protected.
*
* @since 2.3.11.5
*
* @return bool
*/
function is_password_protected() {
global $post;
if ( ! empty( $post->post_password ) ) {
return true;
}
return false;
}
/**
* Sitelinks Search Box
*
* @since ?
*
* @return mixed|void
*/
function sitelinks_search_box() {
global $aioseop_options;
$home_url = esc_url( get_home_url() );
$search_block = '';
if ( ! empty( $aioseop_options['aiosp_google_sitelinks_search'] ) ) {
$search_block = <<
{
"@context": "https://schema.org",
"@type": "WebSite",
EOF;
if ( ! empty( $search_block ) ) {
$search_box .= $search_block;
}
$search_box .= <<
EOF;
return apply_filters( 'aiosp_sitelinks_search_box', $search_box );
}
/**
* Get Previous/Next Links
*
* @since ?
*
* @param null $post
* @return array
*/
function get_prev_next_links( $post = null ) {
$prev = $next = '';
$page = $this->get_page_number();
if ( is_home() || is_archive() || is_paged() ) {
global $wp_query;
$max_page = $wp_query->max_num_pages;
if ( $page > 1 ) {
$prev = get_previous_posts_page_link();
}
if ( $page < $max_page ) {
$paged = $GLOBALS['paged'];
if ( ! is_single() ) {
if ( ! $paged ) {
$paged = 1;
}
$nextpage = intval( $paged ) + 1;
if ( ! $max_page || $max_page >= $nextpage ) {
$next = get_pagenum_link( $nextpage );
}
}
}
} elseif ( is_page() || is_single() ) {
$numpages = 1;
$multipage = 0;
$page = get_query_var( 'page' );
if ( ! $page ) {
$page = 1;
}
if ( is_single() || is_page() || is_feed() ) {
$more = 1;
}
$content = $post->post_content;
if ( false !== strpos( $content, '', 0 ) ) {
if ( $page > 1 ) {
$more = 1;
}
$content = str_replace( "\n\n", '', $content );
$content = str_replace( "\n", '', $content );
$content = str_replace( "\n", '', $content );
// Ignore nextpage at the beginning of the content.
if ( 0 === strpos( $content, '', 0 ) ) {
$content = substr( $content, 15 );
}
$pages = explode( '', $content );
$numpages = count( $pages );
if ( $numpages > 1 ) {
$multipage = 1;
}
} else {
$page = null;
}
if ( ! empty( $page ) ) {
if ( $page > 1 ) {
// Cannot use `wp_link_page()` since it is for rendering purposes and has no control over the page number.
// TODO Investigate alternate wp concept. If none is found, keep private function in case of any future WP changes.
$prev = _wp_link_page( $page - 1 );
}
if ( $page + 1 <= $numpages ) {
// Cannot use `wp_link_page()` since it is for rendering purposes and has no control over the page number.
// TODO Investigate alternate wp concept. If none is found, keep private function in case of any future WP changes.
$next = _wp_link_page( $page + 1 );
}
}
if ( ! empty( $prev ) ) {
$dom = new DOMDocument();
$dom->loadHTML( $prev );
$prev = $dom->getElementsByTagName( 'a' )->item( 0 )->getAttribute( 'href' );
}
if ( ! empty( $next ) ) {
$dom = new DOMDocument();
$dom->loadHTML( $next );
$next = $dom->getElementsByTagName( 'a' )->item( 0 )->getAttribute( 'href' );
}
}
return array(
'prev' => $prev,
'next' => $next,
);
}
/**
* Validate URL Scheme
*
* Validates whether the url should be https or http.
*
* Mainly we're just using this for canonical URLS, but eventually it may be useful for other things
*
* @since 2.3.5
* @since 2.3.11 Removed check for legacy protocol setting. Added filter.
*
* @param $url
* @return string $url
*/
function validate_url_scheme( $url ) {
// TODO we should check for the site setting in the case of auto.
global $aioseop_options;
$scheme = apply_filters( 'aioseop_canonical_protocol', false );
if ( 'http' === $scheme ) {
$url = preg_replace( '/^https:/i', 'http:', $url );
}
if ( 'https' === $scheme ) {
$url = preg_replace( '/^http:/i', 'https:', $url );
}
return $url;
}
/**
* Override Options
*
* @since ?
*
* @param $options
* @param $location
* @param $settings
* @return mixed
*/
function override_options( $options, $location, $settings ) {
if ( class_exists( 'DOMDocument' ) ) {
$options['aiosp_google_connect'] = $settings['aiosp_google_connect']['default'];
}
return $options;
}
function aiosp_google_analytics() {
new aioseop_google_analytics;
}
/**
* Save Post Data
*
* @since ?
*
* @param $id
* @return bool
*/
function save_post_data( $id ) {
$awmp_edit = $nonce = null;
if ( empty( $_POST ) ) {
return false;
}
if ( isset( $_POST['aiosp_edit'] ) ) {
$awmp_edit = $_POST['aiosp_edit'];
}
if ( isset( $_POST['nonce-aioseop-edit'] ) ) {
$nonce = $_POST['nonce-aioseop-edit'];
}
if ( isset( $awmp_edit ) && ! empty( $awmp_edit ) && wp_verify_nonce( $nonce, 'edit-aioseop-nonce' ) ) {
$optlist = array(
'keywords',
'description',
'title',
'custom_link',
'sitemap_exclude',
'disable',
'disable_analytics',
'noindex',
'nofollow',
);
if ( ! ( ! empty( $this->options['aiosp_can'] ) ) ) {
unset( $optlist['custom_link'] );
}
foreach ( $optlist as $f ) {
$field = "aiosp_$f";
if ( isset( $_POST[ $field ] ) ) {
$$field = $_POST[ $field ];
}
}
$optlist = array(
'keywords',
'description',
'title',
'custom_link',
'noindex',
'nofollow',
);
if ( ! ( ! empty( $this->options['aiosp_can'] ) ) ) {
unset( $optlist['custom_link'] );
}
foreach ( $optlist as $f ) {
delete_post_meta( $id, "_aioseop_{$f}" );
}
delete_post_meta( $id, '_aioseop_sitemap_exclude' );
delete_post_meta( $id, '_aioseop_disable' );
delete_post_meta( $id, '_aioseop_disable_analytics' );
foreach ( $optlist as $f ) {
$var = "aiosp_$f";
$field = "_aioseop_$f";
if ( isset( $$var ) && ! empty( $$var ) ) {
add_post_meta( $id, $field, $$var );
}
}
if ( isset( $aiosp_sitemap_exclude ) && ! empty( $aiosp_sitemap_exclude ) ) {
add_post_meta( $id, '_aioseop_sitemap_exclude', $aiosp_sitemap_exclude );
}
if ( isset( $aiosp_disable ) && ! empty( $aiosp_disable ) ) {
add_post_meta( $id, '_aioseop_disable', $aiosp_disable );
if ( isset( $aiosp_disable_analytics ) && ! empty( $aiosp_disable_analytics ) ) {
add_post_meta( $id, '_aioseop_disable_analytics', $aiosp_disable_analytics );
}
}
}
}
/**
* Display Tabbed Metabox
*
* @since ?
*
* @param $post
* @param $metabox
*/
function display_tabbed_metabox( $post, $metabox ) {
$tabs = $metabox['args'];
echo '