' . __( '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();
}
*/
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 );
}
/**
* @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;
}
/**
* Handle resetting options to defaults, but preserve the license key if pro.
*
* @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 );
}
/**
* @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;
}
/**
* @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;
}
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 );
}
}
/**
* @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;
}
/**
* @param $content
*
* @return mixed|string
*/
function output_callback_for_title( $content ) {
return $this->rewrite_title( $content );
}
/**
* Used for forcing title rewrites.
*
* @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;
}
/**
* @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 );
}
/**
* Adds WordPress hooks.
*
* @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' ) && current_user_can( 'manage_options' ) && ! AIOSEOPPRO ) {
$aioseop_notices->activate_notice( 'woocommerce_detected' );
} else {
global $aioseop_notices;
$aioseop_notices->deactivate_notice( 'woocommerce_detected' );
}
}
/**
* @param $description
*
* @return string
*/
function make_unique_att_desc( $description ) {
global $wp_query;
if ( is_attachment() ) {
$url = $this->aiosp_mrt_get_url( $wp_query );
if ( $url ) {
$matches = array();
preg_match_all( '/(\d+)/', $url, $matches );
if ( is_array( $matches ) ) {
$uniqueDesc = join( '', $matches[0] );
}
}
$description .= ' ' . $uniqueDesc;
}
return $description;
}
/**
* Adds meta description to AMP pages.
*
* @since 2.3.11.5
*/
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;
}
}
/**
* Checks whether the current CPT should show the SEO tags.
*/
private function is_seo_enabled_for_cpt() {
global $aioseop_options;
return empty( $post_type ) || in_array( get_post_type(), $aioseop_options['aiosp_cpostactive'], true );
}
/**
* @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.
*/
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" );
}
}
}
}
}
/**
* @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;
}
/**
* @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;
}
/**
* @return string
* @since 0.0
* @since 2.3.11.5 Added no index API filter hook for password protected posts.
*/
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;
}
/**
* 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;
}
/**
* 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 );
}
/**
* @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 );
}
/**
*
* 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
*
* @param $url
*
* @return string $url
*
* @since 2.3.5
* @since 2.3.11 Removed check for legacy protocol setting. Added filter.
*/
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;
}
/**
* @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;
}
/**
* @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 );
}
}
}
}
/**
* @param $post
* @param $metabox
*/
function display_tabbed_metabox( $post, $metabox ) {
$tabs = $metabox['args'];
echo '