From 15f232409c94e2c9d56fc64572082dad2f3b4701 Mon Sep 17 00:00:00 2001 From: contactashish13 Date: Tue, 26 Feb 2019 04:49:21 +0530 Subject: [PATCH 001/121] Social Meta module - Remove Blog from Object Type drop downs (#2232) * Social Meta module - Remove Blog from Object Type drop downs * Dev-Add/change phpDoc * Dev-Fix potential bug with no array value --- modules/aioseop_opengraph.php | 45 ++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/modules/aioseop_opengraph.php b/modules/aioseop_opengraph.php index 4c79315af..d50c7517c 100644 --- a/modules/aioseop_opengraph.php +++ b/modules/aioseop_opengraph.php @@ -76,7 +76,6 @@ function __construct() { ), 'Websites' => array( 'article' => __( 'Article', 'all-in-one-seo-pack' ), - 'blog' => __( 'Blog', 'all-in-one-seo-pack' ), 'website' => __( 'Website', 'all-in-one-seo-pack' ), ), ); @@ -191,6 +190,7 @@ function __construct() { // Set variables after WordPress load. add_action( 'init', array( &$this, 'init' ), 999999 ); add_filter( 'jetpack_enable_open_graph', '__return_false' ); // Avoid having duplicate meta tags + add_filter( $this->prefix . 'meta', array( $this, 'handle_meta_tag' ), 10, 3 ); // Force refresh of Facebook cache. add_action( 'post_updated', array( &$this, 'force_fb_refresh_update' ), 10, 3 ); add_action( 'transition_post_status', array( &$this, 'force_fb_refresh_transition' ), 10, 3 ); @@ -203,6 +203,28 @@ function __construct() { $this->init(); } + /** + * Handle specific meta tags. + * + * @since 3.0 + * + * @param string $value The value of the meta tag. + * @param string $t The type of network. + * @param string $k The name of the meta tag. + * @return string + */ + function handle_meta_tag( $value, $t, $k ) { + switch ( $k ) { + case 'type': + // https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/1013 + if ( 'blog' === $value ) { + $value = 'website'; + } + break; + } + return $value; + } + /** * Sets the terms defaults after a new term is created. * @@ -871,10 +893,18 @@ function filter_settings( $settings, $location, $current ) { $flat_type_list[ $k ] = $v; } } + $default_fb_type = $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ]; + // https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/1013 + // if 'blog' is the selected type but because it is no longer a schema type, we use 'website' instead. + if ( 'blog' === $default_fb_type ) { + $default_fb_type = 'website'; + } + if ( isset( $flat_type_list[ $default_fb_type ] ) ) { + $default_fb_type = $flat_type_list[ $default_fb_type ]; + } $settings[ $prefix . 'category' ]['initial_options'] = array_merge( array( - $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ] => __( 'Default ', 'all-in-one-seo-pack' ) . ' - ' - . $flat_type_list[ $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ] ], + $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ] => __( 'Default ', 'all-in-one-seo-pack' ) . ' - ' . $default_fb_type, ), $settings[ $prefix . 'category' ]['initial_options'] ); @@ -980,6 +1010,15 @@ function override_options( $options, $location, $settings ) { } $options = wp_parse_args( $options, $opts ); + // https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/1013 + $post_types = $this->get_post_type_titles(); + foreach ( $post_types as $slug => $name ) { + $field = 'aiosp_opengraph_' . $slug . '_fb_object_type'; + if ( isset( $options[ $field ] ) && 'blog' === $options[ $field ] ) { + $options[ $field ] = 'website'; + } + } + return $options; } From d16fb2329e23c1fcda09297bf6bf5e420d6242e0 Mon Sep 17 00:00:00 2001 From: contactashish13 Date: Thu, 28 Feb 2019 02:34:24 +0530 Subject: [PATCH 002/121] Filter for controlling which description to use for WooCommerce products (#1576) * Filter for controlling which description to use for WooCommerce products #185 * show excerpt if return false * use excerpt on return false * revert code in wrong spot * Fix for filter code for autogenerated descriptions * Dev-fix else placement * Dev-Change using function multiple times Reduces the amount of duplicate code. --- aioseop_class.php | 16 +- modules/aioseop_opengraph.php | 3864 +++++++++++++++++---------------- 2 files changed, 1945 insertions(+), 1935 deletions(-) diff --git a/aioseop_class.php b/aioseop_class.php index 54fc98b12..e88d63f12 100644 --- a/aioseop_class.php +++ b/aioseop_class.php @@ -2590,15 +2590,21 @@ function get_post_description( $post ) { } if ( ! $description ) { if ( empty( $aioseop_options['aiosp_skip_excerpt'] ) ) { - $description = $this->trim_text_without_filters_full_length( $this->internationalize( $post->post_excerpt ) ); + $description = $post->post_excerpt; } if ( ! $description && isset( $aioseop_options['aiosp_generate_descriptions'] ) && $aioseop_options['aiosp_generate_descriptions'] ) { - $content = $post->post_content; - if ( ! empty( $aioseop_options['aiosp_run_shortcodes'] ) ) { - $content = do_shortcode( $content ); + if ( ! AIOSEOPPRO || ( AIOSEOPPRO && apply_filters( $this->prefix . 'generate_descriptions_from_content', true, $post ) ) ) { + $content = $post->post_content; + if ( ! empty( $aioseop_options['aiosp_run_shortcodes'] ) ) { + $content = do_shortcode( $content ); + } + $description = $content; + } else { + $description = $post->post_excerpt; } - $description = $this->trim_text_without_filters_full_length( $this->internationalize( $content ) ); } + + $description = $this->trim_text_without_filters_full_length( $this->internationalize( $description ) ); } return $description; diff --git a/modules/aioseop_opengraph.php b/modules/aioseop_opengraph.php index d50c7517c..d83ac95ee 100644 --- a/modules/aioseop_opengraph.php +++ b/modules/aioseop_opengraph.php @@ -1,1930 +1,1934 @@ -name = __( 'Social Meta', 'all-in-one-seo-pack' ); // Human-readable name of the plugin - $this->prefix = 'aiosp_opengraph_'; // option prefix - $this->file = __FILE__; // the current file - $this->fb_object_types = array( - 'Activities' => array( - 'activity' => __( 'Activity', 'all-in-one-seo-pack' ), - 'sport' => __( 'Sport', 'all-in-one-seo-pack' ), - ), - 'Businesses' => array( - 'bar' => __( 'Bar', 'all-in-one-seo-pack' ), - 'company' => __( 'Company', 'all-in-one-seo-pack' ), - 'cafe' => __( 'Cafe', 'all-in-one-seo-pack' ), - 'hotel' => __( 'Hotel', 'all-in-one-seo-pack' ), - 'restaurant' => __( 'Restaurant', 'all-in-one-seo-pack' ), - ), - 'Groups' => array( - 'cause' => __( 'Cause', 'all-in-one-seo-pack' ), - 'sports_league' => __( 'Sports League', 'all-in-one-seo-pack' ), - 'sports_team' => __( 'Sports Team', 'all-in-one-seo-pack' ), - ), - 'Organizations' => array( - 'band' => __( 'Band', 'all-in-one-seo-pack' ), - 'government' => __( 'Government', 'all-in-one-seo-pack' ), - 'non_profit' => __( 'Non Profit', 'all-in-one-seo-pack' ), - 'school' => __( 'School', 'all-in-one-seo-pack' ), - 'university' => __( 'University', 'all-in-one-seo-pack' ), - ), - 'People' => array( - 'actor' => __( 'Actor', 'all-in-one-seo-pack' ), - 'athlete' => __( 'Athlete', 'all-in-one-seo-pack' ), - 'author' => __( 'Author', 'all-in-one-seo-pack' ), - 'director' => __( 'Director', 'all-in-one-seo-pack' ), - 'musician' => __( 'Musician', 'all-in-one-seo-pack' ), - 'politician' => __( 'Politician', 'all-in-one-seo-pack' ), - 'profile' => __( 'Profile', 'all-in-one-seo-pack' ), - 'public_figure' => __( 'Public Figure', 'all-in-one-seo-pack' ), - ), - 'Places' => array( - 'city' => __( 'City', 'all-in-one-seo-pack' ), - 'country' => __( 'Country', 'all-in-one-seo-pack' ), - 'landmark' => __( 'Landmark', 'all-in-one-seo-pack' ), - 'state_province' => __( 'State Province', 'all-in-one-seo-pack' ), - ), - 'Products and Entertainment' => array( - 'album' => __( 'Album', 'all-in-one-seo-pack' ), - 'book' => __( 'Book', 'all-in-one-seo-pack' ), - 'drink' => __( 'Drink', 'all-in-one-seo-pack' ), - 'food' => __( 'Food', 'all-in-one-seo-pack' ), - 'game' => __( 'Game', 'all-in-one-seo-pack' ), - 'movie' => __( 'Movie', 'all-in-one-seo-pack' ), - 'product' => __( 'Product', 'all-in-one-seo-pack' ), - 'song' => __( 'Song', 'all-in-one-seo-pack' ), - 'tv_show' => __( 'TV Show', 'all-in-one-seo-pack' ), - 'episode' => __( 'Episode', 'all-in-one-seo-pack' ), - ), - 'Websites' => array( - 'article' => __( 'Article', 'all-in-one-seo-pack' ), - 'website' => __( 'Website', 'all-in-one-seo-pack' ), - ), - ); - parent::__construct(); - - $this->help_text = array( - 'setmeta' => __( 'Checking this box will use the Home Title and Home Description set in All in One SEO Pack, General Settings as the Open Graph title and description for your home page.', 'all-in-one-seo-pack' ), - 'key' => __( 'Enter your Facebook Admin ID here. You can enter multiple IDs separated by a comma. You can look up your Facebook ID using this tool http://findmyfbid.com/', 'all-in-one-seo-pack' ), - 'appid' => __( 'Enter your Facebook App ID here. Information about how to get your Facebook App ID can be found at https://developers.facebook.com/docs/apps/register', 'all-in-one-seo-pack' ), - 'title_shortcodes' => __( 'Run shortcodes that appear in social title meta tags.', 'all-in-one-seo-pack' ), - 'description_shortcodes' => __( 'Run shortcodes that appear in social description meta tags.', 'all-in-one-seo-pack' ), - 'sitename' => __( 'The Site Name is the name that is used to identify your website.', 'all-in-one-seo-pack' ), - 'hometitle' => __( 'The Home Title is the Open Graph title for your home page.', 'all-in-one-seo-pack' ), - 'description' => __( 'The Home Description is the Open Graph description for your home page.', 'all-in-one-seo-pack' ), - 'homeimage' => __( 'The Home Image is the Open Graph image for your home page.', 'all-in-one-seo-pack' ), - 'generate_descriptions' => __( 'This option will auto generate your Open Graph descriptions from your post content instead of your post excerpt. WooCommerce users should read the documentation regarding this setting.', 'all-in-one-seo-pack' ), - 'defimg' => __( 'This option lets you choose which image will be displayed by default for the Open Graph image. You may override this on individual posts.', 'all-in-one-seo-pack' ), - 'fallback' => __( 'This option lets you fall back to the default image if no image could be found above.', 'all-in-one-seo-pack' ), - 'dimg' => __( 'This option sets a default image that can be used for the Open Graph image. You can upload an image, select an image from your Media Library or paste the URL of an image here.', 'all-in-one-seo-pack' ), - 'dimgwidth' => __( 'This option lets you set a default width for your images, where unspecified.', 'all-in-one-seo-pack' ), - 'dimgheight' => __( 'This option lets you set a default height for your images, where unspecified.', 'all-in-one-seo-pack' ), - 'meta_key' => __( 'Enter the name of a custom field (or multiple field names separated by commas) to use that field to specify the Open Graph image on Pages or Posts.', 'all-in-one-seo-pack' ), - 'image' => __( 'This option lets you select the Open Graph image that will be used for this Page or Post, overriding the default settings.', 'all-in-one-seo-pack' ), - 'customimg' => __( 'This option lets you upload an image to use as the Open Graph image for this Page or Post.', 'all-in-one-seo-pack' ), - 'imagewidth' => __( 'Enter the width for your Open Graph image in pixels (i.e. 600).', 'all-in-one-seo-pack' ), - 'imageheight' => __( 'Enter the height for your Open Graph image in pixels (i.e. 600).', 'all-in-one-seo-pack' ), - 'video' => __( 'This option lets you specify a link to the Open Graph video used on this Page or Post.', 'all-in-one-seo-pack' ), - 'videowidth' => __( 'Enter the width for your Open Graph video in pixels (i.e. 600).', 'all-in-one-seo-pack' ), - 'videoheight' => __( 'Enter the height for your Open Graph video in pixels (i.e. 600).', 'all-in-one-seo-pack' ), - 'defcard' => __( 'Select the default type of Twitter Card to display.', 'all-in-one-seo-pack' ), - 'setcard' => __( 'Select the Twitter Card type to use for this Page or Post, overriding the default setting.', 'all-in-one-seo-pack' ), - 'twitter_site' => __( 'Enter the Twitter username associated with your website here.', 'all-in-one-seo-pack' ), - 'twitter_creator' => __( 'Allows your authors to be identified by their Twitter usernames as content creators on the Twitter cards for their posts.', 'all-in-one-seo-pack' ), - 'twitter_domain' => __( 'Enter the name of your website here.', 'all-in-one-seo-pack' ), - 'customimg_twitter' => __( 'This option lets you upload an image to use as the Twitter image for this Page or Post.', 'all-in-one-seo-pack' ), - 'gen_tags' => __( 'Automatically generate article tags for Facebook type article when not provided.', 'all-in-one-seo-pack' ), - 'gen_keywords' => __( 'Use keywords in generated article tags.', 'all-in-one-seo-pack' ), - 'gen_categories' => __( 'Use categories in generated article tags.', 'all-in-one-seo-pack' ), - 'gen_post_tags' => __( 'Use post tags in generated article tags.', 'all-in-one-seo-pack' ), - 'types' => __( 'Select which Post Types you want to use All in One SEO Pack to set Open Graph meta values for.', 'all-in-one-seo-pack' ), - 'title' => __( 'This is the Open Graph title of this Page or Post.', 'all-in-one-seo-pack' ), - 'desc' => __( 'This is the Open Graph description of this Page or Post.', 'all-in-one-seo-pack' ), - 'category' => __( 'Select the Open Graph type that best describes the content of this Page or Post.', 'all-in-one-seo-pack' ), - 'facebook_debug' => __( 'Press this button to have Facebook re-fetch and debug this page.', 'all-in-one-seo-pack' ), - 'section' => __( 'This Open Graph meta allows you to add a general section name that best describes this content.', 'all-in-one-seo-pack' ), - 'tag' => __( 'This Open Graph meta allows you to add a list of keywords that best describe this content.', 'all-in-one-seo-pack' ), - 'facebook_publisher' => __( 'Link articles to the Facebook page associated with your website.', 'all-in-one-seo-pack' ), - 'facebook_author' => __( 'Allows your authors to be identified by their Facebook pages as content authors on the Opengraph meta for their articles.', 'all-in-one-seo-pack' ), - 'person_or_org' => __( 'Are the social profile links for your website for a person or an organization?', 'all-in-one-seo-pack' ), - 'profile_links' => __( "Add URLs for your website's social profiles here (Facebook, Twitter, Google+, Instagram, LinkedIn), one per line.", 'all-in-one-seo-pack' ), - 'social_name' => __( 'Add the name of the person or organization who owns these profiles.', 'all-in-one-seo-pack' ), - ); - - $this->help_anchors = array( - 'title_shortcodes' => '#run-shortcodes-in-title', - 'description_shortcodes' => '#run-shortcodes-in-description', - 'generate_descriptions' => '#auto-generate-og-descriptions', - 'setmeta' => '#use-aioseo-title-and-description', - 'sitename' => '#site-name', - 'hometitle' => '#home-title-and-description', - 'description' => '#home-title-and-description', - 'homeimage' => '#home-image', - 'defimg' => '#select-og-image-source', - 'fallback' => '#use-default-if-no-image-found', - 'dimg' => '#default-og-image', - 'dimgwidth' => '#default-image-width', - 'dimgheight' => '#default-image-height', - 'meta_key' => '#use-custom-field-for-image', - 'profile_links' => '#social-profile-links', - 'person_or_org' => '#social-profile-links', - 'social_name' => '#social-profile-links', - 'key' => '#facebook-admin-id', - 'appid' => '#facebook-app-id', - 'gen_tags' => '#automatically-generate-article-tags', - 'gen_keywords' => '#use-keywords-in-article-tags', - 'gen_categories' => '#use-categories-in-article-tags', - 'gen_post_tags' => '#use-post-tags-in-article-tags', - 'facebook_publisher' => '#show-facebook-publisher-on-articles', - 'facebook_author' => '#show-facebook-author-on-articles', - 'types' => '#enable-facebook-meta-for', - 'defcard' => '#default-twitter-card', - 'twitter_site' => '#twitter-site', - 'twitter_creator' => '#show-twitter-author', - 'twitter_domain' => '#twitter-domain', - 'scan_header' => '#scan-social-meta', - 'title' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#title', - 'desc' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#description', - 'image' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#image', - 'customimg' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#custom-image', - 'imagewidth' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#specify-image-width-height', - 'imageheight' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#specify-image-width-height', - 'video' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#custom-video', - 'videowidth' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#specify-video-width-height', - 'videoheight' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#specify-video-width-height', - 'category' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#facebook-object-type', - 'facebook_debug' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#facebook-debug', - 'section' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#article-section', - 'tag' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#article-tags', - 'setcard' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#twitter-card-type', - 'customimg_twitter' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#custom-twitter-image', - ); - - if ( is_admin() ) { - add_action( 'admin_init', array( $this, 'admin_init' ), 5 ); - } else { - add_action( 'wp', array( $this, 'type_setup' ) ); - } - - if ( ! is_admin() || defined( 'DOING_AJAX' ) ) { - $this->do_opengraph(); - } - // Set variables after WordPress load. - add_action( 'init', array( &$this, 'init' ), 999999 ); - add_filter( 'jetpack_enable_open_graph', '__return_false' ); // Avoid having duplicate meta tags - add_filter( $this->prefix . 'meta', array( $this, 'handle_meta_tag' ), 10, 3 ); - // Force refresh of Facebook cache. - add_action( 'post_updated', array( &$this, 'force_fb_refresh_update' ), 10, 3 ); - add_action( 'transition_post_status', array( &$this, 'force_fb_refresh_transition' ), 10, 3 ); - add_action( 'edited_term', array( &$this, 'save_tax_data' ), 10, 3 ); - // Adds special filters - add_filter( 'aioseop_opengraph_placeholder', array( &$this, 'filter_placeholder' ) ); - add_action( 'aiosp_activate_opengraph', array( $this, 'activate_module' ) ); - add_action( 'created_term', array( $this, 'created_term' ), 10, 3 ); - // Call to init to generate menus - $this->init(); - } - - /** - * Handle specific meta tags. - * - * @since 3.0 - * - * @param string $value The value of the meta tag. - * @param string $t The type of network. - * @param string $k The name of the meta tag. - * @return string - */ - function handle_meta_tag( $value, $t, $k ) { - switch ( $k ) { - case 'type': - // https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/1013 - if ( 'blog' === $value ) { - $value = 'website'; - } - break; - } - return $value; - } - - /** - * Sets the terms defaults after a new term is created. - * - * @param int $term_id Term ID. - * @param int $tt_id Term taxonomy ID. - * @param string $taxonomy Taxonomy slug. - */ - function created_term( $term_id, $tt_id, $taxonomy_name ) { - $k = 'settings'; - $prefix = $this->get_prefix( $k ); - $tax = get_taxonomy( $taxonomy_name ); - $this->set_object_type_for_taxonomy( $prefix, $k, $taxonomy_name, $tax, false, array( $term_id ) ); - } - - /** - * Sets the defaults for a taxonomy. - * - * @param string $prefix The prefix of this module. - * @param string $k The key against which the options will be determined/set. - * @param string $taxonomy_name The name of the taxonomy. - * @param Object $tax The taxonomy object. - * @param bool $bail_if_no_terms Bail if the taxonomy has no terms. - * @param array $terms The terms in the taxonomy. - */ - private function set_object_type_for_taxonomy( $prefix, $k, $taxonomy_name, $tax, $bail_if_no_terms = false, $terms = null ) { - $object_type = null; - if ( ! $terms ) { - $terms = get_terms( - $taxonomy_name, array( - 'meta_query' => array( - array( - 'key' => '_' . $prefix . $k, - 'compare' => 'NOT EXISTS', - ), - ), - 'number' => PHP_INT_MAX, - 'fields' => 'ids', - 'hide_empty' => false, - ) - ); - } - - if ( empty( $terms ) && $bail_if_no_terms ) { - return false; - } - - if ( true === $tax->_builtin ) { - $object_type = 'article'; - } else { - // custom taxonomy. Let's get a post against this to determine its post type. - $posts = get_posts( - array( - 'numberposts' => 1, - 'post_type' => 'any', - 'tax_query' => array( - array( - 'taxonomy' => $taxonomy_name, - 'field' => 'term_id', - 'terms' => $terms, - ), - ), - ) - ); - if ( $posts ) { - global $aioseop_options; - $post_type = $posts[0]->post_type; - if ( isset( $aioseop_options['modules'] ) && isset( $aioseop_options['modules'][ $this->prefix . 'options' ] ) ) { - $og_options = $aioseop_options['modules'][ $this->prefix . 'options' ]; - - // now let's see what default object type is set for this post type. - $object_type_set = $og_options[ $this->prefix . $post_type . '_fb_object_type' ]; - if ( ! empty( $object_type_set ) ) { - $object_type = $object_type_set; - } - } - } - } - - if ( $object_type ) { - $opts[ $prefix . $k . '_category' ] = $object_type; - foreach ( $terms as $term_id ) { - update_term_meta( $term_id, '_' . $prefix . $k, $opts ); - } - } - - return true; - } - - /** - * Called when this module is activated. - */ - public function activate_module() { - if ( $this->locations !== null ) { - foreach ( $this->locations as $k => $v ) { - if ( ! isset( $v['type'] ) || 'metabox' !== $v['type'] ) { - continue; - } - $this->set_virgin_tax_terms( $k ); - } - } - } - /** - * This iterates over all taxonomies that do not have a opengraph setting defined and sets the defaults. - * - * @param string $k The key against which the options will be determined/set. - */ - private function set_virgin_tax_terms( $k ) { - $prefix = $this->get_prefix( $k ); - $opts = $this->default_options( $k ); - $taxonomies = get_taxonomies( array( 'public' => true ), 'object' ); - if ( ! $taxonomies ) { - return; - } - foreach ( $taxonomies as $name => $tax ) { - $this->set_object_type_for_taxonomy( $prefix, $k, $name, $tax, true, null ); - - } - } - - /** - * Hook called after WordPress has been loaded. - * - * @since 2.4.14 - */ - public function init() { - $count_desc = __( ' characters. Open Graph allows up to a maximum of %1$s chars for the %2$s.', 'all-in-one-seo-pack' ); - // Create default options - $this->default_options = array( - 'scan_header' => array( - 'name' => __( 'Scan Header', 'all-in-one-seo-pack' ), - 'type' => 'custom', - 'save' => true, - ), - 'setmeta' => array( - 'name' => __( 'Use AIOSEO Title and Description', 'all-in-one-seo-pack' ), - 'type' => 'checkbox', - ), - 'key' => array( - 'name' => __( 'Facebook Admin ID', 'all-in-one-seo-pack' ), - 'default' => '', - 'type' => 'text', - ), - 'appid' => array( - 'name' => __( 'Facebook App ID', 'all-in-one-seo-pack' ), - 'default' => '', - 'type' => 'text', - ), - 'title_shortcodes' => array( - 'name' => __( 'Run Shortcodes In Title', 'all-in-one-seo-pack' ), - ), - 'description_shortcodes' => array( - 'name' => __( 'Run Shortcodes In Description', 'all-in-one-seo-pack' ), - ), - 'sitename' => array( - 'name' => __( 'Site Name', 'all-in-one-seo-pack' ), - 'default' => get_bloginfo( 'name' ), - 'type' => 'text', - ), - 'hometitle' => array( - 'name' => __( 'Home Title', 'all-in-one-seo-pack' ), - 'default' => '', - 'type' => 'textarea', - 'condshow' => array( - 'aiosp_opengraph_setmeta' => array( - 'lhs' => 'aiosp_opengraph_setmeta', - 'op' => '!=', - 'rhs' => 'on', - ), - ), - ), - 'description' => array( - 'name' => __( 'Home Description', 'all-in-one-seo-pack' ), - 'default' => '', - 'type' => 'textarea', - 'condshow' => array( - 'aiosp_opengraph_setmeta' => array( - 'lhs' => 'aiosp_opengraph_setmeta', - 'op' => '!=', - 'rhs' => 'on', - ), - ), - ), - 'homeimage' => array( - 'name' => __( 'Home Image', 'all-in-one-seo-pack' ), - 'type' => 'image', - ), - 'generate_descriptions' => array( - 'name' => __( 'Use Content For Autogenerated OG Descriptions', 'all-in-one-seo-pack' ), - 'default' => 0, - ), - 'defimg' => array( - 'name' => __( 'Select OG:Image Source', 'all-in-one-seo-pack' ), - 'type' => 'select', - 'initial_options' => array( - '' => __( 'Default Image' ), - 'featured' => __( 'Featured Image' ), - 'attach' => __( 'First Attached Image' ), - 'content' => __( 'First Image In Content' ), - 'custom' => __( 'Image From Custom Field' ), - 'author' => __( 'Post Author Image' ), - 'auto' => __( 'First Available Image' ), - ), - ), - 'fallback' => array( - 'name' => __( 'Use Default If No Image Found', 'all-in-one-seo-pack' ), - 'type' => 'checkbox', - ), - 'dimg' => array( - 'name' => __( 'Default OG:Image', 'all-in-one-seo-pack' ), - 'default' => AIOSEOP_PLUGIN_IMAGES_URL . 'default-user-image.png', - 'type' => 'image', - ), - 'dimgwidth' => array( - 'name' => __( 'Default Image Width', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - ), - 'dimgheight' => array( - 'name' => __( 'Default Image Height', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - ), - 'meta_key' => array( - 'name' => __( 'Use Custom Field For Image', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - ), - 'image' => array( - 'name' => __( 'Image', 'all-in-one-seo-pack' ), - 'type' => 'radio', - 'initial_options' => array( - 0 => '', - ), - ), - 'customimg' => array( - 'name' => __( 'Custom Image', 'all-in-one-seo-pack' ), - 'type' => 'image', - ), - 'imagewidth' => array( - 'name' => __( 'Specify Image Width', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - ), - 'imageheight' => array( - 'name' => __( 'Specify Image Height', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - ), - 'video' => array( - 'name' => __( 'Custom Video', 'all-in-one-seo-pack' ), - 'type' => 'text', - ), - 'videowidth' => array( - 'name' => __( 'Specify Video Width', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - 'condshow' => array( - 'aioseop_opengraph_settings_video' => array( - 'lhs' => 'aioseop_opengraph_settings_video', - 'op' => '!=', - 'rhs' => '', - ), - ), - ), - 'videoheight' => array( - 'name' => __( 'Specify Video Height', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - 'condshow' => array( - 'aioseop_opengraph_settings_video' => array( - 'lhs' => 'aioseop_opengraph_settings_video', - 'op' => '!=', - 'rhs' => '', - ), - ), - ), - 'defcard' => array( - 'name' => __( 'Default Twitter Card', 'all-in-one-seo-pack' ), - 'type' => 'select', - 'default' => 'summary', - 'initial_options' => array( - 'summary' => __( 'Summary', 'all-in-one-seo-pack' ), - 'summary_large_image' => __( 'Summary Large Image', 'all-in-one-seo-pack' ), - - /* - REMOVING THIS TWITTER CARD TYPE FROM SOCIAL META MODULE - 'photo' => __( 'Photo', 'all-in-one-seo-pack' ) - */ - ), - ), - 'setcard' => array( - 'name' => __( 'Twitter Card Type', 'all-in-one-seo-pack' ), - 'type' => 'select', - 'initial_options' => array( - 'summary_large_image' => __( 'Summary Large Image', 'all-in-one-seo-pack' ), - 'summary' => __( 'Summary', 'all-in-one-seo-pack' ), - - /* - REMOVING THIS TWITTER CARD TYPE FROM SOCIAL META MODULE - 'photo' => __( 'Photo', 'all-in-one-seo-pack' ) - */ - ), - ), - 'twitter_site' => array( - 'name' => __( 'Twitter Site', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - ), - 'twitter_creator' => array( - 'name' => __( 'Show Twitter Author', 'all-in-one-seo-pack' ), - ), - 'twitter_domain' => array( - 'name' => __( 'Twitter Domain', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - ), - 'customimg_twitter' => array( - 'name' => __( 'Custom Twitter Image', 'all-in-one-seo-pack' ), - 'type' => 'image', - ), - 'gen_tags' => array( - 'name' => __( 'Automatically Generate Article Tags', 'all-in-one-seo-pack' ), - ), - 'gen_keywords' => array( - 'name' => __( 'Use Keywords In Article Tags', 'all-in-one-seo-pack' ), - 'default' => 'on', - 'condshow' => array( 'aiosp_opengraph_gen_tags' => 'on' ), - ), - 'gen_categories' => array( - 'name' => __( 'Use Categories In Article Tags', 'all-in-one-seo-pack' ), - 'default' => 'on', - 'condshow' => array( 'aiosp_opengraph_gen_tags' => 'on' ), - ), - 'gen_post_tags' => array( - 'name' => __( 'Use Post Tags In Article Tags', 'all-in-one-seo-pack' ), - 'default' => 'on', - 'condshow' => array( 'aiosp_opengraph_gen_tags' => 'on' ), - ), - 'types' => array( - 'name' => __( 'Enable Facebook Meta for Post Types', 'all-in-one-seo-pack' ), - 'type' => 'multicheckbox', - 'default' => array( 'post' => 'post', 'page' => 'page' ), - 'initial_options' => $this->get_post_type_titles( array( '_builtin' => false ) ), - ), - 'title' => array( - 'name' => __( 'Title', 'all-in-one-seo-pack' ), - 'default' => '', - 'type' => 'text', - 'size' => 95, - 'count' => 1, - 'count_desc' => $count_desc, - ), - 'desc' => array( - 'name' => __( 'Description', 'all-in-one-seo-pack' ), - 'default' => '', - 'type' => 'textarea', - 'cols' => 250, - 'rows' => 4, - 'count' => 1, - 'count_desc' => $count_desc, - ), - 'category' => array( - 'name' => __( 'Facebook Object Type', 'all-in-one-seo-pack' ), - 'type' => 'select', - 'style' => '', - 'default' => '', - 'initial_options' => $this->fb_object_types, - ), - 'facebook_debug' => array( - 'name' => __( 'Facebook Debug', 'all-in-one-seo-pack' ), - 'type' => 'html', - 'save' => false, - 'default' => '' . __( 'Debug This Post', 'all-in-one-seo-pack' ) . '', - ), - 'section' => array( - 'name' => __( 'Article Section', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - 'condshow' => array( 'aioseop_opengraph_settings_category' => 'article' ), - ), - 'tag' => array( - 'name' => __( 'Article Tags', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - 'condshow' => array( 'aioseop_opengraph_settings_category' => 'article' ), - ), - 'facebook_publisher' => array( - 'name' => __( 'Show Facebook Publisher on Articles', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - ), - 'facebook_author' => array( - 'name' => __( 'Show Facebook Author on Articles', 'all-in-one-seo-pack' ), - ), - 'profile_links' => array( - 'name' => __( 'Social Profile Links', 'all-in-one-seo-pack' ), - 'type' => 'textarea', - 'cols' => 60, - 'rows' => 5, - ), - 'person_or_org' => array( - 'name' => __( 'Person or Organization?', 'all-in-one-seo-pack' ), - 'type' => 'radio', - 'initial_options' => array( - 'person' => __( 'Person', 'all-in-one-seo-pack' ), - 'org' => __( 'Organization', 'all-in-one-seo-pack' ), - ), - ), - 'social_name' => array( - 'name' => __( 'Associated Name', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - ), - ); - // load initial options / set defaults - $this->update_options(); - $display = array(); - if ( isset( $this->options['aiosp_opengraph_types'] ) && ! empty( $this->options['aiosp_opengraph_types'] ) ) { - $display = $this->options['aiosp_opengraph_types']; - } - $this->locations = array( - 'opengraph' => array( - 'name' => $this->name, - 'prefix' => 'aiosp_', - 'type' => 'settings', - 'options' => array( - 'scan_header', - 'setmeta', - 'key', - 'appid', - 'sitename', - 'title_shortcodes', - 'description_shortcodes', - 'hometitle', - 'description', - 'homeimage', - 'generate_descriptions', - 'defimg', - 'fallback', - 'dimg', - 'dimgwidth', - 'dimgheight', - 'meta_key', - 'defcard', - 'profile_links', - 'person_or_org', - 'social_name', - 'twitter_site', - 'twitter_creator', - 'twitter_domain', - 'gen_tags', - 'gen_keywords', - 'gen_categories', - 'gen_post_tags', - 'types', - 'facebook_publisher', - 'facebook_author', - ), - ), - 'settings' => array( - 'name' => __( 'Social Settings', 'all-in-one-seo-pack' ), - 'type' => 'metabox', - 'help_link' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/', - 'options' => array( - 'title', - 'desc', - 'image', - 'customimg', - 'imagewidth', - 'imageheight', - 'video', - 'videowidth', - 'videoheight', - 'category', - 'facebook_debug', - 'section', - 'tag', - 'setcard', - 'customimg_twitter', - ), - 'display' => apply_filters( 'aioseop_opengraph_display', $display ), - 'prefix' => 'aioseop_opengraph_', - ), - ); - $this->layout = array( - 'home' => array( - 'name' => __( 'Home Page Settings', 'all-in-one-seo-pack' ), - 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#use-aioseo-title-and-description', - 'options' => array( 'setmeta', 'sitename', 'hometitle', 'description', 'homeimage' ), - ), - 'image' => array( - 'name' => __( 'Image Settings', 'all-in-one-seo-pack' ), - 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#select-og-image-source', - 'options' => array( 'defimg', 'fallback', 'dimg', 'dimgwidth', 'dimgheight', 'meta_key' ), - ), - 'links' => array( - 'name' => __( 'Social Profile Links', 'all-in-one-seo-pack' ), - 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#social-profile-links', - 'options' => array( 'profile_links', 'person_or_org', 'social_name' ), - ), - 'facebook' => array( - 'name' => __( 'Facebook Settings', 'all-in-one-seo-pack' ), - 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#facebook-settings', - 'options' => array( - 'key', - 'appid', - 'types', - 'gen_tags', - 'gen_keywords', - 'gen_categories', - 'gen_post_tags', - 'facebook_publisher', - 'facebook_author', - ), - ), - 'twitter' => array( - 'name' => __( 'Twitter Settings', 'all-in-one-seo-pack' ), - 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#default-twitter-card', - 'options' => array( 'defcard', 'setcard', 'twitter_site', 'twitter_creator', 'twitter_domain' ), - ), - 'default' => array( - 'name' => __( 'Advanced Settings', 'all-in-one-seo-pack' ), - 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/', - 'options' => array(), // this is set below, to the remaining options -- pdb - ), - 'scan_meta' => array( - 'name' => __( 'Scan Social Meta', 'all-in-one-seo-pack' ), - 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#scan_meta', - 'options' => array( 'scan_header' ), - ), - ); - $other_options = array(); - foreach ( $this->layout as $k => $v ) { - $other_options = array_merge( $other_options, $v['options'] ); - } - - $this->layout['default']['options'] = array_diff( array_keys( $this->default_options ), $other_options ); - } - - /** - * Forces FaceBook OpenGraph to refresh its cache when a post is changed to - * - * @param $new_status - * @param $old_status - * @param $post - * - * @todo this and force_fb_refresh_update can probably have the remote POST extracted out. - * - * @see https://developers.facebook.com/docs/sharing/opengraph/using-objects#update - * @since 2.3.11 - */ - function force_fb_refresh_transition( $new_status, $old_status, $post ) { - if ( 'publish' !== $new_status ) { - return; - } - if ( 'future' !== $old_status ) { - return; - } - - $current_post_type = get_post_type(); - - // Only ping Facebook if Social SEO is enabled on this post type. - if ( $this->option_isset( 'types' ) && is_array( $this->options['aiosp_opengraph_types'] ) && in_array( $current_post_type, $this->options['aiosp_opengraph_types'] ) ) { - $post_url = aioseop_get_permalink( $post->ID ); - $endpoint = sprintf( - 'https://graph.facebook.com/?%s', http_build_query( - array( - 'id' => $post_url, - 'scrape' => true, - ) - ) - ); - wp_remote_post( $endpoint, array( 'blocking' => false ) ); - } - } - - /** - * Forces FaceBook OpenGraph refresh on update. - * - * @param $post_id - * @param $post_after - * - * @see https://developers.facebook.com/docs/sharing/opengraph/using-objects#update - * @since 2.3.11 - */ - function force_fb_refresh_update( $post_id, $post_after ) { - - $current_post_type = get_post_type(); - - // Only ping Facebook if Social SEO is enabled on this post type. - if ( 'publish' === $post_after->post_status && $this->option_isset( 'types' ) && is_array( $this->options['aiosp_opengraph_types'] ) && in_array( $current_post_type, $this->options['aiosp_opengraph_types'] ) ) { - $post_url = aioseop_get_permalink( $post_id ); - $endpoint = sprintf( - 'https://graph.facebook.com/?%s', http_build_query( - array( - 'id' => $post_url, - 'scrape' => true, - ) - ) - ); - wp_remote_post( $endpoint, array( 'blocking' => false ) ); - } - } - - function settings_page_init() { - add_filter( 'aiosp_output_option', array( $this, 'display_custom_options' ), 10, 2 ); - } - - function filter_options( $options, $location ) { - if ( $location == 'settings' ) { - $prefix = $this->get_prefix( $location ) . $location . '_'; - list( $legacy, $images ) = $this->get_all_images( $options ); - if ( isset( $options ) && isset( $options[ "{$prefix}image" ] ) ) { - $thumbnail = $options[ "{$prefix}image" ]; - if ( ctype_digit( (string) $thumbnail ) || ( $thumbnail == 'post' ) ) { - if ( $thumbnail == 'post' ) { - $thumbnail = $images['post1']; - } elseif ( ! empty( $legacy[ $thumbnail ] ) ) { - $thumbnail = $legacy[ $thumbnail ]; - } - } - $options[ "{$prefix}image" ] = $thumbnail; - } - if ( empty( $options[ $prefix . 'image' ] ) ) { - $img = array_keys( $images ); - if ( ! empty( $img ) && ! empty( $img[1] ) ) { - $options[ $prefix . 'image' ] = $img[1]; - } - } - } - - return $options; - } - - /** - * Applies filter to module settings. - * - * @since 2.3.11 - * @since 2.4.14 Added filter for description and title placeholders. - * @since 2.3.15 do_shortcode on description. - * - * @see [plugin]\admin\aioseop_module_class.php > display_options() - */ - function filter_settings( $settings, $location, $current ) { - global $aiosp, $post; - if ( $location == 'opengraph' || $location == 'settings' ) { - $prefix = $this->get_prefix( $location ) . $location . '_'; - if ( $location == 'opengraph' ) { - return $settings; - } - if ( $location == 'settings' ) { - list( $legacy, $settings[ $prefix . 'image' ]['initial_options'] ) = $this->get_all_images( $current ); - $opts = array( 'title', 'desc' ); - $current_post_type = get_post_type(); - if ( isset( $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ] ) ) { - $flat_type_list = array(); - foreach ( $this->fb_object_types as $k => $v ) { - if ( is_array( $v ) ) { - $flat_type_list = array_merge( $flat_type_list, $v ); - } else { - $flat_type_list[ $k ] = $v; - } - } - $default_fb_type = $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ]; - // https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/1013 - // if 'blog' is the selected type but because it is no longer a schema type, we use 'website' instead. - if ( 'blog' === $default_fb_type ) { - $default_fb_type = 'website'; - } - if ( isset( $flat_type_list[ $default_fb_type ] ) ) { - $default_fb_type = $flat_type_list[ $default_fb_type ]; - } - $settings[ $prefix . 'category' ]['initial_options'] = array_merge( - array( - $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ] => __( 'Default ', 'all-in-one-seo-pack' ) . ' - ' . $default_fb_type, - ), - $settings[ $prefix . 'category' ]['initial_options'] - ); - } - if ( isset( $this->options['aiosp_opengraph_defcard'] ) ) { - $settings[ $prefix . 'setcard' ]['default'] = $this->options['aiosp_opengraph_defcard']; - } - $info = $aiosp->get_page_snippet_info(); - $title = $info['title']; - $description = $info['description']; - - // Description options - if ( is_object( $post ) ) { - // Always show excerpt - $description = empty( $this->options['aiosp_opengraph_generate_descriptions'] ) - ? $aiosp->trim_excerpt_without_filters( - $aiosp->internationalize( preg_replace( '/\s+/', ' ', $post->post_excerpt ) ), - 1000 - ) - : $aiosp->trim_excerpt_without_filters( - $aiosp->internationalize( preg_replace( '/\s+/', ' ', $post->post_content ) ), - 1000 - ); - } - - // #1308 - we want to make sure we are ignoring php version only in the admin area while editing the post, so that it does not impact #932. - $screen = get_current_screen(); - $ignore_php_version = is_admin() && isset( $screen->id ) && 'post' == $screen->id; - - // Add filters - $description = apply_filters( 'aioseop_description', $description, false, $ignore_php_version ); - // Add placholders - $settings[ "{$prefix}title" ]['placeholder'] = apply_filters( 'aioseop_opengraph_placeholder', $title ); - $settings[ "{$prefix}desc" ]['placeholder'] = apply_filters( 'aioseop_opengraph_placeholder', $description ); - } - if ( isset( $current[ $prefix . 'setmeta' ] ) && $current[ $prefix . 'setmeta' ] ) { - foreach ( $opts as $opt ) { - if ( isset( $settings[ $prefix . $opt ] ) ) { - $settings[ $prefix . $opt ]['type'] = 'hidden'; - $settings[ $prefix . $opt ]['label'] = 'none'; - $settings[ $prefix . $opt ]['help_text'] = ''; - unset( $settings[ $prefix . $opt ]['count'] ); - } - } - } - } - - return $settings; - } - - /** - * Applies filter to module options. - * These will display in the "Social Settings" object tab. - * filter:{prefix}override_options - * - * @since 2.3.11 - * @since 2.4.14 Overrides empty og:type values. - * - * @see [plugin]\admin\aioseop_module_class.php > display_options() - * - * @global array $aioseop_options Plugin options. - * - * @param array $options Current options. - * @param string $location Location where filter is called. - * @param array $settings Settings. - * - * @return array - */ - function override_options( $options, $location, $settings ) { - global $aioseop_options; - // Prepare default and prefix - $prefix = $this->get_prefix( $location ) . $location . '_'; - $opts = array(); - - foreach ( $settings as $k => $v ) { - if ( $v['save'] ) { - $opts[ $k ] = $v['default']; - } - } - foreach ( $options as $k => $v ) { - switch ( $k ) { - case $prefix . 'category': - if ( empty( $v ) ) { - // Get post type - $type = isset( get_current_screen()->post_type ) - ? get_current_screen()->post_type - : null; - // Assign default from plugin options - if ( ! empty( $type ) - && isset( $aioseop_options['modules'] ) - && isset( $aioseop_options['modules']['aiosp_opengraph_options'] ) - && isset( $aioseop_options['modules']['aiosp_opengraph_options'][ 'aiosp_opengraph_' . $type . '_fb_object_type' ] ) - ) { - $options[ $prefix . 'category' ] = - $aioseop_options['modules']['aiosp_opengraph_options'][ 'aiosp_opengraph_' . $type . '_fb_object_type' ]; - } - } - break; - } - if ( $v === null ) { - unset( $options[ $k ] ); - } - } - $options = wp_parse_args( $options, $opts ); - - // https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/1013 - $post_types = $this->get_post_type_titles(); - foreach ( $post_types as $slug => $name ) { - $field = 'aiosp_opengraph_' . $slug . '_fb_object_type'; - if ( isset( $options[ $field ] ) && 'blog' === $options[ $field ] ) { - $options[ $field ] = 'website'; - } - } - - return $options; - } - - /** - * Applies filter to metabox settings before they are saved. - * Sets custom as default if a custom image is uploaded. - * filter:{prefix}filter_metabox_options - * filter:{prefix}filter_term_metabox_options - * - * @since 2.3.11 - * @since 2.4.14 Fixes for aioseop-pro #67 and other bugs found. - * - * @see [plugin]\admin\aioseop_module_class.php > save_post_data() - * @see [this file] > save_tax_data() - * - * @param array $options List of current options. - * @param string $location Location where filter is called. - * @param int $id Either post_id or term_id. - * - * @return array - */ - function filter_metabox_options( $options, $location, $post_id ) { - if ( $location == 'settings' ) { - $prefix = $this->get_prefix( $location ) . $location . '_'; - if ( isset( $options[ $prefix . 'customimg_checker' ] ) - && $options[ $prefix . 'customimg_checker' ] - ) { - $options[ $prefix . 'image' ] = $options[ $prefix . 'customimg' ]; - } - } - return $options; - } - - /** Custom settings **/ - function display_custom_options( $buf, $args ) { - if ( $args['name'] == 'aiosp_opengraph_scan_header' ) { - $buf .= '
'; - $args['options']['type'] = 'submit'; - $args['attr'] = " class='button-primary' "; - $args['value'] = $args['options']['default'] = __( 'Scan Now', 'all-in-one-seo-pack' ); - $buf .= __( 'Scan your site for duplicate social meta tags.', 'all-in-one-seo-pack' ); - $buf .= '

' . $this->get_option_html( $args ); - $buf .= '
'; - } - - return $buf; - } - - function add_attributes( $output ) { - // avoid having duplicate meta tags - $type = $this->type; - if ( empty( $type ) ) { - $type = 'website'; - } - $schema_types = array( - 'album' => 'MusicAlbum', - 'article' => 'Article', - 'bar' => 'BarOrPub', - 'blog' => 'Blog', - 'book' => 'Book', - 'cafe' => 'CafeOrCoffeeShop', - 'city' => 'City', - 'country' => 'Country', - 'episode' => 'Episode', - 'food' => 'FoodEvent', - 'game' => 'Game', - 'hotel' => 'Hotel', - 'landmark' => 'LandmarksOrHistoricalBuildings', - 'movie' => 'Movie', - 'product' => 'Product', - 'profile' => 'ProfilePage', - 'restaurant' => 'Restaurant', - 'school' => 'School', - 'sport' => 'SportsEvent', - 'website' => 'WebSite', - ); - - if ( ! empty( $schema_types[ $type ] ) ) { - $type = $schema_types[ $type ]; - } else { - $type = 'WebSite'; - } - - $attributes = apply_filters( - $this->prefix . 'attributes', array( - 'prefix="og: http://ogp.me/ns#"', - ) - ); - - foreach ( $attributes as $attr ) { - if ( strpos( $output, $attr ) === false ) { - $output .= "\n\t$attr "; - } - } - - return $output; - } - - /** - * Add our social meta. - * - * @since 1.0.0 - * @since 2.3.11.5 Support for multiple fb_admins. - * @since 2.3.13 Adds filter:aioseop_description on description. - * @since 2.4.14 Fixes for aioseop-pro #67. - * @since 2.3.15 Always do_shortcode on descriptions, removed for titles. - * - * @global object $post Current WP_Post object. - * @global object $aiosp All in one seo plugin object. - * @global array $aioseop_options All in one seo plugin options. - * @global object $wp_query WP_Query global instance. - */ - function add_meta() { - global $post, $aiosp, $aioseop_options, $wp_query; - $metabox = $this->get_current_options( array(), 'settings' ); - $key = $this->options['aiosp_opengraph_key']; - $key = $this->options['aiosp_opengraph_key']; - $dimg = $this->options['aiosp_opengraph_dimg']; - $current_post_type = get_post_type(); - $title = $description = $image = $video = ''; - $type = $this->type; - $sitename = $this->options['aiosp_opengraph_sitename']; - - $appid = isset( $this->options['aiosp_opengraph_appid'] ) ? $this->options['aiosp_opengraph_appid'] : ''; - - if ( ! empty( $aioseop_options['aiosp_hide_paginated_descriptions'] ) ) { - $first_page = false; - if ( $aiosp->get_page_number() < 2 ) { - $first_page = true; - } - } else { - $first_page = true; - } - $url = $aiosp->aiosp_mrt_get_url( $wp_query ); - $url = apply_filters( 'aioseop_canonical_url', $url ); - - $setmeta = $this->options['aiosp_opengraph_setmeta']; - $social_links = ''; - if ( is_front_page() ) { - $title = $this->options['aiosp_opengraph_hometitle']; - if ( $first_page ) { - $description = $this->options['aiosp_opengraph_description']; - if ( empty( $description ) ) { - $description = get_bloginfo( 'description' ); - } - } - if ( ! empty( $this->options['aiosp_opengraph_homeimage'] ) ) { - $thumbnail = $this->options['aiosp_opengraph_homeimage']; - } else { - $thumbnail = $this->options['aiosp_opengraph_dimg']; - } - - /* If Use AIOSEO Title and Desc Selected */ - if ( $setmeta ) { - $title = $aiosp->wp_title(); - if ( $first_page ) { - $description = $aiosp->get_aioseop_description( $post ); - } - } - - /* Add some defaults */ - if ( empty( $title ) ) { - $title = get_bloginfo( 'name' ); - } - if ( empty( $sitename ) ) { - $sitename = get_bloginfo( 'name' ); - } - - if ( empty( $description ) && $first_page && ! empty( $post ) && ! post_password_required( $post ) ) { - - if ( ! empty( $post->post_content ) || ! empty( $post->post_excerpt ) ) { - $description = $aiosp->trim_excerpt_without_filters( $aiosp->internationalize( preg_replace( '/\s+/', ' ', $post->post_excerpt ) ), 1000 ); - - if ( ! empty( $this->options['aiosp_opengraph_generate_descriptions'] ) ) { - $description = $aiosp->trim_excerpt_without_filters( $aiosp->internationalize( preg_replace( '/\s+/', ' ', $post->post_content ) ), 1000 ); - } - } - } - - if ( empty( $description ) && $first_page ) { - $description = get_bloginfo( 'description' ); - } - if ( ! empty( $this->options['aiosp_opengraph_profile_links'] ) ) { - $social_links = $this->options['aiosp_opengraph_profile_links']; - if ( ! empty( $this->options['aiosp_opengraph_social_name'] ) ) { - $social_name = $this->options['aiosp_opengraph_social_name']; - } else { - $social_name = ''; - } - if ( $this->options['aiosp_opengraph_person_or_org'] == 'person' ) { - $social_type = 'Person'; - } else { - $social_type = 'Organization'; - } - } - } elseif ( is_singular() && $this->option_isset( 'types' ) - && is_array( $this->options['aiosp_opengraph_types'] ) - && in_array( $current_post_type, $this->options['aiosp_opengraph_types'] ) - ) { - - if ( $type == 'article' ) { - if ( ! empty( $metabox['aioseop_opengraph_settings_section'] ) ) { - $section = $metabox['aioseop_opengraph_settings_section']; - } - if ( ! empty( $metabox['aioseop_opengraph_settings_tag'] ) ) { - $tag = $metabox['aioseop_opengraph_settings_tag']; - } - if ( ! empty( $this->options['aiosp_opengraph_facebook_publisher'] ) ) { - $publisher = $this->options['aiosp_opengraph_facebook_publisher']; - } - } - - if ( ! empty( $this->options['aiosp_opengraph_twitter_domain'] ) ) { - $domain = $this->options['aiosp_opengraph_twitter_domain']; - } - - if ( $type == 'article' && ! empty( $post ) ) { - if ( isset( $post->post_author ) && ! empty( $this->options['aiosp_opengraph_facebook_author'] ) ) { - $author = get_the_author_meta( 'facebook', $post->post_author ); - } - - if ( isset( $post->post_date_gmt ) ) { - $published_time = date( 'Y-m-d\TH:i:s\Z', mysql2date( 'U', $post->post_date_gmt ) ); - } - - if ( isset( $post->post_modified_gmt ) ) { - $modified_time = date( 'Y-m-d\TH:i:s\Z', mysql2date( 'U', $post->post_modified_gmt ) ); - } - } - - $image = $metabox['aioseop_opengraph_settings_image']; - $video = $metabox['aioseop_opengraph_settings_video']; - $title = $metabox['aioseop_opengraph_settings_title']; - $description = $metabox['aioseop_opengraph_settings_desc']; - - /* Add AIOSEO variables if Site Title and Desc from AIOSEOP not selected */ - global $aiosp; - if ( empty( $title ) ) { - $title = $aiosp->wp_title(); - } - if ( empty( $description ) ) { - $description = trim( strip_tags( get_post_meta( $post->ID, '_aioseop_description', true ) ) ); - } - - /* Add default title */ - if ( empty( $title ) ) { - $title = get_the_title(); - } - - // Add default description. - if ( empty( $description ) && ! post_password_required( $post ) ) { - - $description = $post->post_excerpt; - - if ( $this->options['aiosp_opengraph_generate_descriptions'] || empty( $description ) ) { - $description = $post->post_content; - } - } - if ( empty( $type ) ) { - $type = 'article'; - } - } elseif ( AIOSEOPPRO && ( is_category() || is_tag() || is_tax() ) ) { - if ( isset( $this->options['aioseop_opengraph_settings_category'] ) ) { - $type = $this->options['aioseop_opengraph_settings_category']; - } - if ( isset( $metabox['aioseop_opengraph_settings_category'] ) ) { - $type = $metabox['aioseop_opengraph_settings_category']; - } - if ( $type == 'article' ) { - if ( ! empty( $metabox['aioseop_opengraph_settings_section'] ) ) { - $section = $metabox['aioseop_opengraph_settings_section']; - } - if ( ! empty( $metabox['aioseop_opengraph_settings_tag'] ) ) { - $tag = $metabox['aioseop_opengraph_settings_tag']; - } - if ( ! empty( $this->options['aiosp_opengraph_facebook_publisher'] ) ) { - $publisher = $this->options['aiosp_opengraph_facebook_publisher']; - } - } - if ( ! empty( $this->options['aiosp_opengraph_twitter_domain'] ) ) { - $domain = $this->options['aiosp_opengraph_twitter_domain']; - } - if ( $type == 'article' && ! empty( $post ) ) { - if ( isset( $post->post_author ) && ! empty( $this->options['aiosp_opengraph_facebook_author'] ) ) { - $author = get_the_author_meta( 'facebook', $post->post_author ); - } - - if ( isset( $post->post_date_gmt ) ) { - $published_time = date( 'Y-m-d\TH:i:s\Z', mysql2date( 'U', $post->post_date_gmt ) ); - } - if ( isset( $post->post_modified_gmt ) ) { - $modified_time = date( 'Y-m-d\TH:i:s\Z', mysql2date( 'U', $post->post_modified_gmt ) ); - } - } - $image = $metabox['aioseop_opengraph_settings_image']; - $video = $metabox['aioseop_opengraph_settings_video']; - $title = $metabox['aioseop_opengraph_settings_title']; - $description = $metabox['aioseop_opengraph_settings_desc']; - /* Add AIOSEO variables if Site Title and Desc from AIOSEOP not selected */ - global $aiosp; - if ( empty( $title ) ) { - $title = $aiosp->wp_title(); - } - if ( empty( $description ) ) { - $term_id = isset( $_GET['tag_ID'] ) ? (int) $_GET['tag_ID'] : 0; - $term_id = $term_id ? $term_id : get_queried_object()->term_id; - $description = trim( strip_tags( get_term_meta( $term_id, '_aioseop_description', true ) ) ); - } - // Add default title - if ( empty( $title ) ) { - $title = get_the_title(); - } - // Add default description. - if ( empty( $description ) && ! post_password_required( $post ) ) { - $description = get_queried_object()->description; - } - if ( empty( $type ) ) { - // https://github.com/semperfiwebdesign/aioseop-pro/issues/321 - if ( AIOSEOPPRO && ( is_category() || is_tag() || is_tax() ) ) { - $og_options = $aioseop_options['modules'][ $this->prefix . 'options' ]; - $current_post_type = get_post_type(); - // check if the post type's object type is set. - if ( isset( $og_options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ] ) ) { - $type = $og_options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ]; - } elseif ( in_array( $current_post_type, array( 'post', 'page' ) ) ) { - $type = 'article'; - } - } else { - $type = 'website'; - } - } - } elseif ( is_home() && ! is_front_page() ) { - // This is the blog page but not the homepage. - global $aiosp; - $image = $metabox['aioseop_opengraph_settings_image']; - $video = $metabox['aioseop_opengraph_settings_video']; - $title = $metabox['aioseop_opengraph_settings_title']; - $description = $metabox['aioseop_opengraph_settings_desc']; - - if ( empty( $description ) ) { - // If there's not social description, fall back to the SEO description. - $description = trim( strip_tags( get_post_meta( get_option( 'page_for_posts' ), '_aioseop_description', true ) ) ); - } - if ( empty( $title ) ) { - $title = $aiosp->wp_title(); - } - } else { - return; - } - - if ( $type === 'article' && ! empty( $post ) && is_singular() ) { - if ( ! empty( $this->options['aiosp_opengraph_gen_tags'] ) ) { - if ( ! empty( $this->options['aiosp_opengraph_gen_keywords'] ) ) { - $keywords = $aiosp->get_main_keywords(); - $keywords = $this->apply_cf_fields( $keywords ); - $keywords = apply_filters( 'aioseop_keywords', $keywords ); - if ( ! empty( $keywords ) && ! empty( $tag ) ) { - $tag .= ',' . $keywords; - } elseif ( empty( $tag ) ) { - $tag = $keywords; - } - } - $tag = $aiosp->keyword_string_to_list( $tag ); - if ( ! empty( $this->options['aiosp_opengraph_gen_categories'] ) ) { - $tag = array_merge( $tag, $aiosp->get_all_categories( $post->ID ) ); - } - if ( ! empty( $this->options['aiosp_opengraph_gen_post_tags'] ) ) { - $tag = array_merge( $tag, $aiosp->get_all_tags( $post->ID ) ); - } - } - if ( ! empty( $tag ) ) { - $tag = $aiosp->clean_keyword_list( $tag ); - } - } - - if ( ! empty( $this->options['aiosp_opengraph_title_shortcodes'] ) ) { - $title = do_shortcode( $title ); - } - if ( ! empty( $description ) ) { - $description = $aiosp->internationalize( preg_replace( '/\s+/', ' ', $description ) ); - if ( ! empty( $this->options['aiosp_opengraph_description_shortcodes'] ) ) { - $description = do_shortcode( $description ); - } - $description = $aiosp->trim_excerpt_without_filters( $description, 1000 ); - } - - $title = $this->apply_cf_fields( $title ); - $description = $this->apply_cf_fields( $description ); - - /* Data Validation */ - $title = strip_tags( esc_attr( $title ) ); - $sitename = strip_tags( esc_attr( $sitename ) ); - $description = strip_tags( esc_attr( $description ) ); - - if ( empty( $thumbnail ) && ! empty( $image ) ) { - $thumbnail = $image; - } - - // Add user supplied default image. - if ( empty( $thumbnail ) ) { - if ( empty( $this->options['aiosp_opengraph_defimg'] ) ) { - $thumbnail = $this->options['aiosp_opengraph_dimg']; - } else { - $img_type = $this->options['aiosp_opengraph_defimg']; - if ( ! empty( $post ) ) { - // Customize the type of image per post/post_type. - $img_type = apply_filters( $this->prefix . 'default_image_type', $img_type, $post, $type ); - } - switch ( $img_type ) { - case 'featured': - $thumbnail = $this->get_the_image_by_post_thumbnail(); - break; - case 'attach': - $thumbnail = $this->get_the_image_by_attachment(); - break; - case 'content': - $thumbnail = $this->get_the_image_by_scan(); - break; - case 'custom': - $meta_key = $this->options['aiosp_opengraph_meta_key']; - if ( ! empty( $meta_key ) && ! empty( $post ) ) { - $meta_key = explode( ',', $meta_key ); - $thumbnail = $this->get_the_image_by_meta_key( - array( - 'post_id' => $post->ID, - 'meta_key' => $meta_key, - ) - ); - } - break; - case 'auto': - $thumbnail = $this->get_the_image(); - break; - case 'author': - $thumbnail = $this->get_the_image_by_author(); - break; - default: - $thumbnail = $this->options['aiosp_opengraph_dimg']; - } - } - } - - if ( empty( $thumbnail ) && ! empty( $this->options['aiosp_opengraph_fallback'] ) ) { - $thumbnail = $this->options['aiosp_opengraph_dimg']; - if ( ! empty( $post ) ) { - // Customize the default image per post/post_type. - $thumbnail = apply_filters( $this->prefix . 'default_image', $thumbnail, $post, $type ); - } - } - - if ( ! empty( $thumbnail ) ) { - $thumbnail = esc_url( $thumbnail ); - $thumbnail = set_url_scheme( $thumbnail ); - } - - $width = $height = ''; - if ( ! empty( $thumbnail ) ) { - if ( ! empty( $metabox['aioseop_opengraph_settings_imagewidth'] ) ) { - $width = $metabox['aioseop_opengraph_settings_imagewidth']; - } - if ( ! empty( $metabox['aioseop_opengraph_settings_imageheight'] ) ) { - $height = $metabox['aioseop_opengraph_settings_imageheight']; - } - if ( empty( $width ) && ! empty( $this->options['aiosp_opengraph_dimgwidth'] ) ) { - $width = $this->options['aiosp_opengraph_dimgwidth']; - } - if ( empty( $height ) && ! empty( $this->options['aiosp_opengraph_dimgheight'] ) ) { - $height = $this->options['aiosp_opengraph_dimgheight']; - } - } - - if ( ! empty( $video ) ) { - if ( ! empty( $metabox['aioseop_opengraph_settings_videowidth'] ) ) { - $videowidth = $metabox['aioseop_opengraph_settings_videowidth']; - } - if ( ! empty( $metabox['aioseop_opengraph_settings_videoheight'] ) ) { - $videoheight = $metabox['aioseop_opengraph_settings_videoheight']; - } - } - - $card = 'summary'; - if ( ! empty( $this->options['aiosp_opengraph_defcard'] ) ) { - $card = $this->options['aiosp_opengraph_defcard']; - } - - if ( ! empty( $metabox['aioseop_opengraph_settings_setcard'] ) ) { - $card = $metabox['aioseop_opengraph_settings_setcard']; - } - - // support for changing legacy twitter cardtype-photo to summary large image - if ( $card == 'photo' ) { - $card = 'summary_large_image'; - } - - $site = $domain = $creator = ''; - - if ( ! empty( $this->options['aiosp_opengraph_twitter_site'] ) ) { - $site = $this->options['aiosp_opengraph_twitter_site']; - $site = AIOSEOP_Opengraph_Public::prepare_twitter_username( $site ); - } - - if ( ! empty( $this->options['aiosp_opengraph_twitter_domain'] ) ) { - $domain = $this->options['aiosp_opengraph_twitter_domain']; - } - - if ( ! empty( $post ) && isset( $post->post_author ) && ! empty( $this->options['aiosp_opengraph_twitter_creator'] ) ) { - $creator = get_the_author_meta( 'twitter', $post->post_author ); - $creator = AIOSEOP_Opengraph_Public::prepare_twitter_username( $creator ); - } - - if ( ! empty( $thumbnail ) ) { - $twitter_thumbnail = $thumbnail; // Default Twitter image if custom isn't set. - } - - if ( isset( $metabox['aioseop_opengraph_settings_customimg_twitter'] ) && ! empty( $metabox['aioseop_opengraph_settings_customimg_twitter'] ) ) { - // Set Twitter image from custom. - $twitter_thumbnail = set_url_scheme( $metabox['aioseop_opengraph_settings_customimg_twitter'] ); - } - - // Apply last filters. - $description = apply_filters( 'aioseop_description', $description ); - - $meta = array( - 'facebook' => array( - 'title' => 'og:title', - 'type' => 'og:type', - 'url' => 'og:url', - 'thumbnail' => 'og:image', - 'width' => 'og:image:width', - 'height' => 'og:image:height', - 'video' => 'og:video', - 'videowidth' => 'og:video:width', - 'videoheight' => 'og:video:height', - 'sitename' => 'og:site_name', - 'key' => 'fb:admins', - 'appid' => 'fb:app_id', - 'description' => 'og:description', - 'section' => 'article:section', - 'tag' => 'article:tag', - 'publisher' => 'article:publisher', - 'author' => 'article:author', - 'published_time' => 'article:published_time', - 'modified_time' => 'article:modified_time', - ), - 'twitter' => array( - 'card' => 'twitter:card', - 'site' => 'twitter:site', - 'creator' => 'twitter:creator', - 'domain' => 'twitter:domain', - 'title' => 'twitter:title', - 'description' => 'twitter:description', - 'twitter_thumbnail' => 'twitter:image', - ), - ); - - // Only show if "use schema.org markup is checked". - if ( ! empty( $aioseop_options['aiosp_schema_markup'] ) ) { - $meta['google+'] = array( 'thumbnail' => 'image' ); - } - - $tags = array( - 'facebook' => array( 'name' => 'property', 'value' => 'content' ), - 'twitter' => array( 'name' => 'name', 'value' => 'content' ), - 'google+' => array( 'name' => 'itemprop', 'value' => 'content' ), - ); - - foreach ( $meta as $t => $data ) { - foreach ( $data as $k => $v ) { - if ( empty( $$k ) ) { - $$k = ''; - } - $filtered_value = $$k; - $filtered_value = apply_filters( $this->prefix . 'meta', $filtered_value, $t, $k ); - if ( ! empty( $filtered_value ) ) { - if ( ! is_array( $filtered_value ) ) { - $filtered_value = array( $filtered_value ); - } - - /** - * This is to accomodate multiple fb:admins on separate lines. - * @TODO Eventually we'll want to put this in its own function so things like images work too. - */ - if ( 'key' === $k ) { - $fbadmins = explode( ',', str_replace( ' ', '', $filtered_value[0] ) ); // Trim spaces then turn comma-separated values into an array. - foreach ( $fbadmins as $fbadmin ) { - echo '' . "\n"; - } - } else { - // For everything else. - foreach ( $filtered_value as $f ) { - // #1363: use esc_attr( $f ) instead of htmlspecialchars_decode( $f, ENT_QUOTES ) - echo '' . "\n"; - } - } - } - } - } - $social_link_schema = ''; - if ( ! empty( $social_links ) ) { - $home_url = esc_url( get_home_url() ); - $social_links = explode( "\n", $social_links ); - foreach ( $social_links as $k => $v ) { - $v = trim( $v ); - if ( empty( $v ) ) { - unset( $social_links[ $k ] ); - } else { - $v = esc_url( $v ); - $social_links[ $k ] = $v; - } - } - $social_links = join( '","', $social_links ); - $social_link_schema = << -{ "@context" : "http://schema.org", - "@type" : "{$social_type}", - "name" : "{$social_name}", - "url" : "{$home_url}", - "sameAs" : ["{$social_links}"] -} - - -END; - } - - // Only show if "use schema.org markup is checked". - if ( ! empty( $aioseop_options['aiosp_schema_markup'] ) ) { - echo apply_filters( 'aiosp_opengraph_social_link_schema', $social_link_schema ); - } - } - - /** - * Do / adds opengraph properties to meta. - * @since 2.3.11 - * - * @global array $aioseop_options AIOSEOP plugin options. - */ - public function do_opengraph() { - global $aioseop_options; - if ( ! empty( $aioseop_options ) - && ! empty( $aioseop_options['aiosp_schema_markup'] ) - ) { - add_filter( 'language_attributes', array( &$this, 'add_attributes' ) ); - } - if ( ! defined( 'DOING_AJAX' ) ) { - add_action( 'aioseop_modules_wp_head', array( &$this, 'add_meta' ), 5 ); - // Add social meta to AMP plugin. - if ( apply_filters( 'aioseop_enable_amp_social_meta', true ) === true ) { - add_action( 'amp_post_template_head', array( &$this, 'add_meta' ), 12 ); - } - } - } - - /** - * Set up types. - * - * @since ? - * @since 2.3.15 Change to website for homepage and blog post index page, default to object. - */ - function type_setup() { - $this->type = 'object'; // Default to type object if we don't have some other rule. - - if ( is_home() || is_front_page() ) { - $this->type = 'website'; // Home page and blog page should be website. - } elseif ( is_singular() && $this->option_isset( 'types' ) ) { - $metabox = $this->get_current_options( array(), 'settings' ); - $current_post_type = get_post_type(); - if ( ! empty( $metabox['aioseop_opengraph_settings_category'] ) ) { - $this->type = $metabox['aioseop_opengraph_settings_category']; - } elseif ( isset( $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ] ) ) { - $this->type = $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ]; - } - } - } - - /** - * Inits hooks and others for admin init. - * action:admin_init. - * - * @since 2.3.11 - * @since 2.4.14 Refactored function name, and new filter added for defaults and missing term metabox. - */ - function admin_init() { - add_filter( $this->prefix . 'display_settings', array( &$this, 'filter_settings' ), 10, 3 ); - add_filter( $this->prefix . 'override_options', array( &$this, 'override_options' ), 10, 3 ); - add_filter( - $this->get_prefix( 'settings' ) . 'default_options', array( - &$this, - 'filter_default_options', - ), 10, 2 - ); - add_filter( - $this->get_prefix( 'settings' ) . 'filter_metabox_options', array( - &$this, - 'filter_metabox_options', - ), 10, 3 - ); - add_filter( - $this->get_prefix( 'settings' ) . 'filter_term_metabox_options', array( - &$this, - 'filter_metabox_options', - ), 10, 3 - ); - $post_types = $this->get_post_type_titles(); - $rempost = array( - 'revision' => 1, - 'nav_menu_item' => 1, - 'custom_css' => 1, - 'customize_changeset' => 1, - ); - $post_types = array_diff_key( $post_types, $rempost ); - $this->default_options['types']['initial_options'] = $post_types; - foreach ( $post_types as $slug => $name ) { - $field = $slug . '_fb_object_type'; - $this->default_options[ $field ] = array( - 'name' => "$name " . __( 'Object Type', 'all-in-one-seo-pack' ) . "
($slug)", - 'type' => 'select', - 'style' => '', - 'initial_options' => $this->fb_object_types, - 'default' => 'article', - 'condshow' => array( 'aiosp_opengraph_types\[\]' => $slug ), - ); - $this->help_text[ $field ] = __( 'Choose a default value that best describes the content of your post type.', 'all-in-one-seo-pack' ); - $this->help_anchors[ $field ] = '#content-object-types'; - $this->locations['opengraph']['options'][] = $field; - $this->layout['facebook']['options'][] = $field; - } - $this->setting_options(); - $this->add_help_text_links(); - - } - - function get_all_images( $options = null, $p = null ) { - static $img = array(); - if ( ! is_array( $options ) ) { - $options = array(); - } - if ( ! empty( $this->options['aiosp_opengraph_meta_key'] ) ) { - $options['meta_key'] = $this->options['aiosp_opengraph_meta_key']; - } - if ( empty( $img ) ) { - $size = apply_filters( 'post_thumbnail_size', 'large' ); - $default = $this->get_the_image_by_default(); - if ( ! empty( $default ) ) { - $default = set_url_scheme( $default ); - $img[ $default ] = 0; - } - $img = array_merge( $img, parent::get_all_images( $options, null ) ); - } - - if ( ! empty( $options ) && ! empty( $options['aioseop_opengraph_settings_customimg'] ) ) { - $img[ $options['aioseop_opengraph_settings_customimg'] ] = 'customimg'; - } - - if ( ! empty( $options ) && ! empty( $options['aioseop_opengraph_settings_customimg'] ) ) { - $img[ $options['aioseop_opengraph_settings_customimg'] ] = 'customimg'; - $img[ $options['aioseop_opengraph_settings_customimg_twitter'] ] = 'customimg_twitter'; - } - - if ( $author_img = $this->get_the_image_by_author( $p ) ) { - $image['author'] = $author_img; - } - $image = array_flip( $img ); - $images = array(); - if ( ! empty( $image ) ) { - foreach ( $image as $k => $v ) { - $images[ $v ] = ''; - } - } - - return array( $image, $images ); - } - - function get_the_image_by_author( $options = null, $p = null ) { - if ( $p === null ) { - global $post; - } else { - $post = $p; - } - if ( ! empty( $post ) && ! empty( $post->post_author ) ) { - $matches = array(); - $get_avatar = get_avatar( $post->post_author, 300 ); - if ( preg_match( "/src='(.*?)'/i", $get_avatar, $matches ) ) { - return $matches[1]; - } - } - - return false; - } - - function get_the_image( $options = null, $p = null ) { - $meta_key = $this->options['aiosp_opengraph_meta_key']; - - return parent::get_the_image( array( 'meta_key' => $meta_key ), $p ); - } - - function get_the_image_by_default( $args = array() ) { - return $this->options['aiosp_opengraph_dimg']; - } - - function settings_update() { - - } - - /** - * Admin Enqueue Scripts - * - * Add hook in \All_in_One_SEO_Pack_Module::enqueue_metabox_scripts - Bails adding hook if not on target valid screen. - * Add hook in \All_in_One_SEO_Pack_Module::add_page_hooks - Function itself is hooked based on the screen_id/page. - * - * @since 2.9.2 - * - * @see 'admin_enqueue_scripts' hook - * @link https://developer.wordpress.org/reference/hooks/admin_enqueue_scripts/ - * - * @param string $hook_suffix - */ - public function admin_enqueue_scripts( $hook_suffix ) { - wp_enqueue_script( - 'aioseop-opengraph-script', - AIOSEOP_PLUGIN_URL . 'js/modules/aioseop_opengraph.js', - array(), - AIOSEOP_VERSION - ); - - // Dev note: If certain JS files need to be restricted to select screens, then follow concept - // used in `All_in_One_SEO_Pack::admin_enqueue_scripts()` (v2.9.1); which uses the `$hook_suffix` - // and a switch-case. This also helps prevent unnessecarily processing localized data when it isn't needed. - parent::admin_enqueue_scripts( $hook_suffix ); - } - - /** - * Enqueue our file upload scripts and styles. - * @param $hook - */ - function og_admin_enqueue_scripts( $hook ) { - - if ( 'all-in-one-seo_page_aiosp_opengraph' != $hook && 'term.php' != $hook ) { - // Only enqueue if we're on the social module settings page. - return; - } - - wp_enqueue_script( 'media-upload' ); - wp_enqueue_script( 'thickbox' ); - wp_enqueue_style( 'thickbox' ); - wp_enqueue_media(); - } - - function save_tax_data( $term_id, $tt_id, $taxonomy ) { - static $update = false; - if ( $update ) { - return; - } - if ( $this->locations !== null ) { - foreach ( $this->locations as $k => $v ) { - if ( isset( $v['type'] ) && ( $v['type'] === 'metabox' ) ) { - $opts = $this->default_options( $k ); - $options = array(); - $update = false; - foreach ( $opts as $l => $o ) { - if ( isset( $_POST[ $l ] ) ) { - $options[ $l ] = stripslashes_deep( $_POST[ $l ] ); - $options[ $l ] = esc_attr( $options[ $l ] ); - $update = true; - } - } - if ( $update ) { - $prefix = $this->get_prefix( $k ); - $options = apply_filters( $prefix . 'filter_term_metabox_options', $options, $k, $term_id ); - update_term_meta( $term_id, '_' . $prefix . $k, $options ); - } - } - } - } - } - - /** - * Returns the placeholder filtered and ready for DOM display. - * filter:aioseop_opengraph_placeholder - * @since 2.4.14 - * - * @param mixed $placeholder Placeholder to be filtered. - * @param string $type Type of the value to be filtered. - * - * @return string - */ - public function filter_placeholder( $placeholder, $type = 'text' ) { - return strip_tags( trim( $placeholder ) ); - } - - /** - * Returns filtered default options. - * filter:{prefix}default_options - * @since 2.4.13 - * - * @param array $options Default options. - * @param string $location Location. - * - * @return array - */ - public function filter_default_options( $options, $location ) { - if ( $location === 'settings' ) { - $prefix = $this->get_prefix( $location ) . $location . '_'; - // Add image checker as default - $options[ $prefix . 'customimg_checker' ] = 0; - } - return $options; - } - } -} +name = __( 'Social Meta', 'all-in-one-seo-pack' ); // Human-readable name of the plugin + $this->prefix = 'aiosp_opengraph_'; // option prefix + $this->file = __FILE__; // the current file + $this->fb_object_types = array( + 'Activities' => array( + 'activity' => __( 'Activity', 'all-in-one-seo-pack' ), + 'sport' => __( 'Sport', 'all-in-one-seo-pack' ), + ), + 'Businesses' => array( + 'bar' => __( 'Bar', 'all-in-one-seo-pack' ), + 'company' => __( 'Company', 'all-in-one-seo-pack' ), + 'cafe' => __( 'Cafe', 'all-in-one-seo-pack' ), + 'hotel' => __( 'Hotel', 'all-in-one-seo-pack' ), + 'restaurant' => __( 'Restaurant', 'all-in-one-seo-pack' ), + ), + 'Groups' => array( + 'cause' => __( 'Cause', 'all-in-one-seo-pack' ), + 'sports_league' => __( 'Sports League', 'all-in-one-seo-pack' ), + 'sports_team' => __( 'Sports Team', 'all-in-one-seo-pack' ), + ), + 'Organizations' => array( + 'band' => __( 'Band', 'all-in-one-seo-pack' ), + 'government' => __( 'Government', 'all-in-one-seo-pack' ), + 'non_profit' => __( 'Non Profit', 'all-in-one-seo-pack' ), + 'school' => __( 'School', 'all-in-one-seo-pack' ), + 'university' => __( 'University', 'all-in-one-seo-pack' ), + ), + 'People' => array( + 'actor' => __( 'Actor', 'all-in-one-seo-pack' ), + 'athlete' => __( 'Athlete', 'all-in-one-seo-pack' ), + 'author' => __( 'Author', 'all-in-one-seo-pack' ), + 'director' => __( 'Director', 'all-in-one-seo-pack' ), + 'musician' => __( 'Musician', 'all-in-one-seo-pack' ), + 'politician' => __( 'Politician', 'all-in-one-seo-pack' ), + 'profile' => __( 'Profile', 'all-in-one-seo-pack' ), + 'public_figure' => __( 'Public Figure', 'all-in-one-seo-pack' ), + ), + 'Places' => array( + 'city' => __( 'City', 'all-in-one-seo-pack' ), + 'country' => __( 'Country', 'all-in-one-seo-pack' ), + 'landmark' => __( 'Landmark', 'all-in-one-seo-pack' ), + 'state_province' => __( 'State Province', 'all-in-one-seo-pack' ), + ), + 'Products and Entertainment' => array( + 'album' => __( 'Album', 'all-in-one-seo-pack' ), + 'book' => __( 'Book', 'all-in-one-seo-pack' ), + 'drink' => __( 'Drink', 'all-in-one-seo-pack' ), + 'food' => __( 'Food', 'all-in-one-seo-pack' ), + 'game' => __( 'Game', 'all-in-one-seo-pack' ), + 'movie' => __( 'Movie', 'all-in-one-seo-pack' ), + 'product' => __( 'Product', 'all-in-one-seo-pack' ), + 'song' => __( 'Song', 'all-in-one-seo-pack' ), + 'tv_show' => __( 'TV Show', 'all-in-one-seo-pack' ), + 'episode' => __( 'Episode', 'all-in-one-seo-pack' ), + ), + 'Websites' => array( + 'article' => __( 'Article', 'all-in-one-seo-pack' ), + 'website' => __( 'Website', 'all-in-one-seo-pack' ), + ), + ); + parent::__construct(); + + $this->help_text = array( + 'setmeta' => __( 'Checking this box will use the Home Title and Home Description set in All in One SEO Pack, General Settings as the Open Graph title and description for your home page.', 'all-in-one-seo-pack' ), + 'key' => __( 'Enter your Facebook Admin ID here. You can enter multiple IDs separated by a comma. You can look up your Facebook ID using this tool http://findmyfbid.com/', 'all-in-one-seo-pack' ), + 'appid' => __( 'Enter your Facebook App ID here. Information about how to get your Facebook App ID can be found at https://developers.facebook.com/docs/apps/register', 'all-in-one-seo-pack' ), + 'title_shortcodes' => __( 'Run shortcodes that appear in social title meta tags.', 'all-in-one-seo-pack' ), + 'description_shortcodes' => __( 'Run shortcodes that appear in social description meta tags.', 'all-in-one-seo-pack' ), + 'sitename' => __( 'The Site Name is the name that is used to identify your website.', 'all-in-one-seo-pack' ), + 'hometitle' => __( 'The Home Title is the Open Graph title for your home page.', 'all-in-one-seo-pack' ), + 'description' => __( 'The Home Description is the Open Graph description for your home page.', 'all-in-one-seo-pack' ), + 'homeimage' => __( 'The Home Image is the Open Graph image for your home page.', 'all-in-one-seo-pack' ), + 'generate_descriptions' => __( 'This option will auto generate your Open Graph descriptions from your post content instead of your post excerpt. WooCommerce users should read the documentation regarding this setting.', 'all-in-one-seo-pack' ), + 'defimg' => __( 'This option lets you choose which image will be displayed by default for the Open Graph image. You may override this on individual posts.', 'all-in-one-seo-pack' ), + 'fallback' => __( 'This option lets you fall back to the default image if no image could be found above.', 'all-in-one-seo-pack' ), + 'dimg' => __( 'This option sets a default image that can be used for the Open Graph image. You can upload an image, select an image from your Media Library or paste the URL of an image here.', 'all-in-one-seo-pack' ), + 'dimgwidth' => __( 'This option lets you set a default width for your images, where unspecified.', 'all-in-one-seo-pack' ), + 'dimgheight' => __( 'This option lets you set a default height for your images, where unspecified.', 'all-in-one-seo-pack' ), + 'meta_key' => __( 'Enter the name of a custom field (or multiple field names separated by commas) to use that field to specify the Open Graph image on Pages or Posts.', 'all-in-one-seo-pack' ), + 'image' => __( 'This option lets you select the Open Graph image that will be used for this Page or Post, overriding the default settings.', 'all-in-one-seo-pack' ), + 'customimg' => __( 'This option lets you upload an image to use as the Open Graph image for this Page or Post.', 'all-in-one-seo-pack' ), + 'imagewidth' => __( 'Enter the width for your Open Graph image in pixels (i.e. 600).', 'all-in-one-seo-pack' ), + 'imageheight' => __( 'Enter the height for your Open Graph image in pixels (i.e. 600).', 'all-in-one-seo-pack' ), + 'video' => __( 'This option lets you specify a link to the Open Graph video used on this Page or Post.', 'all-in-one-seo-pack' ), + 'videowidth' => __( 'Enter the width for your Open Graph video in pixels (i.e. 600).', 'all-in-one-seo-pack' ), + 'videoheight' => __( 'Enter the height for your Open Graph video in pixels (i.e. 600).', 'all-in-one-seo-pack' ), + 'defcard' => __( 'Select the default type of Twitter Card to display.', 'all-in-one-seo-pack' ), + 'setcard' => __( 'Select the Twitter Card type to use for this Page or Post, overriding the default setting.', 'all-in-one-seo-pack' ), + 'twitter_site' => __( 'Enter the Twitter username associated with your website here.', 'all-in-one-seo-pack' ), + 'twitter_creator' => __( 'Allows your authors to be identified by their Twitter usernames as content creators on the Twitter cards for their posts.', 'all-in-one-seo-pack' ), + 'twitter_domain' => __( 'Enter the name of your website here.', 'all-in-one-seo-pack' ), + 'customimg_twitter' => __( 'This option lets you upload an image to use as the Twitter image for this Page or Post.', 'all-in-one-seo-pack' ), + 'gen_tags' => __( 'Automatically generate article tags for Facebook type article when not provided.', 'all-in-one-seo-pack' ), + 'gen_keywords' => __( 'Use keywords in generated article tags.', 'all-in-one-seo-pack' ), + 'gen_categories' => __( 'Use categories in generated article tags.', 'all-in-one-seo-pack' ), + 'gen_post_tags' => __( 'Use post tags in generated article tags.', 'all-in-one-seo-pack' ), + 'types' => __( 'Select which Post Types you want to use All in One SEO Pack to set Open Graph meta values for.', 'all-in-one-seo-pack' ), + 'title' => __( 'This is the Open Graph title of this Page or Post.', 'all-in-one-seo-pack' ), + 'desc' => __( 'This is the Open Graph description of this Page or Post.', 'all-in-one-seo-pack' ), + 'category' => __( 'Select the Open Graph type that best describes the content of this Page or Post.', 'all-in-one-seo-pack' ), + 'facebook_debug' => __( 'Press this button to have Facebook re-fetch and debug this page.', 'all-in-one-seo-pack' ), + 'section' => __( 'This Open Graph meta allows you to add a general section name that best describes this content.', 'all-in-one-seo-pack' ), + 'tag' => __( 'This Open Graph meta allows you to add a list of keywords that best describe this content.', 'all-in-one-seo-pack' ), + 'facebook_publisher' => __( 'Link articles to the Facebook page associated with your website.', 'all-in-one-seo-pack' ), + 'facebook_author' => __( 'Allows your authors to be identified by their Facebook pages as content authors on the Opengraph meta for their articles.', 'all-in-one-seo-pack' ), + 'person_or_org' => __( 'Are the social profile links for your website for a person or an organization?', 'all-in-one-seo-pack' ), + 'profile_links' => __( "Add URLs for your website's social profiles here (Facebook, Twitter, Google+, Instagram, LinkedIn), one per line.", 'all-in-one-seo-pack' ), + 'social_name' => __( 'Add the name of the person or organization who owns these profiles.', 'all-in-one-seo-pack' ), + ); + + $this->help_anchors = array( + 'title_shortcodes' => '#run-shortcodes-in-title', + 'description_shortcodes' => '#run-shortcodes-in-description', + 'generate_descriptions' => '#auto-generate-og-descriptions', + 'setmeta' => '#use-aioseo-title-and-description', + 'sitename' => '#site-name', + 'hometitle' => '#home-title-and-description', + 'description' => '#home-title-and-description', + 'homeimage' => '#home-image', + 'defimg' => '#select-og-image-source', + 'fallback' => '#use-default-if-no-image-found', + 'dimg' => '#default-og-image', + 'dimgwidth' => '#default-image-width', + 'dimgheight' => '#default-image-height', + 'meta_key' => '#use-custom-field-for-image', + 'profile_links' => '#social-profile-links', + 'person_or_org' => '#social-profile-links', + 'social_name' => '#social-profile-links', + 'key' => '#facebook-admin-id', + 'appid' => '#facebook-app-id', + 'gen_tags' => '#automatically-generate-article-tags', + 'gen_keywords' => '#use-keywords-in-article-tags', + 'gen_categories' => '#use-categories-in-article-tags', + 'gen_post_tags' => '#use-post-tags-in-article-tags', + 'facebook_publisher' => '#show-facebook-publisher-on-articles', + 'facebook_author' => '#show-facebook-author-on-articles', + 'types' => '#enable-facebook-meta-for', + 'defcard' => '#default-twitter-card', + 'twitter_site' => '#twitter-site', + 'twitter_creator' => '#show-twitter-author', + 'twitter_domain' => '#twitter-domain', + 'scan_header' => '#scan-social-meta', + 'title' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#title', + 'desc' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#description', + 'image' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#image', + 'customimg' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#custom-image', + 'imagewidth' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#specify-image-width-height', + 'imageheight' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#specify-image-width-height', + 'video' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#custom-video', + 'videowidth' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#specify-video-width-height', + 'videoheight' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#specify-video-width-height', + 'category' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#facebook-object-type', + 'facebook_debug' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#facebook-debug', + 'section' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#article-section', + 'tag' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#article-tags', + 'setcard' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#twitter-card-type', + 'customimg_twitter' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#custom-twitter-image', + ); + + if ( is_admin() ) { + add_action( 'admin_init', array( $this, 'admin_init' ), 5 ); + } else { + add_action( 'wp', array( $this, 'type_setup' ) ); + } + + if ( ! is_admin() || defined( 'DOING_AJAX' ) ) { + $this->do_opengraph(); + } + // Set variables after WordPress load. + add_action( 'init', array( &$this, 'init' ), 999999 ); + add_filter( 'jetpack_enable_open_graph', '__return_false' ); // Avoid having duplicate meta tags + add_filter( $this->prefix . 'meta', array( $this, 'handle_meta_tag' ), 10, 3 ); + // Force refresh of Facebook cache. + add_action( 'post_updated', array( &$this, 'force_fb_refresh_update' ), 10, 3 ); + add_action( 'transition_post_status', array( &$this, 'force_fb_refresh_transition' ), 10, 3 ); + add_action( 'edited_term', array( &$this, 'save_tax_data' ), 10, 3 ); + // Adds special filters + add_filter( 'aioseop_opengraph_placeholder', array( &$this, 'filter_placeholder' ) ); + add_action( 'aiosp_activate_opengraph', array( $this, 'activate_module' ) ); + add_action( 'created_term', array( $this, 'created_term' ), 10, 3 ); + // Call to init to generate menus + $this->init(); + } + + /** + * Handle specific meta tags. + * + * @since 3.0 + * + * @param string $value The value of the meta tag. + * @param string $t The type of network. + * @param string $k The name of the meta tag. + * @return string + */ + function handle_meta_tag( $value, $t, $k ) { + switch ( $k ) { + case 'type': + // https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/1013 + if ( 'blog' === $value ) { + $value = 'website'; + } + break; + } + return $value; + } + + /** + * Sets the terms defaults after a new term is created. + * + * @param int $term_id Term ID. + * @param int $tt_id Term taxonomy ID. + * @param string $taxonomy Taxonomy slug. + */ + function created_term( $term_id, $tt_id, $taxonomy_name ) { + $k = 'settings'; + $prefix = $this->get_prefix( $k ); + $tax = get_taxonomy( $taxonomy_name ); + $this->set_object_type_for_taxonomy( $prefix, $k, $taxonomy_name, $tax, false, array( $term_id ) ); + } + + /** + * Sets the defaults for a taxonomy. + * + * @param string $prefix The prefix of this module. + * @param string $k The key against which the options will be determined/set. + * @param string $taxonomy_name The name of the taxonomy. + * @param Object $tax The taxonomy object. + * @param bool $bail_if_no_terms Bail if the taxonomy has no terms. + * @param array $terms The terms in the taxonomy. + */ + private function set_object_type_for_taxonomy( $prefix, $k, $taxonomy_name, $tax, $bail_if_no_terms = false, $terms = null ) { + $object_type = null; + if ( ! $terms ) { + $terms = get_terms( + $taxonomy_name, array( + 'meta_query' => array( + array( + 'key' => '_' . $prefix . $k, + 'compare' => 'NOT EXISTS', + ), + ), + 'number' => PHP_INT_MAX, + 'fields' => 'ids', + 'hide_empty' => false, + ) + ); + } + + if ( empty( $terms ) && $bail_if_no_terms ) { + return false; + } + + if ( true === $tax->_builtin ) { + $object_type = 'article'; + } else { + // custom taxonomy. Let's get a post against this to determine its post type. + $posts = get_posts( + array( + 'numberposts' => 1, + 'post_type' => 'any', + 'tax_query' => array( + array( + 'taxonomy' => $taxonomy_name, + 'field' => 'term_id', + 'terms' => $terms, + ), + ), + ) + ); + if ( $posts ) { + global $aioseop_options; + $post_type = $posts[0]->post_type; + if ( isset( $aioseop_options['modules'] ) && isset( $aioseop_options['modules'][ $this->prefix . 'options' ] ) ) { + $og_options = $aioseop_options['modules'][ $this->prefix . 'options' ]; + + // now let's see what default object type is set for this post type. + $object_type_set = $og_options[ $this->prefix . $post_type . '_fb_object_type' ]; + if ( ! empty( $object_type_set ) ) { + $object_type = $object_type_set; + } + } + } + } + + if ( $object_type ) { + $opts[ $prefix . $k . '_category' ] = $object_type; + foreach ( $terms as $term_id ) { + update_term_meta( $term_id, '_' . $prefix . $k, $opts ); + } + } + + return true; + } + + /** + * Called when this module is activated. + */ + public function activate_module() { + if ( $this->locations !== null ) { + foreach ( $this->locations as $k => $v ) { + if ( ! isset( $v['type'] ) || 'metabox' !== $v['type'] ) { + continue; + } + $this->set_virgin_tax_terms( $k ); + } + } + } + /** + * This iterates over all taxonomies that do not have a opengraph setting defined and sets the defaults. + * + * @param string $k The key against which the options will be determined/set. + */ + private function set_virgin_tax_terms( $k ) { + $prefix = $this->get_prefix( $k ); + $opts = $this->default_options( $k ); + $taxonomies = get_taxonomies( array( 'public' => true ), 'object' ); + if ( ! $taxonomies ) { + return; + } + foreach ( $taxonomies as $name => $tax ) { + $this->set_object_type_for_taxonomy( $prefix, $k, $name, $tax, true, null ); + + } + } + + /** + * Hook called after WordPress has been loaded. + * + * @since 2.4.14 + */ + public function init() { + $count_desc = __( ' characters. Open Graph allows up to a maximum of %1$s chars for the %2$s.', 'all-in-one-seo-pack' ); + // Create default options + $this->default_options = array( + 'scan_header' => array( + 'name' => __( 'Scan Header', 'all-in-one-seo-pack' ), + 'type' => 'custom', + 'save' => true, + ), + 'setmeta' => array( + 'name' => __( 'Use AIOSEO Title and Description', 'all-in-one-seo-pack' ), + 'type' => 'checkbox', + ), + 'key' => array( + 'name' => __( 'Facebook Admin ID', 'all-in-one-seo-pack' ), + 'default' => '', + 'type' => 'text', + ), + 'appid' => array( + 'name' => __( 'Facebook App ID', 'all-in-one-seo-pack' ), + 'default' => '', + 'type' => 'text', + ), + 'title_shortcodes' => array( + 'name' => __( 'Run Shortcodes In Title', 'all-in-one-seo-pack' ), + ), + 'description_shortcodes' => array( + 'name' => __( 'Run Shortcodes In Description', 'all-in-one-seo-pack' ), + ), + 'sitename' => array( + 'name' => __( 'Site Name', 'all-in-one-seo-pack' ), + 'default' => get_bloginfo( 'name' ), + 'type' => 'text', + ), + 'hometitle' => array( + 'name' => __( 'Home Title', 'all-in-one-seo-pack' ), + 'default' => '', + 'type' => 'textarea', + 'condshow' => array( + 'aiosp_opengraph_setmeta' => array( + 'lhs' => 'aiosp_opengraph_setmeta', + 'op' => '!=', + 'rhs' => 'on', + ), + ), + ), + 'description' => array( + 'name' => __( 'Home Description', 'all-in-one-seo-pack' ), + 'default' => '', + 'type' => 'textarea', + 'condshow' => array( + 'aiosp_opengraph_setmeta' => array( + 'lhs' => 'aiosp_opengraph_setmeta', + 'op' => '!=', + 'rhs' => 'on', + ), + ), + ), + 'homeimage' => array( + 'name' => __( 'Home Image', 'all-in-one-seo-pack' ), + 'type' => 'image', + ), + 'generate_descriptions' => array( + 'name' => __( 'Use Content For Autogenerated OG Descriptions', 'all-in-one-seo-pack' ), + 'default' => 0, + ), + 'defimg' => array( + 'name' => __( 'Select OG:Image Source', 'all-in-one-seo-pack' ), + 'type' => 'select', + 'initial_options' => array( + '' => __( 'Default Image' ), + 'featured' => __( 'Featured Image' ), + 'attach' => __( 'First Attached Image' ), + 'content' => __( 'First Image In Content' ), + 'custom' => __( 'Image From Custom Field' ), + 'author' => __( 'Post Author Image' ), + 'auto' => __( 'First Available Image' ), + ), + ), + 'fallback' => array( + 'name' => __( 'Use Default If No Image Found', 'all-in-one-seo-pack' ), + 'type' => 'checkbox', + ), + 'dimg' => array( + 'name' => __( 'Default OG:Image', 'all-in-one-seo-pack' ), + 'default' => AIOSEOP_PLUGIN_IMAGES_URL . 'default-user-image.png', + 'type' => 'image', + ), + 'dimgwidth' => array( + 'name' => __( 'Default Image Width', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + ), + 'dimgheight' => array( + 'name' => __( 'Default Image Height', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + ), + 'meta_key' => array( + 'name' => __( 'Use Custom Field For Image', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + ), + 'image' => array( + 'name' => __( 'Image', 'all-in-one-seo-pack' ), + 'type' => 'radio', + 'initial_options' => array( + 0 => '', + ), + ), + 'customimg' => array( + 'name' => __( 'Custom Image', 'all-in-one-seo-pack' ), + 'type' => 'image', + ), + 'imagewidth' => array( + 'name' => __( 'Specify Image Width', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + ), + 'imageheight' => array( + 'name' => __( 'Specify Image Height', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + ), + 'video' => array( + 'name' => __( 'Custom Video', 'all-in-one-seo-pack' ), + 'type' => 'text', + ), + 'videowidth' => array( + 'name' => __( 'Specify Video Width', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + 'condshow' => array( + 'aioseop_opengraph_settings_video' => array( + 'lhs' => 'aioseop_opengraph_settings_video', + 'op' => '!=', + 'rhs' => '', + ), + ), + ), + 'videoheight' => array( + 'name' => __( 'Specify Video Height', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + 'condshow' => array( + 'aioseop_opengraph_settings_video' => array( + 'lhs' => 'aioseop_opengraph_settings_video', + 'op' => '!=', + 'rhs' => '', + ), + ), + ), + 'defcard' => array( + 'name' => __( 'Default Twitter Card', 'all-in-one-seo-pack' ), + 'type' => 'select', + 'default' => 'summary', + 'initial_options' => array( + 'summary' => __( 'Summary', 'all-in-one-seo-pack' ), + 'summary_large_image' => __( 'Summary Large Image', 'all-in-one-seo-pack' ), + + /* + REMOVING THIS TWITTER CARD TYPE FROM SOCIAL META MODULE + 'photo' => __( 'Photo', 'all-in-one-seo-pack' ) + */ + ), + ), + 'setcard' => array( + 'name' => __( 'Twitter Card Type', 'all-in-one-seo-pack' ), + 'type' => 'select', + 'initial_options' => array( + 'summary_large_image' => __( 'Summary Large Image', 'all-in-one-seo-pack' ), + 'summary' => __( 'Summary', 'all-in-one-seo-pack' ), + + /* + REMOVING THIS TWITTER CARD TYPE FROM SOCIAL META MODULE + 'photo' => __( 'Photo', 'all-in-one-seo-pack' ) + */ + ), + ), + 'twitter_site' => array( + 'name' => __( 'Twitter Site', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + ), + 'twitter_creator' => array( + 'name' => __( 'Show Twitter Author', 'all-in-one-seo-pack' ), + ), + 'twitter_domain' => array( + 'name' => __( 'Twitter Domain', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + ), + 'customimg_twitter' => array( + 'name' => __( 'Custom Twitter Image', 'all-in-one-seo-pack' ), + 'type' => 'image', + ), + 'gen_tags' => array( + 'name' => __( 'Automatically Generate Article Tags', 'all-in-one-seo-pack' ), + ), + 'gen_keywords' => array( + 'name' => __( 'Use Keywords In Article Tags', 'all-in-one-seo-pack' ), + 'default' => 'on', + 'condshow' => array( 'aiosp_opengraph_gen_tags' => 'on' ), + ), + 'gen_categories' => array( + 'name' => __( 'Use Categories In Article Tags', 'all-in-one-seo-pack' ), + 'default' => 'on', + 'condshow' => array( 'aiosp_opengraph_gen_tags' => 'on' ), + ), + 'gen_post_tags' => array( + 'name' => __( 'Use Post Tags In Article Tags', 'all-in-one-seo-pack' ), + 'default' => 'on', + 'condshow' => array( 'aiosp_opengraph_gen_tags' => 'on' ), + ), + 'types' => array( + 'name' => __( 'Enable Facebook Meta for Post Types', 'all-in-one-seo-pack' ), + 'type' => 'multicheckbox', + 'default' => array( 'post' => 'post', 'page' => 'page' ), + 'initial_options' => $this->get_post_type_titles( array( '_builtin' => false ) ), + ), + 'title' => array( + 'name' => __( 'Title', 'all-in-one-seo-pack' ), + 'default' => '', + 'type' => 'text', + 'size' => 95, + 'count' => 1, + 'count_desc' => $count_desc, + ), + 'desc' => array( + 'name' => __( 'Description', 'all-in-one-seo-pack' ), + 'default' => '', + 'type' => 'textarea', + 'cols' => 250, + 'rows' => 4, + 'count' => 1, + 'count_desc' => $count_desc, + ), + 'category' => array( + 'name' => __( 'Facebook Object Type', 'all-in-one-seo-pack' ), + 'type' => 'select', + 'style' => '', + 'default' => '', + 'initial_options' => $this->fb_object_types, + ), + 'facebook_debug' => array( + 'name' => __( 'Facebook Debug', 'all-in-one-seo-pack' ), + 'type' => 'html', + 'save' => false, + 'default' => '' . __( 'Debug This Post', 'all-in-one-seo-pack' ) . '', + ), + 'section' => array( + 'name' => __( 'Article Section', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + 'condshow' => array( 'aioseop_opengraph_settings_category' => 'article' ), + ), + 'tag' => array( + 'name' => __( 'Article Tags', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + 'condshow' => array( 'aioseop_opengraph_settings_category' => 'article' ), + ), + 'facebook_publisher' => array( + 'name' => __( 'Show Facebook Publisher on Articles', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + ), + 'facebook_author' => array( + 'name' => __( 'Show Facebook Author on Articles', 'all-in-one-seo-pack' ), + ), + 'profile_links' => array( + 'name' => __( 'Social Profile Links', 'all-in-one-seo-pack' ), + 'type' => 'textarea', + 'cols' => 60, + 'rows' => 5, + ), + 'person_or_org' => array( + 'name' => __( 'Person or Organization?', 'all-in-one-seo-pack' ), + 'type' => 'radio', + 'initial_options' => array( + 'person' => __( 'Person', 'all-in-one-seo-pack' ), + 'org' => __( 'Organization', 'all-in-one-seo-pack' ), + ), + ), + 'social_name' => array( + 'name' => __( 'Associated Name', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + ), + ); + // load initial options / set defaults + $this->update_options(); + $display = array(); + if ( isset( $this->options['aiosp_opengraph_types'] ) && ! empty( $this->options['aiosp_opengraph_types'] ) ) { + $display = $this->options['aiosp_opengraph_types']; + } + $this->locations = array( + 'opengraph' => array( + 'name' => $this->name, + 'prefix' => 'aiosp_', + 'type' => 'settings', + 'options' => array( + 'scan_header', + 'setmeta', + 'key', + 'appid', + 'sitename', + 'title_shortcodes', + 'description_shortcodes', + 'hometitle', + 'description', + 'homeimage', + 'generate_descriptions', + 'defimg', + 'fallback', + 'dimg', + 'dimgwidth', + 'dimgheight', + 'meta_key', + 'defcard', + 'profile_links', + 'person_or_org', + 'social_name', + 'twitter_site', + 'twitter_creator', + 'twitter_domain', + 'gen_tags', + 'gen_keywords', + 'gen_categories', + 'gen_post_tags', + 'types', + 'facebook_publisher', + 'facebook_author', + ), + ), + 'settings' => array( + 'name' => __( 'Social Settings', 'all-in-one-seo-pack' ), + 'type' => 'metabox', + 'help_link' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/', + 'options' => array( + 'title', + 'desc', + 'image', + 'customimg', + 'imagewidth', + 'imageheight', + 'video', + 'videowidth', + 'videoheight', + 'category', + 'facebook_debug', + 'section', + 'tag', + 'setcard', + 'customimg_twitter', + ), + 'display' => apply_filters( 'aioseop_opengraph_display', $display ), + 'prefix' => 'aioseop_opengraph_', + ), + ); + $this->layout = array( + 'home' => array( + 'name' => __( 'Home Page Settings', 'all-in-one-seo-pack' ), + 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#use-aioseo-title-and-description', + 'options' => array( 'setmeta', 'sitename', 'hometitle', 'description', 'homeimage' ), + ), + 'image' => array( + 'name' => __( 'Image Settings', 'all-in-one-seo-pack' ), + 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#select-og-image-source', + 'options' => array( 'defimg', 'fallback', 'dimg', 'dimgwidth', 'dimgheight', 'meta_key' ), + ), + 'links' => array( + 'name' => __( 'Social Profile Links', 'all-in-one-seo-pack' ), + 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#social-profile-links', + 'options' => array( 'profile_links', 'person_or_org', 'social_name' ), + ), + 'facebook' => array( + 'name' => __( 'Facebook Settings', 'all-in-one-seo-pack' ), + 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#facebook-settings', + 'options' => array( + 'key', + 'appid', + 'types', + 'gen_tags', + 'gen_keywords', + 'gen_categories', + 'gen_post_tags', + 'facebook_publisher', + 'facebook_author', + ), + ), + 'twitter' => array( + 'name' => __( 'Twitter Settings', 'all-in-one-seo-pack' ), + 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#default-twitter-card', + 'options' => array( 'defcard', 'setcard', 'twitter_site', 'twitter_creator', 'twitter_domain' ), + ), + 'default' => array( + 'name' => __( 'Advanced Settings', 'all-in-one-seo-pack' ), + 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/', + 'options' => array(), // this is set below, to the remaining options -- pdb + ), + 'scan_meta' => array( + 'name' => __( 'Scan Social Meta', 'all-in-one-seo-pack' ), + 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#scan_meta', + 'options' => array( 'scan_header' ), + ), + ); + $other_options = array(); + foreach ( $this->layout as $k => $v ) { + $other_options = array_merge( $other_options, $v['options'] ); + } + + $this->layout['default']['options'] = array_diff( array_keys( $this->default_options ), $other_options ); + } + + /** + * Forces FaceBook OpenGraph to refresh its cache when a post is changed to + * + * @param $new_status + * @param $old_status + * @param $post + * + * @todo this and force_fb_refresh_update can probably have the remote POST extracted out. + * + * @see https://developers.facebook.com/docs/sharing/opengraph/using-objects#update + * @since 2.3.11 + */ + function force_fb_refresh_transition( $new_status, $old_status, $post ) { + if ( 'publish' !== $new_status ) { + return; + } + if ( 'future' !== $old_status ) { + return; + } + + $current_post_type = get_post_type(); + + // Only ping Facebook if Social SEO is enabled on this post type. + if ( $this->option_isset( 'types' ) && is_array( $this->options['aiosp_opengraph_types'] ) && in_array( $current_post_type, $this->options['aiosp_opengraph_types'] ) ) { + $post_url = aioseop_get_permalink( $post->ID ); + $endpoint = sprintf( + 'https://graph.facebook.com/?%s', http_build_query( + array( + 'id' => $post_url, + 'scrape' => true, + ) + ) + ); + wp_remote_post( $endpoint, array( 'blocking' => false ) ); + } + } + + /** + * Forces FaceBook OpenGraph refresh on update. + * + * @param $post_id + * @param $post_after + * + * @see https://developers.facebook.com/docs/sharing/opengraph/using-objects#update + * @since 2.3.11 + */ + function force_fb_refresh_update( $post_id, $post_after ) { + + $current_post_type = get_post_type(); + + // Only ping Facebook if Social SEO is enabled on this post type. + if ( 'publish' === $post_after->post_status && $this->option_isset( 'types' ) && is_array( $this->options['aiosp_opengraph_types'] ) && in_array( $current_post_type, $this->options['aiosp_opengraph_types'] ) ) { + $post_url = aioseop_get_permalink( $post_id ); + $endpoint = sprintf( + 'https://graph.facebook.com/?%s', http_build_query( + array( + 'id' => $post_url, + 'scrape' => true, + ) + ) + ); + wp_remote_post( $endpoint, array( 'blocking' => false ) ); + } + } + + function settings_page_init() { + add_filter( 'aiosp_output_option', array( $this, 'display_custom_options' ), 10, 2 ); + } + + function filter_options( $options, $location ) { + if ( $location == 'settings' ) { + $prefix = $this->get_prefix( $location ) . $location . '_'; + list( $legacy, $images ) = $this->get_all_images( $options ); + if ( isset( $options ) && isset( $options[ "{$prefix}image" ] ) ) { + $thumbnail = $options[ "{$prefix}image" ]; + if ( ctype_digit( (string) $thumbnail ) || ( $thumbnail == 'post' ) ) { + if ( $thumbnail == 'post' ) { + $thumbnail = $images['post1']; + } elseif ( ! empty( $legacy[ $thumbnail ] ) ) { + $thumbnail = $legacy[ $thumbnail ]; + } + } + $options[ "{$prefix}image" ] = $thumbnail; + } + if ( empty( $options[ $prefix . 'image' ] ) ) { + $img = array_keys( $images ); + if ( ! empty( $img ) && ! empty( $img[1] ) ) { + $options[ $prefix . 'image' ] = $img[1]; + } + } + } + + return $options; + } + + /** + * Applies filter to module settings. + * + * @since 2.3.11 + * @since 2.4.14 Added filter for description and title placeholders. + * @since 2.3.15 do_shortcode on description. + * + * @see [plugin]\admin\aioseop_module_class.php > display_options() + */ + function filter_settings( $settings, $location, $current ) { + global $aiosp, $post; + if ( $location == 'opengraph' || $location == 'settings' ) { + $prefix = $this->get_prefix( $location ) . $location . '_'; + if ( $location == 'opengraph' ) { + return $settings; + } + if ( $location == 'settings' ) { + list( $legacy, $settings[ $prefix . 'image' ]['initial_options'] ) = $this->get_all_images( $current ); + $opts = array( 'title', 'desc' ); + $current_post_type = get_post_type(); + if ( isset( $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ] ) ) { + $flat_type_list = array(); + foreach ( $this->fb_object_types as $k => $v ) { + if ( is_array( $v ) ) { + $flat_type_list = array_merge( $flat_type_list, $v ); + } else { + $flat_type_list[ $k ] = $v; + } + } + $default_fb_type = $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ]; + // https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/1013 + // if 'blog' is the selected type but because it is no longer a schema type, we use 'website' instead. + if ( 'blog' === $default_fb_type ) { + $default_fb_type = 'website'; + } + if ( isset( $flat_type_list[ $default_fb_type ] ) ) { + $default_fb_type = $flat_type_list[ $default_fb_type ]; + } + $settings[ $prefix . 'category' ]['initial_options'] = array_merge( + array( + $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ] => __( 'Default ', 'all-in-one-seo-pack' ) . ' - ' . $default_fb_type, + ), + $settings[ $prefix . 'category' ]['initial_options'] + ); + } + if ( isset( $this->options['aiosp_opengraph_defcard'] ) ) { + $settings[ $prefix . 'setcard' ]['default'] = $this->options['aiosp_opengraph_defcard']; + } + $info = $aiosp->get_page_snippet_info(); + $title = $info['title']; + $description = $info['description']; + + // Description options + if ( is_object( $post ) ) { + // Always show excerpt + $description = empty( $this->options['aiosp_opengraph_generate_descriptions'] ) + ? $aiosp->trim_excerpt_without_filters( + $aiosp->internationalize( preg_replace( '/\s+/', ' ', $post->post_excerpt ) ), + 1000 + ) + : $aiosp->trim_excerpt_without_filters( + $aiosp->internationalize( preg_replace( '/\s+/', ' ', $post->post_content ) ), + 1000 + ); + } + + // #1308 - we want to make sure we are ignoring php version only in the admin area while editing the post, so that it does not impact #932. + $screen = get_current_screen(); + $ignore_php_version = is_admin() && isset( $screen->id ) && 'post' == $screen->id; + + // Add filters + $description = apply_filters( 'aioseop_description', $description, false, $ignore_php_version ); + // Add placholders + $settings[ "{$prefix}title" ]['placeholder'] = apply_filters( 'aioseop_opengraph_placeholder', $title ); + $settings[ "{$prefix}desc" ]['placeholder'] = apply_filters( 'aioseop_opengraph_placeholder', $description ); + } + if ( isset( $current[ $prefix . 'setmeta' ] ) && $current[ $prefix . 'setmeta' ] ) { + foreach ( $opts as $opt ) { + if ( isset( $settings[ $prefix . $opt ] ) ) { + $settings[ $prefix . $opt ]['type'] = 'hidden'; + $settings[ $prefix . $opt ]['label'] = 'none'; + $settings[ $prefix . $opt ]['help_text'] = ''; + unset( $settings[ $prefix . $opt ]['count'] ); + } + } + } + } + + return $settings; + } + + /** + * Applies filter to module options. + * These will display in the "Social Settings" object tab. + * filter:{prefix}override_options + * + * @since 2.3.11 + * @since 2.4.14 Overrides empty og:type values. + * + * @see [plugin]\admin\aioseop_module_class.php > display_options() + * + * @global array $aioseop_options Plugin options. + * + * @param array $options Current options. + * @param string $location Location where filter is called. + * @param array $settings Settings. + * + * @return array + */ + function override_options( $options, $location, $settings ) { + global $aioseop_options; + // Prepare default and prefix + $prefix = $this->get_prefix( $location ) . $location . '_'; + $opts = array(); + + foreach ( $settings as $k => $v ) { + if ( $v['save'] ) { + $opts[ $k ] = $v['default']; + } + } + foreach ( $options as $k => $v ) { + switch ( $k ) { + case $prefix . 'category': + if ( empty( $v ) ) { + // Get post type + $type = isset( get_current_screen()->post_type ) + ? get_current_screen()->post_type + : null; + // Assign default from plugin options + if ( ! empty( $type ) + && isset( $aioseop_options['modules'] ) + && isset( $aioseop_options['modules']['aiosp_opengraph_options'] ) + && isset( $aioseop_options['modules']['aiosp_opengraph_options'][ 'aiosp_opengraph_' . $type . '_fb_object_type' ] ) + ) { + $options[ $prefix . 'category' ] = + $aioseop_options['modules']['aiosp_opengraph_options'][ 'aiosp_opengraph_' . $type . '_fb_object_type' ]; + } + } + break; + } + if ( $v === null ) { + unset( $options[ $k ] ); + } + } + $options = wp_parse_args( $options, $opts ); + + // https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/1013 + $post_types = $this->get_post_type_titles(); + foreach ( $post_types as $slug => $name ) { + $field = 'aiosp_opengraph_' . $slug . '_fb_object_type'; + if ( isset( $options[ $field ] ) && 'blog' === $options[ $field ] ) { + $options[ $field ] = 'website'; + } + } + + return $options; + } + + /** + * Applies filter to metabox settings before they are saved. + * Sets custom as default if a custom image is uploaded. + * filter:{prefix}filter_metabox_options + * filter:{prefix}filter_term_metabox_options + * + * @since 2.3.11 + * @since 2.4.14 Fixes for aioseop-pro #67 and other bugs found. + * + * @see [plugin]\admin\aioseop_module_class.php > save_post_data() + * @see [this file] > save_tax_data() + * + * @param array $options List of current options. + * @param string $location Location where filter is called. + * @param int $id Either post_id or term_id. + * + * @return array + */ + function filter_metabox_options( $options, $location, $post_id ) { + if ( $location == 'settings' ) { + $prefix = $this->get_prefix( $location ) . $location . '_'; + if ( isset( $options[ $prefix . 'customimg_checker' ] ) + && $options[ $prefix . 'customimg_checker' ] + ) { + $options[ $prefix . 'image' ] = $options[ $prefix . 'customimg' ]; + } + } + return $options; + } + + /** Custom settings **/ + function display_custom_options( $buf, $args ) { + if ( $args['name'] == 'aiosp_opengraph_scan_header' ) { + $buf .= '
'; + $args['options']['type'] = 'submit'; + $args['attr'] = " class='button-primary' "; + $args['value'] = $args['options']['default'] = __( 'Scan Now', 'all-in-one-seo-pack' ); + $buf .= __( 'Scan your site for duplicate social meta tags.', 'all-in-one-seo-pack' ); + $buf .= '

' . $this->get_option_html( $args ); + $buf .= '
'; + } + + return $buf; + } + + function add_attributes( $output ) { + // avoid having duplicate meta tags + $type = $this->type; + if ( empty( $type ) ) { + $type = 'website'; + } + $schema_types = array( + 'album' => 'MusicAlbum', + 'article' => 'Article', + 'bar' => 'BarOrPub', + 'blog' => 'Blog', + 'book' => 'Book', + 'cafe' => 'CafeOrCoffeeShop', + 'city' => 'City', + 'country' => 'Country', + 'episode' => 'Episode', + 'food' => 'FoodEvent', + 'game' => 'Game', + 'hotel' => 'Hotel', + 'landmark' => 'LandmarksOrHistoricalBuildings', + 'movie' => 'Movie', + 'product' => 'Product', + 'profile' => 'ProfilePage', + 'restaurant' => 'Restaurant', + 'school' => 'School', + 'sport' => 'SportsEvent', + 'website' => 'WebSite', + ); + + if ( ! empty( $schema_types[ $type ] ) ) { + $type = $schema_types[ $type ]; + } else { + $type = 'WebSite'; + } + + $attributes = apply_filters( + $this->prefix . 'attributes', array( + 'prefix="og: http://ogp.me/ns#"', + ) + ); + + foreach ( $attributes as $attr ) { + if ( strpos( $output, $attr ) === false ) { + $output .= "\n\t$attr "; + } + } + + return $output; + } + + /** + * Add our social meta. + * + * @since 1.0.0 + * @since 2.3.11.5 Support for multiple fb_admins. + * @since 2.3.13 Adds filter:aioseop_description on description. + * @since 2.4.14 Fixes for aioseop-pro #67. + * @since 2.3.15 Always do_shortcode on descriptions, removed for titles. + * + * @global object $post Current WP_Post object. + * @global object $aiosp All in one seo plugin object. + * @global array $aioseop_options All in one seo plugin options. + * @global object $wp_query WP_Query global instance. + */ + function add_meta() { + global $post, $aiosp, $aioseop_options, $wp_query; + $metabox = $this->get_current_options( array(), 'settings' ); + $key = $this->options['aiosp_opengraph_key']; + $key = $this->options['aiosp_opengraph_key']; + $dimg = $this->options['aiosp_opengraph_dimg']; + $current_post_type = get_post_type(); + $title = $description = $image = $video = ''; + $type = $this->type; + $sitename = $this->options['aiosp_opengraph_sitename']; + + $appid = isset( $this->options['aiosp_opengraph_appid'] ) ? $this->options['aiosp_opengraph_appid'] : ''; + + if ( ! empty( $aioseop_options['aiosp_hide_paginated_descriptions'] ) ) { + $first_page = false; + if ( $aiosp->get_page_number() < 2 ) { + $first_page = true; + } + } else { + $first_page = true; + } + $url = $aiosp->aiosp_mrt_get_url( $wp_query ); + $url = apply_filters( 'aioseop_canonical_url', $url ); + + $setmeta = $this->options['aiosp_opengraph_setmeta']; + $social_links = ''; + if ( is_front_page() ) { + $title = $this->options['aiosp_opengraph_hometitle']; + if ( $first_page ) { + $description = $this->options['aiosp_opengraph_description']; + if ( empty( $description ) ) { + $description = get_bloginfo( 'description' ); + } + } + if ( ! empty( $this->options['aiosp_opengraph_homeimage'] ) ) { + $thumbnail = $this->options['aiosp_opengraph_homeimage']; + } else { + $thumbnail = $this->options['aiosp_opengraph_dimg']; + } + + /* If Use AIOSEO Title and Desc Selected */ + if ( $setmeta ) { + $title = $aiosp->wp_title(); + if ( $first_page ) { + $description = $aiosp->get_aioseop_description( $post ); + } + } + + /* Add some defaults */ + if ( empty( $title ) ) { + $title = get_bloginfo( 'name' ); + } + if ( empty( $sitename ) ) { + $sitename = get_bloginfo( 'name' ); + } + + if ( empty( $description ) && $first_page && ! empty( $post ) && ! post_password_required( $post ) ) { + + if ( ! empty( $post->post_content ) || ! empty( $post->post_excerpt ) ) { + $description = $aiosp->trim_excerpt_without_filters( $aiosp->internationalize( preg_replace( '/\s+/', ' ', $post->post_excerpt ) ), 1000 ); + + if ( ! empty( $this->options['aiosp_opengraph_generate_descriptions'] ) ) { + $description = $aiosp->trim_excerpt_without_filters( $aiosp->internationalize( preg_replace( '/\s+/', ' ', $post->post_content ) ), 1000 ); + } + } + } + + if ( empty( $description ) && $first_page ) { + $description = get_bloginfo( 'description' ); + } + if ( ! empty( $this->options['aiosp_opengraph_profile_links'] ) ) { + $social_links = $this->options['aiosp_opengraph_profile_links']; + if ( ! empty( $this->options['aiosp_opengraph_social_name'] ) ) { + $social_name = $this->options['aiosp_opengraph_social_name']; + } else { + $social_name = ''; + } + if ( $this->options['aiosp_opengraph_person_or_org'] == 'person' ) { + $social_type = 'Person'; + } else { + $social_type = 'Organization'; + } + } + } elseif ( is_singular() && $this->option_isset( 'types' ) + && is_array( $this->options['aiosp_opengraph_types'] ) + && in_array( $current_post_type, $this->options['aiosp_opengraph_types'] ) + ) { + + if ( $type == 'article' ) { + if ( ! empty( $metabox['aioseop_opengraph_settings_section'] ) ) { + $section = $metabox['aioseop_opengraph_settings_section']; + } + if ( ! empty( $metabox['aioseop_opengraph_settings_tag'] ) ) { + $tag = $metabox['aioseop_opengraph_settings_tag']; + } + if ( ! empty( $this->options['aiosp_opengraph_facebook_publisher'] ) ) { + $publisher = $this->options['aiosp_opengraph_facebook_publisher']; + } + } + + if ( ! empty( $this->options['aiosp_opengraph_twitter_domain'] ) ) { + $domain = $this->options['aiosp_opengraph_twitter_domain']; + } + + if ( $type == 'article' && ! empty( $post ) ) { + if ( isset( $post->post_author ) && ! empty( $this->options['aiosp_opengraph_facebook_author'] ) ) { + $author = get_the_author_meta( 'facebook', $post->post_author ); + } + + if ( isset( $post->post_date_gmt ) ) { + $published_time = date( 'Y-m-d\TH:i:s\Z', mysql2date( 'U', $post->post_date_gmt ) ); + } + + if ( isset( $post->post_modified_gmt ) ) { + $modified_time = date( 'Y-m-d\TH:i:s\Z', mysql2date( 'U', $post->post_modified_gmt ) ); + } + } + + $image = $metabox['aioseop_opengraph_settings_image']; + $video = $metabox['aioseop_opengraph_settings_video']; + $title = $metabox['aioseop_opengraph_settings_title']; + $description = $metabox['aioseop_opengraph_settings_desc']; + + /* Add AIOSEO variables if Site Title and Desc from AIOSEOP not selected */ + global $aiosp; + if ( empty( $title ) ) { + $title = $aiosp->wp_title(); + } + if ( empty( $description ) ) { + $description = trim( strip_tags( get_post_meta( $post->ID, '_aioseop_description', true ) ) ); + } + + /* Add default title */ + if ( empty( $title ) ) { + $title = get_the_title(); + } + + // Add default description. + if ( empty( $description ) && ! post_password_required( $post ) ) { + + $description = $post->post_excerpt; + + if ( $this->options['aiosp_opengraph_generate_descriptions'] || empty( $description ) ) { + if ( ! AIOSEOPPRO || ( AIOSEOPPRO && apply_filters( $this->prefix . 'generate_descriptions_from_content', true, $post ) ) ) { + $description = $post->post_content; + } else { + $description = $post->post_excerpt; + } + } + } + if ( empty( $type ) ) { + $type = 'article'; + } + } elseif ( AIOSEOPPRO && ( is_category() || is_tag() || is_tax() ) ) { + if ( isset( $this->options['aioseop_opengraph_settings_category'] ) ) { + $type = $this->options['aioseop_opengraph_settings_category']; + } + if ( isset( $metabox['aioseop_opengraph_settings_category'] ) ) { + $type = $metabox['aioseop_opengraph_settings_category']; + } + if ( $type == 'article' ) { + if ( ! empty( $metabox['aioseop_opengraph_settings_section'] ) ) { + $section = $metabox['aioseop_opengraph_settings_section']; + } + if ( ! empty( $metabox['aioseop_opengraph_settings_tag'] ) ) { + $tag = $metabox['aioseop_opengraph_settings_tag']; + } + if ( ! empty( $this->options['aiosp_opengraph_facebook_publisher'] ) ) { + $publisher = $this->options['aiosp_opengraph_facebook_publisher']; + } + } + if ( ! empty( $this->options['aiosp_opengraph_twitter_domain'] ) ) { + $domain = $this->options['aiosp_opengraph_twitter_domain']; + } + if ( $type == 'article' && ! empty( $post ) ) { + if ( isset( $post->post_author ) && ! empty( $this->options['aiosp_opengraph_facebook_author'] ) ) { + $author = get_the_author_meta( 'facebook', $post->post_author ); + } + + if ( isset( $post->post_date_gmt ) ) { + $published_time = date( 'Y-m-d\TH:i:s\Z', mysql2date( 'U', $post->post_date_gmt ) ); + } + if ( isset( $post->post_modified_gmt ) ) { + $modified_time = date( 'Y-m-d\TH:i:s\Z', mysql2date( 'U', $post->post_modified_gmt ) ); + } + } + $image = $metabox['aioseop_opengraph_settings_image']; + $video = $metabox['aioseop_opengraph_settings_video']; + $title = $metabox['aioseop_opengraph_settings_title']; + $description = $metabox['aioseop_opengraph_settings_desc']; + /* Add AIOSEO variables if Site Title and Desc from AIOSEOP not selected */ + global $aiosp; + if ( empty( $title ) ) { + $title = $aiosp->wp_title(); + } + if ( empty( $description ) ) { + $term_id = isset( $_GET['tag_ID'] ) ? (int) $_GET['tag_ID'] : 0; + $term_id = $term_id ? $term_id : get_queried_object()->term_id; + $description = trim( strip_tags( get_term_meta( $term_id, '_aioseop_description', true ) ) ); + } + // Add default title + if ( empty( $title ) ) { + $title = get_the_title(); + } + // Add default description. + if ( empty( $description ) && ! post_password_required( $post ) ) { + $description = get_queried_object()->description; + } + if ( empty( $type ) ) { + // https://github.com/semperfiwebdesign/aioseop-pro/issues/321 + if ( AIOSEOPPRO && ( is_category() || is_tag() || is_tax() ) ) { + $og_options = $aioseop_options['modules'][ $this->prefix . 'options' ]; + $current_post_type = get_post_type(); + // check if the post type's object type is set. + if ( isset( $og_options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ] ) ) { + $type = $og_options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ]; + } elseif ( in_array( $current_post_type, array( 'post', 'page' ) ) ) { + $type = 'article'; + } + } else { + $type = 'website'; + } + } + } elseif ( is_home() && ! is_front_page() ) { + // This is the blog page but not the homepage. + global $aiosp; + $image = $metabox['aioseop_opengraph_settings_image']; + $video = $metabox['aioseop_opengraph_settings_video']; + $title = $metabox['aioseop_opengraph_settings_title']; + $description = $metabox['aioseop_opengraph_settings_desc']; + + if ( empty( $description ) ) { + // If there's not social description, fall back to the SEO description. + $description = trim( strip_tags( get_post_meta( get_option( 'page_for_posts' ), '_aioseop_description', true ) ) ); + } + if ( empty( $title ) ) { + $title = $aiosp->wp_title(); + } + } else { + return; + } + + if ( $type === 'article' && ! empty( $post ) && is_singular() ) { + if ( ! empty( $this->options['aiosp_opengraph_gen_tags'] ) ) { + if ( ! empty( $this->options['aiosp_opengraph_gen_keywords'] ) ) { + $keywords = $aiosp->get_main_keywords(); + $keywords = $this->apply_cf_fields( $keywords ); + $keywords = apply_filters( 'aioseop_keywords', $keywords ); + if ( ! empty( $keywords ) && ! empty( $tag ) ) { + $tag .= ',' . $keywords; + } elseif ( empty( $tag ) ) { + $tag = $keywords; + } + } + $tag = $aiosp->keyword_string_to_list( $tag ); + if ( ! empty( $this->options['aiosp_opengraph_gen_categories'] ) ) { + $tag = array_merge( $tag, $aiosp->get_all_categories( $post->ID ) ); + } + if ( ! empty( $this->options['aiosp_opengraph_gen_post_tags'] ) ) { + $tag = array_merge( $tag, $aiosp->get_all_tags( $post->ID ) ); + } + } + if ( ! empty( $tag ) ) { + $tag = $aiosp->clean_keyword_list( $tag ); + } + } + + if ( ! empty( $this->options['aiosp_opengraph_title_shortcodes'] ) ) { + $title = do_shortcode( $title ); + } + if ( ! empty( $description ) ) { + $description = $aiosp->internationalize( preg_replace( '/\s+/', ' ', $description ) ); + if ( ! empty( $this->options['aiosp_opengraph_description_shortcodes'] ) ) { + $description = do_shortcode( $description ); + } + $description = $aiosp->trim_excerpt_without_filters( $description, 1000 ); + } + + $title = $this->apply_cf_fields( $title ); + $description = $this->apply_cf_fields( $description ); + + /* Data Validation */ + $title = strip_tags( esc_attr( $title ) ); + $sitename = strip_tags( esc_attr( $sitename ) ); + $description = strip_tags( esc_attr( $description ) ); + + if ( empty( $thumbnail ) && ! empty( $image ) ) { + $thumbnail = $image; + } + + // Add user supplied default image. + if ( empty( $thumbnail ) ) { + if ( empty( $this->options['aiosp_opengraph_defimg'] ) ) { + $thumbnail = $this->options['aiosp_opengraph_dimg']; + } else { + $img_type = $this->options['aiosp_opengraph_defimg']; + if ( ! empty( $post ) ) { + // Customize the type of image per post/post_type. + $img_type = apply_filters( $this->prefix . 'default_image_type', $img_type, $post, $type ); + } + switch ( $img_type ) { + case 'featured': + $thumbnail = $this->get_the_image_by_post_thumbnail(); + break; + case 'attach': + $thumbnail = $this->get_the_image_by_attachment(); + break; + case 'content': + $thumbnail = $this->get_the_image_by_scan(); + break; + case 'custom': + $meta_key = $this->options['aiosp_opengraph_meta_key']; + if ( ! empty( $meta_key ) && ! empty( $post ) ) { + $meta_key = explode( ',', $meta_key ); + $thumbnail = $this->get_the_image_by_meta_key( + array( + 'post_id' => $post->ID, + 'meta_key' => $meta_key, + ) + ); + } + break; + case 'auto': + $thumbnail = $this->get_the_image(); + break; + case 'author': + $thumbnail = $this->get_the_image_by_author(); + break; + default: + $thumbnail = $this->options['aiosp_opengraph_dimg']; + } + } + } + + if ( empty( $thumbnail ) && ! empty( $this->options['aiosp_opengraph_fallback'] ) ) { + $thumbnail = $this->options['aiosp_opengraph_dimg']; + if ( ! empty( $post ) ) { + // Customize the default image per post/post_type. + $thumbnail = apply_filters( $this->prefix . 'default_image', $thumbnail, $post, $type ); + } + } + + if ( ! empty( $thumbnail ) ) { + $thumbnail = esc_url( $thumbnail ); + $thumbnail = set_url_scheme( $thumbnail ); + } + + $width = $height = ''; + if ( ! empty( $thumbnail ) ) { + if ( ! empty( $metabox['aioseop_opengraph_settings_imagewidth'] ) ) { + $width = $metabox['aioseop_opengraph_settings_imagewidth']; + } + if ( ! empty( $metabox['aioseop_opengraph_settings_imageheight'] ) ) { + $height = $metabox['aioseop_opengraph_settings_imageheight']; + } + if ( empty( $width ) && ! empty( $this->options['aiosp_opengraph_dimgwidth'] ) ) { + $width = $this->options['aiosp_opengraph_dimgwidth']; + } + if ( empty( $height ) && ! empty( $this->options['aiosp_opengraph_dimgheight'] ) ) { + $height = $this->options['aiosp_opengraph_dimgheight']; + } + } + + if ( ! empty( $video ) ) { + if ( ! empty( $metabox['aioseop_opengraph_settings_videowidth'] ) ) { + $videowidth = $metabox['aioseop_opengraph_settings_videowidth']; + } + if ( ! empty( $metabox['aioseop_opengraph_settings_videoheight'] ) ) { + $videoheight = $metabox['aioseop_opengraph_settings_videoheight']; + } + } + + $card = 'summary'; + if ( ! empty( $this->options['aiosp_opengraph_defcard'] ) ) { + $card = $this->options['aiosp_opengraph_defcard']; + } + + if ( ! empty( $metabox['aioseop_opengraph_settings_setcard'] ) ) { + $card = $metabox['aioseop_opengraph_settings_setcard']; + } + + // support for changing legacy twitter cardtype-photo to summary large image + if ( $card == 'photo' ) { + $card = 'summary_large_image'; + } + + $site = $domain = $creator = ''; + + if ( ! empty( $this->options['aiosp_opengraph_twitter_site'] ) ) { + $site = $this->options['aiosp_opengraph_twitter_site']; + $site = AIOSEOP_Opengraph_Public::prepare_twitter_username( $site ); + } + + if ( ! empty( $this->options['aiosp_opengraph_twitter_domain'] ) ) { + $domain = $this->options['aiosp_opengraph_twitter_domain']; + } + + if ( ! empty( $post ) && isset( $post->post_author ) && ! empty( $this->options['aiosp_opengraph_twitter_creator'] ) ) { + $creator = get_the_author_meta( 'twitter', $post->post_author ); + $creator = AIOSEOP_Opengraph_Public::prepare_twitter_username( $creator ); + } + + if ( ! empty( $thumbnail ) ) { + $twitter_thumbnail = $thumbnail; // Default Twitter image if custom isn't set. + } + + if ( isset( $metabox['aioseop_opengraph_settings_customimg_twitter'] ) && ! empty( $metabox['aioseop_opengraph_settings_customimg_twitter'] ) ) { + // Set Twitter image from custom. + $twitter_thumbnail = set_url_scheme( $metabox['aioseop_opengraph_settings_customimg_twitter'] ); + } + + // Apply last filters. + $description = apply_filters( 'aioseop_description', $description ); + + $meta = array( + 'facebook' => array( + 'title' => 'og:title', + 'type' => 'og:type', + 'url' => 'og:url', + 'thumbnail' => 'og:image', + 'width' => 'og:image:width', + 'height' => 'og:image:height', + 'video' => 'og:video', + 'videowidth' => 'og:video:width', + 'videoheight' => 'og:video:height', + 'sitename' => 'og:site_name', + 'key' => 'fb:admins', + 'appid' => 'fb:app_id', + 'description' => 'og:description', + 'section' => 'article:section', + 'tag' => 'article:tag', + 'publisher' => 'article:publisher', + 'author' => 'article:author', + 'published_time' => 'article:published_time', + 'modified_time' => 'article:modified_time', + ), + 'twitter' => array( + 'card' => 'twitter:card', + 'site' => 'twitter:site', + 'creator' => 'twitter:creator', + 'domain' => 'twitter:domain', + 'title' => 'twitter:title', + 'description' => 'twitter:description', + 'twitter_thumbnail' => 'twitter:image', + ), + ); + + // Only show if "use schema.org markup is checked". + if ( ! empty( $aioseop_options['aiosp_schema_markup'] ) ) { + $meta['google+'] = array( 'thumbnail' => 'image' ); + } + + $tags = array( + 'facebook' => array( 'name' => 'property', 'value' => 'content' ), + 'twitter' => array( 'name' => 'name', 'value' => 'content' ), + 'google+' => array( 'name' => 'itemprop', 'value' => 'content' ), + ); + + foreach ( $meta as $t => $data ) { + foreach ( $data as $k => $v ) { + if ( empty( $$k ) ) { + $$k = ''; + } + $filtered_value = $$k; + $filtered_value = apply_filters( $this->prefix . 'meta', $filtered_value, $t, $k ); + if ( ! empty( $filtered_value ) ) { + if ( ! is_array( $filtered_value ) ) { + $filtered_value = array( $filtered_value ); + } + + /** + * This is to accomodate multiple fb:admins on separate lines. + * @TODO Eventually we'll want to put this in its own function so things like images work too. + */ + if ( 'key' === $k ) { + $fbadmins = explode( ',', str_replace( ' ', '', $filtered_value[0] ) ); // Trim spaces then turn comma-separated values into an array. + foreach ( $fbadmins as $fbadmin ) { + echo '' . "\n"; + } + } else { + // For everything else. + foreach ( $filtered_value as $f ) { + // #1363: use esc_attr( $f ) instead of htmlspecialchars_decode( $f, ENT_QUOTES ) + echo '' . "\n"; + } + } + } + } + } + $social_link_schema = ''; + if ( ! empty( $social_links ) ) { + $home_url = esc_url( get_home_url() ); + $social_links = explode( "\n", $social_links ); + foreach ( $social_links as $k => $v ) { + $v = trim( $v ); + if ( empty( $v ) ) { + unset( $social_links[ $k ] ); + } else { + $v = esc_url( $v ); + $social_links[ $k ] = $v; + } + } + $social_links = join( '","', $social_links ); + $social_link_schema = << +{ "@context" : "http://schema.org", + "@type" : "{$social_type}", + "name" : "{$social_name}", + "url" : "{$home_url}", + "sameAs" : ["{$social_links}"] +} + + +END; + } + + // Only show if "use schema.org markup is checked". + if ( ! empty( $aioseop_options['aiosp_schema_markup'] ) ) { + echo apply_filters( 'aiosp_opengraph_social_link_schema', $social_link_schema ); + } + } + + /** + * Do / adds opengraph properties to meta. + * @since 2.3.11 + * + * @global array $aioseop_options AIOSEOP plugin options. + */ + public function do_opengraph() { + global $aioseop_options; + if ( ! empty( $aioseop_options ) + && ! empty( $aioseop_options['aiosp_schema_markup'] ) + ) { + add_filter( 'language_attributes', array( &$this, 'add_attributes' ) ); + } + if ( ! defined( 'DOING_AJAX' ) ) { + add_action( 'aioseop_modules_wp_head', array( &$this, 'add_meta' ), 5 ); + // Add social meta to AMP plugin. + if ( apply_filters( 'aioseop_enable_amp_social_meta', true ) === true ) { + add_action( 'amp_post_template_head', array( &$this, 'add_meta' ), 12 ); + } + } + } + + /** + * Set up types. + * + * @since ? + * @since 2.3.15 Change to website for homepage and blog post index page, default to object. + */ + function type_setup() { + $this->type = 'object'; // Default to type object if we don't have some other rule. + + if ( is_home() || is_front_page() ) { + $this->type = 'website'; // Home page and blog page should be website. + } elseif ( is_singular() && $this->option_isset( 'types' ) ) { + $metabox = $this->get_current_options( array(), 'settings' ); + $current_post_type = get_post_type(); + if ( ! empty( $metabox['aioseop_opengraph_settings_category'] ) ) { + $this->type = $metabox['aioseop_opengraph_settings_category']; + } elseif ( isset( $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ] ) ) { + $this->type = $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ]; + } + } + } + + /** + * Inits hooks and others for admin init. + * action:admin_init. + * + * @since 2.3.11 + * @since 2.4.14 Refactored function name, and new filter added for defaults and missing term metabox. + */ + function admin_init() { + add_filter( $this->prefix . 'display_settings', array( &$this, 'filter_settings' ), 10, 3 ); + add_filter( $this->prefix . 'override_options', array( &$this, 'override_options' ), 10, 3 ); + add_filter( + $this->get_prefix( 'settings' ) . 'default_options', array( + &$this, + 'filter_default_options', + ), 10, 2 + ); + add_filter( + $this->get_prefix( 'settings' ) . 'filter_metabox_options', array( + &$this, + 'filter_metabox_options', + ), 10, 3 + ); + add_filter( + $this->get_prefix( 'settings' ) . 'filter_term_metabox_options', array( + &$this, + 'filter_metabox_options', + ), 10, 3 + ); + $post_types = $this->get_post_type_titles(); + $rempost = array( + 'revision' => 1, + 'nav_menu_item' => 1, + 'custom_css' => 1, + 'customize_changeset' => 1, + ); + $post_types = array_diff_key( $post_types, $rempost ); + $this->default_options['types']['initial_options'] = $post_types; + foreach ( $post_types as $slug => $name ) { + $field = $slug . '_fb_object_type'; + $this->default_options[ $field ] = array( + 'name' => "$name " . __( 'Object Type', 'all-in-one-seo-pack' ) . "
($slug)", + 'type' => 'select', + 'style' => '', + 'initial_options' => $this->fb_object_types, + 'default' => 'article', + 'condshow' => array( 'aiosp_opengraph_types\[\]' => $slug ), + ); + $this->help_text[ $field ] = __( 'Choose a default value that best describes the content of your post type.', 'all-in-one-seo-pack' ); + $this->help_anchors[ $field ] = '#content-object-types'; + $this->locations['opengraph']['options'][] = $field; + $this->layout['facebook']['options'][] = $field; + } + $this->setting_options(); + $this->add_help_text_links(); + + } + + function get_all_images( $options = null, $p = null ) { + static $img = array(); + if ( ! is_array( $options ) ) { + $options = array(); + } + if ( ! empty( $this->options['aiosp_opengraph_meta_key'] ) ) { + $options['meta_key'] = $this->options['aiosp_opengraph_meta_key']; + } + if ( empty( $img ) ) { + $size = apply_filters( 'post_thumbnail_size', 'large' ); + $default = $this->get_the_image_by_default(); + if ( ! empty( $default ) ) { + $default = set_url_scheme( $default ); + $img[ $default ] = 0; + } + $img = array_merge( $img, parent::get_all_images( $options, null ) ); + } + + if ( ! empty( $options ) && ! empty( $options['aioseop_opengraph_settings_customimg'] ) ) { + $img[ $options['aioseop_opengraph_settings_customimg'] ] = 'customimg'; + } + + if ( ! empty( $options ) && ! empty( $options['aioseop_opengraph_settings_customimg'] ) ) { + $img[ $options['aioseop_opengraph_settings_customimg'] ] = 'customimg'; + $img[ $options['aioseop_opengraph_settings_customimg_twitter'] ] = 'customimg_twitter'; + } + + if ( $author_img = $this->get_the_image_by_author( $p ) ) { + $image['author'] = $author_img; + } + $image = array_flip( $img ); + $images = array(); + if ( ! empty( $image ) ) { + foreach ( $image as $k => $v ) { + $images[ $v ] = ''; + } + } + + return array( $image, $images ); + } + + function get_the_image_by_author( $options = null, $p = null ) { + if ( $p === null ) { + global $post; + } else { + $post = $p; + } + if ( ! empty( $post ) && ! empty( $post->post_author ) ) { + $matches = array(); + $get_avatar = get_avatar( $post->post_author, 300 ); + if ( preg_match( "/src='(.*?)'/i", $get_avatar, $matches ) ) { + return $matches[1]; + } + } + + return false; + } + + function get_the_image( $options = null, $p = null ) { + $meta_key = $this->options['aiosp_opengraph_meta_key']; + + return parent::get_the_image( array( 'meta_key' => $meta_key ), $p ); + } + + function get_the_image_by_default( $args = array() ) { + return $this->options['aiosp_opengraph_dimg']; + } + + function settings_update() { + + } + + /** + * Admin Enqueue Scripts + * + * Add hook in \All_in_One_SEO_Pack_Module::enqueue_metabox_scripts - Bails adding hook if not on target valid screen. + * Add hook in \All_in_One_SEO_Pack_Module::add_page_hooks - Function itself is hooked based on the screen_id/page. + * + * @since 2.9.2 + * + * @see 'admin_enqueue_scripts' hook + * @link https://developer.wordpress.org/reference/hooks/admin_enqueue_scripts/ + * + * @param string $hook_suffix + */ + public function admin_enqueue_scripts( $hook_suffix ) { + wp_enqueue_script( + 'aioseop-opengraph-script', + AIOSEOP_PLUGIN_URL . 'js/modules/aioseop_opengraph.js', + array(), + AIOSEOP_VERSION + ); + + // Dev note: If certain JS files need to be restricted to select screens, then follow concept + // used in `All_in_One_SEO_Pack::admin_enqueue_scripts()` (v2.9.1); which uses the `$hook_suffix` + // and a switch-case. This also helps prevent unnessecarily processing localized data when it isn't needed. + parent::admin_enqueue_scripts( $hook_suffix ); + } + + /** + * Enqueue our file upload scripts and styles. + * @param $hook + */ + function og_admin_enqueue_scripts( $hook ) { + + if ( 'all-in-one-seo_page_aiosp_opengraph' != $hook && 'term.php' != $hook ) { + // Only enqueue if we're on the social module settings page. + return; + } + + wp_enqueue_script( 'media-upload' ); + wp_enqueue_script( 'thickbox' ); + wp_enqueue_style( 'thickbox' ); + wp_enqueue_media(); + } + + function save_tax_data( $term_id, $tt_id, $taxonomy ) { + static $update = false; + if ( $update ) { + return; + } + if ( $this->locations !== null ) { + foreach ( $this->locations as $k => $v ) { + if ( isset( $v['type'] ) && ( $v['type'] === 'metabox' ) ) { + $opts = $this->default_options( $k ); + $options = array(); + $update = false; + foreach ( $opts as $l => $o ) { + if ( isset( $_POST[ $l ] ) ) { + $options[ $l ] = stripslashes_deep( $_POST[ $l ] ); + $options[ $l ] = esc_attr( $options[ $l ] ); + $update = true; + } + } + if ( $update ) { + $prefix = $this->get_prefix( $k ); + $options = apply_filters( $prefix . 'filter_term_metabox_options', $options, $k, $term_id ); + update_term_meta( $term_id, '_' . $prefix . $k, $options ); + } + } + } + } + } + + /** + * Returns the placeholder filtered and ready for DOM display. + * filter:aioseop_opengraph_placeholder + * @since 2.4.14 + * + * @param mixed $placeholder Placeholder to be filtered. + * @param string $type Type of the value to be filtered. + * + * @return string + */ + public function filter_placeholder( $placeholder, $type = 'text' ) { + return strip_tags( trim( $placeholder ) ); + } + + /** + * Returns filtered default options. + * filter:{prefix}default_options + * @since 2.4.13 + * + * @param array $options Default options. + * @param string $location Location. + * + * @return array + */ + public function filter_default_options( $options, $location ) { + if ( $location === 'settings' ) { + $prefix = $this->get_prefix( $location ) . $location . '_'; + // Add image checker as default + $options[ $prefix . 'customimg_checker' ] = 0; + } + return $options; + } + } +} From a18036d4f610e265ce86a3d78fc38c9308d2b565 Mon Sep 17 00:00:00 2001 From: contactashish13 Date: Thu, 28 Feb 2019 07:07:32 +0530 Subject: [PATCH 003/121] Updating large sitemap locks out WP-API (#2161) --- modules/aioseop_sitemap.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/aioseop_sitemap.php b/modules/aioseop_sitemap.php index 99d7542c3..0b66f3c43 100644 --- a/modules/aioseop_sitemap.php +++ b/modules/aioseop_sitemap.php @@ -445,6 +445,8 @@ public function __construct() { add_filter( $this->prefix . 'output_option', array( $this, 'display_custom_options' ), 10, 2 ); add_action( $this->prefix . 'daily_update_cron', array( $this, 'daily_update' ) ); add_action( 'init', array( $this, 'make_dynamic_xsl' ) ); + + // TODO is this required for dynamic sitemap? add_action( 'transition_post_status', array( $this, 'update_sitemap_from_posts' ), 10, 3 ); add_action( 'after_doing_aioseop_updates', array( $this, 'scan_sitemaps' ) ); add_action( 'all_admin_notices', array( $this, 'sitemap_notices' ) ); @@ -523,6 +525,10 @@ public function sitemap_notices() { * @param $post */ public function update_sitemap_from_posts( $new_status, $old_status, $post ) { + // ignore WP API requests. + if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) { + return; + } if ( $this->option_isset( 'rewrite' ) ) { // TODO if dynamic, delete transient (we currently don't do transients). From 117755bb30fdbaf505b95fb1d9e91fa83ca152d7 Mon Sep 17 00:00:00 2001 From: Arnaud Broes Date: Thu, 28 Feb 2019 16:15:57 +0100 Subject: [PATCH 004/121] Remove Exabot from bad bots blacklist (#2107) * Remove Exabot from bad bots blacklist #2104 * Remove Exabot from Bad Bot Blocker options #2104 * Change target version for free to 3.0 #2104 * we don't need to specify pro/non-pro for <3.0 testing #2107 --- admin/aioseop_module_class.php | 1 - inc/aioseop_updates_class.php | 30 +++++++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/admin/aioseop_module_class.php b/admin/aioseop_module_class.php index 3bc98f5a4..ff7109fb6 100644 --- a/admin/aioseop_module_class.php +++ b/admin/aioseop_module_class.php @@ -566,7 +566,6 @@ function default_bad_bots() { 'EmailSiphon', 'EmailWolf', 'EroCrawler', - 'Exabot', 'ExtractorPro', 'Fasterfox', 'FeedBooster', diff --git a/inc/aioseop_updates_class.php b/inc/aioseop_updates_class.php index fbae5d40c..623a4024e 100644 --- a/inc/aioseop_updates_class.php +++ b/inc/aioseop_updates_class.php @@ -120,7 +120,12 @@ function do_version_updates( $old_version ) { ) { $this->bad_bots_remove_semrush_201810(); } - + + if ( + version_compare( $old_version, '3.0', '<' ) + ) { + $this->bad_bots_remove_exabot_201902(); + } } /** @@ -223,6 +228,29 @@ function bad_bots_remove_semrush_201810() { $aiosp->update_class_option( $aioseop_options ); } } + + /** + * Removes Exabot from bad bot blocker to allow Alexabot. (#2105) + * + * @since 3.0 + * @global @aiosp, @aioseop_options + */ + function bad_bots_remove_exabot_201902(){ + global $aiosp, $aioseop_options; + + if ( isset( $aioseop_options['modules']['aiosp_bad_robots_options']['aiosp_bad_robots_blocklist'] ) ) { + $list = $aioseop_options['modules']['aiosp_bad_robots_options']['aiosp_bad_robots_blocklist']; + $list = str_replace( + array( + "Exabot\r\n", + "Exabot\n", + ), '', $list + ); + $aioseop_options['modules']['aiosp_bad_robots_options']['aiosp_bad_robots_blocklist'] = $list; + update_option( 'aioseop_options', $aioseop_options ); + $aiosp->update_class_option( $aioseop_options ); + } + } /** * Updates features. From eb1a1892af9c15b7e7eb362205b86a041cacceb3 Mon Sep 17 00:00:00 2001 From: EkoJR Date: Mon, 4 Mar 2019 08:06:07 -0800 Subject: [PATCH 005/121] Add Operative class for Admin Notices (#1855) * WPCS Clean * Change Notices Class Activate Notice method returns boolean for success * Change Notices Class constructor to allow Pro * Add Notices Class Note * Add Testcase for AIOSEOP_Notices initial operations * Add AIOSEOP_Notices class * Change display to render when JS is enqueued/printed * Fix deregister scripts/styles in AIOSEOP_Notices * Change Notices Testcase's setUp and tearDown Preserve and restore original notice data. Restore current user. Clean up. * Add test AIOSEOP_Noticed enqueue scripts * Add PHPUnit Test for Enqueue Scripts on Screens to notices base testcase * Change notices testcase file structure * Change display functions to refactor duplicate code * Add community standard DISABLE_NAG_NOTICES * Add function add_notice to base class * Change AJAX to send JSON error/success * Add fallback for PHPUnit with filter_input * Add time_set to single notices Primarily used for PHPUnit testing when comparing a time sensitive render time. * Add PHPUnit test for a notice's delay_time * Add PHPUnit test for Notices AJAX * Change Notice display to check user perms * Add PHPUnit test for Notice user perms/restrictions * Add PHPUnit test for Notices AJAX * Dev Notes & Cleanup * Add markTestSkipped for child classes with method test_enqueue_scripts_on_screens * Fix file path syntax with Travis CI * Fix boolean syntax in AIOSEOP_Notices class * Fix array param error with PHP 5.2 & 5.3 * Dev-Change allow admin notices in Pro * Dev-Change Scutinizer edits * Dev-Update phpDoc since tag * Dev-Update phpDoc since tag in PHPUnit test files * Dev-Fix user meta not updating on activate_notice * Dev-Fix screen restriction with aioseop slug * Dev-Add new screen id for robots module. * Dev-Fix compatability with alternate folder name * Dev-Fix travis issue with php5.5 >= * Dev-Change for review edits * Dev-Add missing translators * Dev-Change for review edits --- admin/class-aioseop-notices.php | 719 +++++++++++++++++ admin/display/notice-aioseop.php | 34 + admin/display/notice-default.php | 34 + admin/functions-notice.php | 11 + all_in_one_seo_pack.php | 1 + css/admin-notice.css | 12 + js/admin-notice.js | 118 +++ phpunit.xml.dist | 1 + tests/base/class-aioseop-notices-testcase.php | 730 ++++++++++++++++++ tests/classes/aioseop-notices/test-ajax.php | 572 ++++++++++++++ .../aioseop-notices/test-delay-time.php | 128 +++ .../aioseop-notices/test-enqueue-scripts.php | 111 +++ tests/classes/aioseop-notices/test-init.php | 260 +++++++ tests/classes/aioseop-notices/test-user.php | 210 +++++ 14 files changed, 2941 insertions(+) create mode 100644 admin/class-aioseop-notices.php create mode 100644 admin/display/notice-aioseop.php create mode 100644 admin/display/notice-default.php create mode 100644 admin/functions-notice.php create mode 100644 css/admin-notice.css create mode 100644 js/admin-notice.js create mode 100644 tests/base/class-aioseop-notices-testcase.php create mode 100644 tests/classes/aioseop-notices/test-ajax.php create mode 100644 tests/classes/aioseop-notices/test-delay-time.php create mode 100644 tests/classes/aioseop-notices/test-enqueue-scripts.php create mode 100644 tests/classes/aioseop-notices/test-init.php create mode 100644 tests/classes/aioseop-notices/test-user.php diff --git a/admin/class-aioseop-notices.php b/admin/class-aioseop-notices.php new file mode 100644 index 000000000..3f168b105 --- /dev/null +++ b/admin/class-aioseop-notices.php @@ -0,0 +1,719 @@ +aioseop_screens, + * array('CUSTOM') = specific screen(s). + * @type int $time_start The time the notice was added to the object. + * @type int $time_set Set when AJAX/Action_Option was last used to delay time. Primarily for PHPUnit tests. + * } + * } + */ + public $notices = array(); + + /** + * List of notice slugs that are currently active. + * NOTE: Amount is reduced by 1 second in order to display at exactly X amount of time. + * + * @since 3.0 + * @access public + * + * @var array $active_notices { + * @type string|int $slug => $display_time Contains the current active notices + * that are scheduled to be displayed. + * } + */ + public $active_notices = array(); + + /** + * The default dismiss time. An anti-nag setting. + * + * @var int $default_dismiss_delay + */ + private $default_dismiss_delay = 180; + + /** + * List of Screens used in AIOSEOP. + * + * @since 3.0 + * + * @var array $aioseop_screens { + * @type string Screen ID. + * } + */ + private $aioseop_screens = array(); + + /** + * __constructor. + * + * @since 3.0 + */ + public function __construct() { + $this->_requires(); + if ( current_user_can( 'aiosp_manage_seo' ) ) { + + $this->aioseop_screens[] = 'toplevel_page_' . AIOSEOP_PLUGIN_DIRNAME . '/aioseop_class'; + $this->aioseop_screens[] = 'all-in-one-seo_page_' . AIOSEOP_PLUGIN_DIRNAME . '/modules/aioseop_performance'; + $this->aioseop_screens[] = 'all-in-one-seo_page_' . AIOSEOP_PLUGIN_DIRNAME . '/modules/aioseop_sitemap'; + $this->aioseop_screens[] = 'all-in-one-seo_page_aiosp_opengraph'; + $this->aioseop_screens[] = 'all-in-one-seo_page_aiosp_robots_generator'; + $this->aioseop_screens[] = 'all-in-one-seo_page_' . AIOSEOP_PLUGIN_DIRNAME . '/modules/aioseop_robots'; + $this->aioseop_screens[] = 'all-in-one-seo_page_' . AIOSEOP_PLUGIN_DIRNAME . '/modules/aioseop_file_editor'; + $this->aioseop_screens[] = 'all-in-one-seo_page_' . AIOSEOP_PLUGIN_DIRNAME . '/modules/aioseop_importer_exporter'; + $this->aioseop_screens[] = 'all-in-one-seo_page_' . AIOSEOP_PLUGIN_DIRNAME . '/modules/aioseop_bad_robots'; + $this->aioseop_screens[] = 'all-in-one-seo_page_' . AIOSEOP_PLUGIN_DIRNAME . '/modules/aioseop_feature_manager'; + + $this->obj_load_options(); + + add_action( 'admin_init', array( $this, 'init' ) ); + add_action( 'current_screen', array( $this, 'admin_screen' ) ); + } + } + + /** + * _Requires + * + * Additional files required. + * + * @since 3.0 + */ + private function _requires() { + require_once AIOSEOP_PLUGIN_DIR . 'admin/functions-notice.php'; + } + + /** + * Early operations required by the plugin. + * + * AJAX requires being added early before screens have been loaded. + * + * @since 3.0 + */ + public function init() { + add_action( 'wp_ajax_aioseop_notice', array( $this, 'ajax_notice_action' ) ); + } + + /** + * Setup/Init Admin Screen + * + * Adds the initial actions to WP based on the Admin Screen being loaded. + * The AIOSEOP and Other Screens have separate methods that are used, and + * additional screens can be made exclusive/unique. + * + * @since 3.0 + * + * @param WP_Screen $current_screen The current screen object being loaded. + */ + public function admin_screen( $current_screen ) { + $this->deregister_scripts(); + if ( isset( $current_screen->id ) && in_array( $current_screen->id, $this->aioseop_screens, true ) ) { + // AIOSEO Notice Content. + add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) ); + add_action( 'all_admin_notices', array( $this, 'display_notice_aioseop' ) ); + } elseif ( isset( $current_screen->id ) ) { + // Default WP Notice. + add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) ); + add_action( 'all_admin_notices', array( $this, 'display_notice_default' ) ); + } + } + + /** + * Load AIOSEOP_Notice Options + * + * Gets the options for AIOSEOP_Notice to set its variables to. + * + * @since 3.0 + * @access private + * + * @see self::notices + * @see self::active_notices + */ + private function obj_load_options() { + $notices_options = $this->obj_get_options(); + + $this->notices = $notices_options['notices']; + $this->active_notices = $notices_options['active_notices']; + } + + /** + * Get AIOSEOP_Notice Options + * + * @since 3.0 + * @access private + * + * @return array + */ + private function obj_get_options() { + $defaults = array( + 'notices' => array(), + 'active_notices' => array(), + ); + + $notices_options = get_option( 'aioseop_notices' ); + if ( false === $notices_options ) { + return $defaults; + } + + return wp_parse_args( $notices_options, $defaults ); + } + + /** + * Update Notice Options + * + * @since 3.0 + * @access private + * + * @return boolean True if successful, using update_option() return value. + */ + private function obj_update_options() { + $notices_options = array( + 'notices' => $this->notices, + 'active_notices' => $this->active_notices, + ); + $old_notices_options = $this->obj_get_options(); + $notices_options = wp_parse_args( $notices_options, $old_notices_options ); + + return update_option( 'aioseop_notices', $notices_options ); + } + + /** + * Notice Default Values + * + * Returns the default value for a variable to be used in self::notices[]. + * + * @since 3.0 + * + * @see self::notices Array variable that stores the collection of notices. + * + * @return array Notice variable in self::notices. + */ + public function notice_defaults() { + return array( + 'slug' => '', + 'delay_time' => 0, + 'message' => '', + 'action_options' => array(), + 'class' => 'notice-info', + 'target' => 'site', + 'screens' => array(), + 'time_start' => time(), + 'time_set' => time(), + ); + } + + /** + * Action Options Default Values + * + * Returns the default value for action_options in self::notices[$slug]['action_options']. + * + * @since 3.0 + * + * @return array Action_Options variable in self::notices[$slug]['action_options']. + */ + public function action_options_defaults() { + return array( + 'time' => 0, + 'text' => __( 'Dismiss', 'all-in-one-seo-pack' ), + 'link' => '#', + 'dismiss' => true, + 'class' => '', + ); + } + + /** + * Set Notice Action Options + * + * Sets the Action Options in a Notice. + * + * @since 3.0 + * @access private + * + * @see self::insert_notice() + * @see self::update_notice() + * + * @param array $action_options New action options to be added/updated. + * @return array Action Options with new values added to old. + */ + private function set_action_options( $action_options ) { + $rtn_action_options = array(); + // This helps prevent invalid notices, and empty arrays need to skip this operation when + // there is no actions intended for notice. + if ( ! is_array( $action_options ) ) { + $rtn_action_options[] = $this->action_options_defaults(); + return $rtn_action_options; + } + + foreach ( $action_options as $action_option ) { + $tmp_action_o = $this->action_options_defaults(); + + // For readability and tracking, refrane from using another Foreach loop with the array indexes. + // Button Delay Time. + $tmp_action_o['time'] = $this->default_dismiss_delay; + if ( isset( $action_option['time'] ) ) { + $tmp_action_o['time'] = $action_option['time']; + } + + // Button Text. + if ( isset( $action_option['text'] ) && ! empty( $action_option['text'] ) ) { + $tmp_action_o['text'] = $action_option['text']; + } + + // Link. + if ( isset( $action_option['link'] ) && ! empty( $action_option['link'] ) ) { + $tmp_action_o['link'] = $action_option['link']; + } + + // Dismiss. + if ( isset( $action_option['dismiss'] ) ) { + $tmp_action_o['dismiss'] = $action_option['dismiss']; + } + + // Class. + if ( isset( $action_option['class'] ) && ! empty( $action_option['class'] ) ) { + $tmp_action_o['class'] = $action_option['class']; + } + + $rtn_action_options[] = $tmp_action_o; + } + + return $rtn_action_options; + } + + /** + * Insert Notice + * + * Initial insert for a Notice and Activates it. Used strictly for adding notices + * when no updating or modifications is intended. + * + * @since 3.0 + * + * @uses self::activate_notice() Used to initialize a notice. + * + * @param array $notice See self::notices for more info. + * @return boolean True on success. + */ + public function insert_notice( $notice = array() ) { + if ( empty( $notice['slug'] ) || isset( $this->notices[ $notice['slug'] ] ) ) { + return false; + } + + $this->notices[ $notice['slug'] ] = $this->prepare_notice( $notice ); + + $this->obj_update_options(); + $this->activate_notice( $notice['slug'] ); + + return true; + } + + /** + * Update Notice + * + * Updates an existing Notice without resetting it. Used when modifying + * any existing notices without disturbing its set environment/timeline. + * + * @since 3.0 + * + * @param array $notice See self::notices for more info. + * @return boolean True on success. + */ + public function update_notice( $notice = array() ) { + if ( empty( $notice['slug'] ) || ! isset( $this->notices[ $notice['slug'] ] ) ) { + return false; + } + + $this->notices[ $notice['slug'] ] = $this->prepare_notice( $notice ); + + $this->obj_update_options(); + + return true; + } + + /** + * Prepare Insert/Undate Notice + * + * @since 3.0 + * + * @param array $notice The notice to prepare with the database. + * @return bool + */ + public function prepare_notice( $notice = array() ) { + $notice_default = $this->notice_defaults(); + $new_notice = wp_parse_args( $notice, $notice_default ); + + $new_notice['action_options'] = $this->set_action_options( $new_notice['action_options'] ); + + return $new_notice; + } + + /** + * Used strictly for any notices that are deprecated/obsolete. To stop notices, + * use notice_deactivate(). + * + * @since 3.0 + * + * @param string $slug Unique notice slug. + * @return boolean True if successfully removed. + */ + public function remove_notice( $slug ) { + if ( isset( $this->notices[ $slug ] ) ) { + unset( $this->notices[ $slug ] ); + $this->obj_update_options(); + return true; + } + + return false; + } + + /** + * Activate Notice + * + * Activates a notice, or Re-activates with a new display time. Used after + * updating a notice that requires a hard reset. + * + * @since 3.0 + * + * @param string $slug Notice slug. + * @return boolean + */ + public function activate_notice( $slug ) { + if ( empty( $slug ) || ! isset( $this->notices[ $slug ] ) ) { + return false; + } + + // Display at exactly X time, not (X + 1) time. + $display_time = time() + $this->notices[ $slug ]['delay_time']; + $display_time--; + + if ( 'user' === $this->notices[ $slug ]['target'] ) { + $current_user_id = get_current_user_id(); + + update_user_meta( $current_user_id, 'aioseop_notice_dismissed_' . $slug, false ); + update_user_meta( $current_user_id, 'aioseop_notice_display_time_' . $slug, $display_time ); + } + + $this->active_notices[ $slug ] = $display_time; + $this->obj_update_options(); + + return true; + } + + /** + * Deactivate Notice + * + * Deactivates a notice set as active and completely removes it from the + * list of active notices. Used to prevent conflicting notices that may be + * active at any given point in time. + * + * @since 3.0 + * + * @param string $slug Notice slug. + * @return boolean + */ + public function deactivate_notice( $slug ) { + if ( ! isset( $this->active_notices[ $slug ] ) ) { + return false; + } elseif ( ! isset( $this->notices[ $slug ] ) ) { + return false; + } + + $this->notices[ $slug ]['active'] = false; + unset( $this->active_notices[ $slug ] ); + $this->obj_update_options(); + + return true; + } + + /*** DISPLAY Methods **************************************************/ + /** + * Deregister Scripts + * + * Initial Admin Screen action to remove aioseop script(s) from all screens; + * which will be registered if executed on screen. + * NOTE: As of 3.0, most of it is default layout, styling, & scripting + * that is loaded on all pages. Which can later be different. + * + * @since 3.0 + * @access private + * + * @see self::admin_screen() + */ + private function deregister_scripts() { + wp_deregister_script( 'aioseop-admin-notice-js' ); + wp_deregister_style( 'aioseop-admin-notice-css' ); + } + + /** + * (Register) Enqueue Scripts + * + * Used to register, enqueue, and localize any JS data. Styles can later be added. + * + * @since 3.0 + */ + public function admin_enqueue_scripts() { + // Register. + wp_register_script( + 'aioseop-admin-notice-js', + AIOSEOP_PLUGIN_URL . 'js/admin-notice.js', + array( 'jquery' ), + AIOSEOP_VERSION, + true + ); + + // Localization. + $notice_actions = array(); + foreach ( $this->active_notices as $notice_slug => $notice_display_time ) { + foreach ( $this->notices[ $notice_slug ]['action_options'] as $action_index => $action_arr ) { + $notice_actions[ $notice_slug ][] = $action_index; + } + } + + $admin_notice_localize = array( + 'notice_nonce' => wp_create_nonce( 'aioseop_ajax_notice' ), + 'notice_actions' => $notice_actions, + ); + wp_localize_script( 'aioseop-admin-notice-js', 'aioseop_notice_data', $admin_notice_localize ); + + // Enqueue. + wp_enqueue_script( 'aioseop-admin-notice-js' ); + + wp_enqueue_style( + 'aioseop-admin-notice-css', + AIOSEOP_PLUGIN_URL . 'css/admin-notice.css', + false, + AIOSEOP_VERSION, + false + ); + } + + /** + * Display Notice as Default + * + * Method for default WP Admin notices. + * NOTE: As of 3.0, display_notice_default() & display_notice_aioseop() + * have the same functionality, but serves as a future development concept. + * + * @since 3.0 + * + * @uses AIOSEOP_PLUGIN_DIR . 'admin/display/notice-default.php' Template for default notices. + * + * @return void + */ + public function display_notice_default() { + $this->display_notice( 'default' ); + } + + /** + * Display Notice as AIOSEOP Screens + * + * Method for Admin notices exclusive to AIOSEOP screens. + * NOTE: As of 3.0, display_notice_default() & display_notice_aioseop() + * have the same functionality, but serves as a future development concept. + * + * @since 3.0 + * + * @uses AIOSEOP_PLUGIN_DIR . 'admin/display/notice-aioseop.php' Template for notices. + * + * @return void + */ + public function display_notice_aioseop() { + $this->display_notice( 'aioseop' ); + } + + /** + * Display Notice + * + * @since 2.8 + * + * @param string $template Slug name for template. + */ + public function display_notice( $template ) { + if ( ! wp_script_is( 'aioseop-admin-notice-js', 'enqueued' ) || ! wp_style_is( 'aioseop-admin-notice-css', 'enqueued' ) ) { + return; + } elseif ( 'default' !== $template && 'aioseop' !== $template ) { + return; + } elseif ( ! current_user_can( 'aiosp_manage_seo' ) ) { + return; + } + + $current_screen = get_current_screen(); + $current_user_id = get_current_user_id(); + foreach ( $this->active_notices as $a_notice_slug => $a_notice_time_display ) { + $notice_show = true; + + // Screen Restriction. + if ( ! empty( $this->notices[ $a_notice_slug ]['screens'] ) ) { + // Checks if on aioseop screen. + if ( in_array( 'aioseop', $this->notices[ $a_notice_slug ]['screens'], true ) ) { + if ( ! in_array( $current_screen->id, $this->aioseop_screens, true ) ) { + continue; + } + } + + // Checks the other screen restrictions by slug/id. + if ( ! in_array( 'aioseop', $this->notices[ $a_notice_slug ]['screens'], true ) ) { + if ( ! in_array( $current_screen->id, $this->notices[ $a_notice_slug ]['screens'], true ) ) { + continue; + } + } + } + + // User Settings. + if ( 'user' === $this->notices[ $a_notice_slug ]['target'] ) { + $user_dismissed = get_user_meta( $current_user_id, 'aioseop_notice_dismissed_' . $a_notice_slug, true ); + if ( ! $user_dismissed ) { + $user_notice_time_display = get_user_meta( $current_user_id, 'aioseop_notice_display_time_' . $a_notice_slug, true ); + if ( ! empty( $user_notice_time_display ) ) { + $a_notice_time_display = intval( $user_notice_time_display ); + } + } else { + $notice_show = false; + } + } + + // Display/Render. + $important_admin_notices = array( + 'notice-error', + 'notice-warning', + 'notice-do-nag', + ); + if ( defined( 'DISABLE_NAG_NOTICES' ) && true === DISABLE_NAG_NOTICES && ( ! in_array( $this->notices[ $a_notice_slug ]['class'], $important_admin_notices, true ) ) ) { + // Skip if `DISABLE_NAG_NOTICES` is implemented (as true). + // Important notices, WP's CSS `notice-error` & `notice-warning`, are still rendered. + continue; + } elseif ( time() > $a_notice_time_display && $notice_show ) { + include AIOSEOP_PLUGIN_DIR . 'admin/display/notice-' . $template . '.php'; + } + } + } + + /** + * AJAX Notice Action + * + * Fires when a Action_Option is clicked and sent via AJAX. Also includes + * WP Default Dismiss (rendered as a clickable button on upper-right). + * + * @since 3.0 + * + * @see AIOSEOP_PLUGIN_DIR . 'js/admin-notice.js' + */ + public function ajax_notice_action() { + check_ajax_referer( 'aioseop_ajax_notice' ); + if ( ! current_user_can( 'aiosp_manage_seo' ) ) { + wp_send_json_error( __( 'User doesn\' have `aiosp_manage_seo` capabilities.', 'all-in-one-seo-pack' ) ); + } + // Notice (Slug) => (Action_Options) Index. + $notice_slug = null; + $action_index = null; + if ( isset( $_POST['notice_slug'] ) ) { + $notice_slug = filter_input( INPUT_POST, 'notice_slug', FILTER_SANITIZE_STRING ); + + // When PHPUnit is unable to use filter_input. + if ( defined( 'AIOSEOP_UNIT_TESTING' ) && null === $notice_slug && ! empty( $_POST['notice_slug'] ) ) { + $notice_slug = $_POST['notice_slug']; + } + } + if ( isset( $_POST['action_index'] ) ) { + $action_index = filter_input( INPUT_POST, 'action_index', FILTER_SANITIZE_STRING ); + + // When PHPUnit is unable to use filter_input. + if ( defined( 'AIOSEOP_UNIT_TESTING' ) && null === $action_index && ( ! empty( $_POST['action_index'] ) || 0 === $_POST['action_index'] ) ) { + $action_index = $_POST['action_index']; + } + } + if ( empty( $notice_slug ) ) { + /* Translators: Displays the hordcoded slug that missing. */ + wp_send_json_error( sprintf( __( 'Missing values from `%s`.', 'all-in-one-seo-pack' ), 'notice_slug' ) ); + } elseif ( empty( $action_index ) && 0 !== $action_index ) { + /* Translators: Displays the hordcoded slug that missing. */ + wp_send_json_error( sprintf( __( 'Missing values from `%s`.', 'all-in-one-seo-pack' ), 'action_index' ) ); + } + + $action_options = $this->action_options_defaults(); + $action_options['time'] = $this->default_dismiss_delay; + $action_options['dismiss'] = false; + + if ( isset( $this->notices[ $notice_slug ]['action_options'][ $action_index ] ) ) { + $action_options = $this->notices[ $notice_slug ]['action_options'][ $action_index ]; + } + + // User Notices or Sitewide. + if ( 'user' === $this->notices[ $notice_slug ]['target'] ) { + // Always sets the action time, even if dismissed, so last timestamp is recorded. + $current_user_id = get_current_user_id(); + if ( $action_options['time'] ) { + $time_set = time(); + // Adds action_option delay time, reduced by 1 second to display at exact time. + $metadata = $time_set + $action_options['time'] - 1; + + update_user_meta( $current_user_id, 'aioseop_notice_time_set_' . $notice_slug, $time_set ); + update_user_meta( $current_user_id, 'aioseop_notice_display_time_' . $notice_slug, $metadata ); + } + if ( $action_options['dismiss'] ) { + update_user_meta( $current_user_id, 'aioseop_notice_dismissed_' . $notice_slug, $action_options['dismiss'] ); + } + } else { + if ( $action_options['time'] ) { + $this->notices[ $notice_slug ]['time_set'] = time(); + // Adds action_option delay time, reduced by 1 second to display at exact time. + $this->active_notices[ $notice_slug ] = $this->notices[ $notice_slug ]['time_set'] + $action_options['time'] - 1; + } + + if ( $action_options['dismiss'] ) { + $this->deactivate_notice( $notice_slug ); + } + } + + $this->obj_update_options(); + wp_send_json_success( __( 'Notice updated successfully.', 'all-in-one-seo-pack' ) ); + } + + } + // CLASS INITIALIZATION. + // Should this be a singleton class instead of a global? + global $aioseop_notices; + $aioseop_notices = new AIOSEOP_Notices(); +} diff --git a/admin/display/notice-aioseop.php b/admin/display/notice-aioseop.php new file mode 100644 index 000000000..50c397ddd --- /dev/null +++ b/admin/display/notice-aioseop.php @@ -0,0 +1,34 @@ +notices[ $a_notice_slug ]; +$notice_class = 'notice-info'; +if ( isset( $notice['class'] ) && ! empty( $notice['class'] ) ) { + $notice_class = $notice['class']; +} + +?> +
+

+

+ $action_option ) : ?> + + + +

+
diff --git a/admin/display/notice-default.php b/admin/display/notice-default.php new file mode 100644 index 000000000..8d1ed60fe --- /dev/null +++ b/admin/display/notice-default.php @@ -0,0 +1,34 @@ +notices[ $a_notice_slug ]; +$notice_class = 'notice-info'; +if ( isset( $notice['class'] ) && ! empty( $notice['class'] ) ) { + $notice_class = $notice['class']; +} + +?> +
+

+

+ $action_option ) : ?> + + + +

+
diff --git a/admin/functions-notice.php b/admin/functions-notice.php new file mode 100644 index 000000000..5c08b59b5 --- /dev/null +++ b/admin/functions-notice.php @@ -0,0 +1,11 @@ + ./tests/modules/ + ./tests/classes/ diff --git a/tests/base/class-aioseop-notices-testcase.php b/tests/base/class-aioseop-notices-testcase.php new file mode 100644 index 000000000..6e1bb952d --- /dev/null +++ b/tests/base/class-aioseop-notices-testcase.php @@ -0,0 +1,730 @@ +define_wp_develop_dir(); + } + + parent::__construct( $name, $data, $dataName ); + } + + /** + * Define WP_DEVELOP_DIR + * + * @since 3.0 + */ + public function define_wp_develop_dir() { + if ( defined( 'WP_DEVELOP_DIR' ) ) { + return; + } + + global $_tests_dir; + global $config_file_path; + + self::assertNotEmpty( $_tests_dir ); + + $wp_develop_dir = ''; + if ( ! empty( $_tests_dir ) ) { + $wp_develop_dir = $_tests_dir; + $wp_develop_dir = str_replace( '/test/phpunit', '', $wp_develop_dir ); + $wp_develop_dir = str_replace( '\test\phpunit', '', $wp_develop_dir ); + } else if ( ! empty( $config_file_path ) ) { + $wp_develop_dir = $config_file_path; + $wp_develop_dir = str_replace( '/wp-tests-config.php', '', $wp_develop_dir ); + $wp_develop_dir = str_replace( '\wp-tests-config.php', '', $wp_develop_dir ); + } + + if ( ! empty( $wp_develop_dir ) ) { + define( 'WP_DEVELOP_DIR', $wp_develop_dir ); + } + } + + /** + * PHPUnit Fixture - setUp() + * + * @since 3.0 + * + * @link https://make.wordpress.org/core/handbook/testing/automated-testing/writing-phpunit-tests/#shared-setup-between-related-tests + */ + public function setUp() { + parent::setUp(); + + wp_set_current_user( 1 ); + + global $aioseop_notices; + if ( isset( $aioseop_notices ) && ! empty( $aioseop_notices ) ) { + $this->old_aioseop_notices = $aioseop_notices; + } + $this->old_aioseop_notices_options = get_option( 'aioseop_notices' ); + + $this->clean_aioseop_notices(); + } + + /** + * PHPUnit Fixture - tearDown() + * + * @since 3.0 + * + * @link https://make.wordpress.org/core/handbook/testing/automated-testing/writing-phpunit-tests/#shared-setup-between-related-tests + */ + public function tearDown() { + $this->clean_aioseop_notices(); + + global $aioseop_notices; + if ( isset( $this->old_aioseop_notices ) && ! empty( $this->old_aioseop_notices ) ) { + $aioseop_notices = $this->old_aioseop_notices; + $GLOBALS['aioseop_notices'] = $this->old_aioseop_notices; + } + if ( $this->old_aioseop_notices_options ) { + update_option( 'aioseop_notices', $this->old_aioseop_notices_options ); + } + + parent::tearDown(); + } + + /** + * Clean Options AIOSEOP Notices + * + * @since 3.0 + * + * @return boolean True if deleted, and false if it doesn't exist. + */ + public function clean_aioseop_notices() { + global $aioseop_notices; + if ( isset( $aioseop_notices ) && ! empty( $aioseop_notices ) ) { + $aioseop_notices = null; + unset( $GLOBALS['aioseop_notices'] ); + } + + return delete_option( 'aioseop_notices' ); + } + + /** + * Clean AIOSEOP Notices + * + * @since 3.0 + * + * @param string $notice_slug Target notice to delete. + * @return boolean True if deleted. + */ + public function clean_aioseop_notice( $notice_slug ) { + $notices_options = get_option( 'aioseop_notices' ); + if ( false === $notices_options ) { + return false; + } elseif ( ! isset( $notices_options['notices'][ $notice_slug ] ) || ! isset( $notices_options['active_notices'][ $notice_slug ] ) ) { + return false; + } + + unset( $notices_options['notices'][ $notice_slug ] ); + unset( $notices_options['active_notices'][ $notice_slug ] ); + + return true; + } + + /** + * Validate Global AIOSEOP_Notices object. + * + * @since 3.0 + * + * @param AIOSEOP_Notices $aioseop_notices The current object to test for. + */ + protected function validate_class_aioseop_notices( $aioseop_notices ) { + $this->assertInstanceOf( 'AIOSEOP_Notices', $aioseop_notices, 'Not an instance of AIOSEOP_Notices.' ); + + $class_attrs = array( + 'notices' => 'array', + 'active_notices' => 'array', + 'default_dismiss_delay' => 'int', + 'aioseop_screens' => 'array', + ); + + // Loop through each variable, and check if isset and value type (type-case). + foreach ( $class_attrs as $attr_name => $attr_type ) { + $this->assertObjectHasAttribute( $attr_name, $aioseop_notices, 'Variable is not set.' ); + $this->assertAttributeInternalType( $attr_type, $attr_name, $aioseop_notices, 'Error with Type casting.' ); + if ( 'notices' === $attr_name ) { + $this->validate_attr_notices( $aioseop_notices->$attr_name ); + } + } + } + + /** + * Validates AIOSEOP_Notices::notices + * + * Checks to see if variables are correctly set. + * + * @since 3.0 + * + * @param array $notices Class variable `AIOSEOP_Notices::notices`. + */ + protected function validate_attr_notices( $notices ) { + foreach ( $notices as $notice ) { + $this->validate_attr_notice( $notice ); + } + } + + /** + * Validates notice in AIOSEOP_Notices::notices + * + * Checks to see if the array variables are correctly set. + * + * @since 3.0 + * + * @param array $notice Class variable `AIOSEOP_Notices::notices`. + */ + protected function validate_attr_notice( $notice ) { + $notices_attrs = array( + 'slug' => 'string', + 'delay_time' => 'int', + 'message' => 'string', + 'action_options' => 'array', + 'class' => 'string', + 'target' => 'string', + 'screens' => 'array', + 'time_start' => 'int', + ); + + $action_option_attrs = array( + 'time' => 'int', + 'text' => 'string', + 'class' => 'string', + 'link' => 'string', + 'dismiss' => 'boolean', + ); + + foreach ( $notices_attrs as $attr_name => $attr_type ) { + $this->assertArrayHasKey( $attr_name, $notice, 'Index/Key not found in Notice Array.' ); + $this->assertInternalType( $attr_type, $notice[ $attr_name ], 'Invalid value type (' . $attr_type . ') in ' . $attr_name ); + + if ( 'action_option' === $attr_name ) { + foreach ( $action_option_attrs as $action_attr_name => $action_attr_type ) { + $this->assertArrayHasKey( $action_attr_name, $notice[ $attr_name ], 'Index/Key not found.' ); + $this->assertInternalType( $action_attr_type, $notice[ $attr_name ][ $action_attr_name ], 'Invalid value type.' ); + } + } + } + } + + /** + * Mock Single Notice + * + * @since 3.0 + * + * @return array + */ + protected function mock_notice() { + return array( + 'slug' => 'notice_slug_1', + 'delay_time' => 3600, // 1 Hour. + 'message' => __( 'Admin Sample Message.', 'all-in-one-seo-pack' ), + 'action_options' => array( + array( + 'time' => 0, + 'text' => __( 'Link and close', 'all-in-one-seo-pack' ), + 'link' => 'https://wordpress.org/support/plugin/all-in-one-seo-pack', + 'dismiss' => false, + 'class' => '', + ), + array( + 'text' => 'Delay', + 'time' => 432000, + 'dismiss' => false, + 'class' => '', + ), + array( + 'time' => 0, + 'text' => 'Dismiss', + 'dismiss' => true, + 'class' => '', + ), + ), + 'target' => 'site', + 'screens' => array(), + ); + } + + /** + * Add Notice + * + * Adds and validates the a (child test) notice being tested. + * + * @since 3.0 + * + * @param array $notice Value from `$aioseop_notices`. + */ + protected function add_notice( $notice = array() ) { + global $aioseop_notices; + if ( null === $aioseop_notices ) { + $aioseop_notices = new AIOSEOP_Notices(); + } + $this->validate_class_aioseop_notices( $aioseop_notices ); + if ( empty( $notice ) ) { + $notice = $this->mock_notice(); + } + + // Insert Successful and activated. + $this->assertTrue( $aioseop_notices->insert_notice( $notice ) ); + $this->assertTrue( in_array( $notice['slug'], $notice, true ) ); + + $this->assertTrue( isset( $aioseop_notices->active_notices[ $notice['slug'] ] ) ); + $this->assertNotNull( $aioseop_notices->active_notices[ $notice['slug'] ] ); + + // Validates the global $aioseop_notices instance and variable types. + $this->validate_class_aioseop_notices( $aioseop_notices ); + } + + /** + * Add Notice + * + * Function: Inserts, and Updates, a single notice into wp_options. + * Expected: If no notice exists, it shouldn't be operational, and new notices should insert instead of update. Then + * should be able to update without effecting the active notices. + * Actual: As expected; no current issue. + * Result: Inserts and Updates successfully to the database (wp_options). + * + * @since 3.0 + * + * @param array $notice Single notice to add to object/database. + */ + public function test_add_notice( $notice = array() ) { + global $aioseop_notices; + if ( null === $aioseop_notices ) { + $aioseop_notices = new AIOSEOP_Notices(); + } + if ( empty( $notice ) ) { + $notice = $this->mock_notice(); + } + + // Shouldn't exist yet. + $this->assertFalse( $aioseop_notices->activate_notice( $notice['slug'] ) ); + $this->assertFalse( $aioseop_notices->deactivate_notice( $notice['slug'] ) ); + + // Cannot update before insert. + $this->assertFalse( $aioseop_notices->update_notice( $notice ) ); + + // Insert Successful and activated. + $this->assertTrue( $aioseop_notices->insert_notice( $notice ) ); + $this->assertTrue( in_array( $notice['slug'], $notice, true ) ); + + // Re-Insert Failed. + $this->assertFalse( $aioseop_notices->insert_notice( $notice ) ); + + // Deactivate. + $this->assertTrue( $aioseop_notices->deactivate_notice( $notice['slug'] ) ); + $this->assertFalse( $aioseop_notices->deactivate_notice( $notice['slug'] ) ); + $this->assertFalse( isset( $aioseop_notices->active_notices[ $notice['slug'] ] ) ); + + // Update success, but notice is not active. + $this->assertTrue( $aioseop_notices->update_notice( $notice ) ); + $this->assertFalse( isset( $aioseop_notices->active_notices[ $notice['slug'] ] ) ); + + // Activate. + $this->assertTrue( $aioseop_notices->activate_notice( $notice['slug'] ) ); + $this->assertTrue( isset( $aioseop_notices->active_notices[ $notice['slug'] ] ) ); + $this->assertNotNull( $aioseop_notices->active_notices[ $notice['slug'] ] ); + + // Update Successful. + $this->assertTrue( $aioseop_notices->update_notice( $notice ) ); + } + + /** + * Test enqueue scripts on screens. + * + * Function: Enqueue Scripts and Styles with the WP Enqueue hook. + * Expected: Registered and enqueue scripts on target screens; provided by data_screens. + * Actual: As expected; no current issue. + * Result: Scripts are ready to be printed via enqueue. + * + * * should not enqueue if before delayed amount of time. + * * -notices with screen restrictions should be true only on set screens + * * (Test Render) Should not display content if script doesn't enqueue; also should send a Debug notice. + * + * @since 3.0 + * + * @dataProvider data_screens + * + * @param string $screen_id + * @param string $url + * @param string $dir + */ + public function test_enqueue_scripts_on_screens( $screen_id, $url, $dir ) { + + global $aioseop_notices; + if ( null === $aioseop_notices ) { + $aioseop_notices = new AIOSEOP_Notices(); + } + $this->validate_class_aioseop_notices( $aioseop_notices ); + + // Should be empty. + $this->assertTrue( empty( $aioseop_notices->active_notices ) ); + + $notice = $this->mock_notice(); + + // Insert Successful and activated. + $this->assertTrue( $aioseop_notices->insert_notice( $notice ) ); + $this->assertTrue( in_array( $notice['slug'], $notice, true ) ); + + $this->assertTrue( isset( $aioseop_notices->active_notices[ $notice['slug'] ] ) ); + $this->assertNotNull( $aioseop_notices->active_notices[ $notice['slug'] ] ); + + $this->validate_class_aioseop_notices( $aioseop_notices ); + + wp_deregister_script( 'aioseop-admin-notice-js' ); + wp_deregister_style( 'aioseop-admin-notice-css' ); + $this->assertFalse( wp_script_is( 'aioseop-admin-notice-js', 'registered' ), 'Screen: ' . $screen_id ); + + set_current_screen( $screen_id ); + $this->go_to( $url ); + + $aioseop_notices = new AIOSEOP_Notices(); + + set_current_screen( $screen_id ); + + $this->assertFalse( wp_script_is( 'aioseop-admin-notice-js', 'registered' ), 'Screen: ' . $screen_id ); + + do_action( 'admin_enqueue_scripts' ); + + $this->assertTrue( wp_script_is( 'aioseop-admin-notice-js', 'registered' ), 'Screen: ' . $screen_id ); + $this->assertTrue( wp_script_is( 'aioseop-admin-notice-js', 'enqueued' ) ); + } + + /** + * DataProvider for Screens + * + * TODO Create a restricted screens array to test for false. + * + * @since 3.0 + * + * @return array + */ + public function data_screens() { + $notice = $this->mock_notice(); + + $screens = array(); + if ( empty( $notice['screens'] ) ) { + $screens = array_merge( $this->data_screens_wp(), $this->data_screens_aioseop() ); + } elseif ( 'aioseop' === $notice['screens'] ) { + $screens = $this->data_screens_aioseop(); + } elseif ( ! empty( $notice['screens'] ) ) { + $all_screens = array_merge( $this->data_screens_wp(), $this->data_screens_aioseop() ); + + foreach ( $notice['screens'] as $n_screen ) { + foreach ( $all_screens as $screen ) { + if ( $n_screen === $screen['screen_id'] ) { + $screens[] = $screen; + } + } + } + } + + return $screens; + } + + /** + * Data (Provider) for Default/WP Screens + * + * @since 3.0 + * + * @return array + */ + protected function data_screens_wp() { + return array( + array( + 'screen_id' => 'dashboard', + 'url' => site_url() . '/wp-admin/index.php', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/index.php', + ), + array( + 'screen_id' => 'update-core', + 'url' => site_url() . '/wp-admin/update-core.php', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/update-core.php', + ), + + array( + 'screen_id' => 'edit-post', + 'url' => site_url() . '/wp-admin/edit.php', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/edit.php', + ), + array( + 'screen_id' => 'post', + 'url' => site_url() . '/wp-admin/post-new.php', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/post-new.php', + ), +// array( +// 'screen_id' => 'post', +// 'url' => site_url() . '/wp-admin/post.php?post=###&action=edit', +// 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/post.php?post=###&action=edit', +// ), + array( + 'screen_id' => 'edit-category', + 'url' => site_url() . '/wp-admin/edit-tags.php?taxonomy=category', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/edit-tags.php?taxonomy=category', + ), +// array( +// 'screen_id' => 'edit-category', +// 'url' => site_url() . '/wp-admin/edit-tags.php?action=edit&taxonomy=category&tag_ID=###&post_type=post', +// 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/edit-tags.php?action=edit&taxonomy=category&tag_ID=###&post_type=post', +// ), + array( + 'screen_id' => 'edit-post_tag', + 'url' => site_url() . '/wp-admin/edit-tags.php?taxonomy=post_tag', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/edit-tags.php?taxonomy=post_tag', + ), +// array( +// 'screen_id' => 'edit-post_tag', +// 'url' => site_url() . '/wp-admin/edit-tags.php?action=edit&taxonomy=post_tag&tag_ID=###&post_type=post', +// 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/edit-tags.php?action=edit&taxonomy=post_tag&tag_ID=###&post_type=post', +// ), + // Custom Post Types. + // Custom Taxonomies. + array( + 'screen_id' => 'upload', + 'url' => site_url() . '/wp-admin/upload.php', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/upload.php', + ), + array( + 'screen_id' => 'media', + 'url' => site_url() . '/wp-admin/media-new.php', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/media-new.php', + ), +// array( +// 'screen_id' => 'attachment', +// 'url' => site_url() . '/wp-admin/post.php?post=###&action=edit', +// 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/post.php?post=###&action=edit', +// ), + array( + 'screen_id' => 'edit-page', + 'url' => site_url() . '/wp-admin/edit.php?post_type=page', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/edit.php?post_type=page', + ), + array( + 'screen_id' => 'page', + 'url' => site_url() . '/wp-admin/post-new.php?post_type=page', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/post-new.php?post_type=page', + ), +// array( +// 'screen_id' => 'page', +// 'url' => site_url() . '/wp-admin/post.php?post=###&action=edit', +// 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/post.php?post=###&action=edit', +// ), + array( + 'screen_id' => 'edit-comments', + 'url' => site_url() . '/wp-admin/edit-comments.php', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/edit-comments.php', + ), +// array( +// 'screen_id' => 'comment', +// 'url' => site_url() . '/wp-admin/comment.php?action=editcomment&c=###', +// 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/comment.php?action=editcomment&c=###', +// ), + array( + 'screen_id' => 'themes', + 'url' => site_url() . '/wp-admin/themes.php', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/themes.php', + ), + array( + 'screen_id' => 'widgets', + 'url' => site_url() . '/wp-admin/widgets.php', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/widgets.php', + ), + array( + 'screen_id' => 'nav-menus', + 'url' => site_url() . '/wp-admin/nav-menus.php', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/nav-menus.php', + ), + array( + 'screen_id' => 'theme-editor', + 'url' => site_url() . '/wp-admin/theme-editor.php', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/theme-editor.php', + ), +// array( +// 'screen_id' => 'appearance_page_{page}', +// 'url' => site_url() . '/wp-admin/themes.php?page={page}', +// 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/themes.php?page={page}', +// ), + + array( + 'screen_id' => 'plugins', + 'url' => site_url() . '/wp-admin/plugins.php', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/plugins.php', + ), + array( + 'screen_id' => 'plugin-install', + 'url' => site_url() . '/wp-admin/plugin-install.php', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/plugin-install.php', + ), + array( + 'screen_id' => 'plugin-editor', + 'url' => site_url() . '/wp-admin/plugin-editor.php', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/plugin-editor.php', + ), + + array( + 'screen_id' => 'users', + 'url' => site_url() . '/wp-admin/users.php', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/users.php', + ), + array( + 'screen_id' => 'user-new', + 'url' => site_url() . '/wp-admin/user-new.php', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/user-new.php', + ), +// array( +// 'screen_id' => 'user-edit', +// 'url' => site_url() . '/wp-admin/user-edit.php?user_id=###', +// 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/user-edit.php?user_id=###', +// ), + array( + 'screen_id' => 'profile', + 'url' => site_url() . '/wp-admin/profile.php', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/profile.php', + ), + + array( + 'screen_id' => 'tools', + 'url' => site_url() . '/wp-admin/tools.php', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/tools.php', + ), + array( + 'screen_id' => 'import', + 'url' => site_url() . '/wp-admin/import.php', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/import.php', + ), + array( + 'screen_id' => 'export', + 'url' => site_url() . '/wp-admin/export.php', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/export.php', + ), + + array( + 'screen_id' => 'options-general', + 'url' => site_url() . '/wp-admin/options-general.php', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/options-general.php', + ), + array( + 'screen_id' => 'options-writing', + 'url' => site_url() . '/wp-admin/options-writing.php', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/options-writing.php', + ), + array( + 'screen_id' => 'options-reading', + 'url' => site_url() . '/wp-admin/options-reading.php', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/options-reading.php', + ), + array( + 'screen_id' => 'options-discussion', + 'url' => site_url() . '/wp-admin/options-discussion.php', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/options-discussion.php', + ), + array( + 'screen_id' => 'options-media', + 'url' => site_url() . '/wp-admin/options-media.php', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/options-media.php', + ), + array( + 'screen_id' => 'options-permalink', + 'url' => site_url() . '/wp-admin/options-permalink.php', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/options-permalink.php', + ), + + ); + } + + /** + * Data (Provider) for AIOSEOP Screens + * + * @since 3.0 + * + * @return array + */ + protected function data_screens_aioseop() { + return array( + array( + 'screen_id' => 'toplevel_page_all-in-one-seo-pack/aioseop_class', + 'url' => site_url() . '/wp-admin/admin.php?page=aioseop%2Faioseop_class.php', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/admin.php?page=aioseop%2Faioseop_class.php', + ), + array( + 'screen_id' => 'all-in-one-seo_page_all-in-one-seo-pack/modules/aioseop_performance', + 'url' => site_url() . '/wp-admin/admin.php?page=aioseop%2Fmodules%2Faioseop_performance.php', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/admin.php?page=aioseop%2Fmodules%2Faioseop_performance.php', + ), + array( + 'screen_id' => 'all-in-one-seo_page_all-in-one-seo-pack/modules/aioseop_sitemap', + 'url' => site_url() . '/wp-admin/admin.php?page=aioseop%2Fmodules%2Faioseop_sitemap.php', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/admin.php?page=aioseop%2Fmodules%2Faioseop_sitemap.php', + ), + array( + 'screen_id' => 'all-in-one-seo_page_aiosp_opengraph', + 'url' => site_url() . '/wp-admin/admin.php?page=aiosp_opengraph', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/admin.php?page=aiosp_opengraph', + ), + array( + 'screen_id' => 'all-in-one-seo_page_aiosp_robots_generator', + 'url' => site_url() . '/wp-admin/admin.php?page=aiosp_robots_generator', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/admin.php?page=aiosp_robots_generator', + ), + array( + 'screen_id' => 'all-in-one-seo_page_all-in-one-seo-pack/modules/aioseop_file_editor', + 'url' => site_url() . '/wp-admin/admin.php?page=aioseop%2Fmodules%2Faioseop_file_editor.php', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/admin.php?page=aioseop%2Fmodules%2Faioseop_file_editor.php', + ), + array( + 'screen_id' => 'all-in-one-seo_page_all-in-one-seo-pack/modules/aioseop_importer_exporter', + 'url' => site_url() . '/wp-admin/admin.php?page=aioseop%2Fmodules%2Faioseop_importer_exporter.php', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/admin.php?page=aioseop%2Fmodules%2Faioseop_importer_exporter.php', + ), + array( + 'screen_id' => 'all-in-one-seo_page_all-in-one-seo-pack/modules/aioseop_bad_robots', + 'url' => site_url() . '/wp-admin/admin.php?page=aioseop%2Fmodules%2Faioseop_bad_robots.php', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/admin.php?page=aioseop%2Fmodules%2Faioseop_bad_robots.php', + ), + array( + 'screen_id' => 'all-in-one-seo_page_all-in-one-seo-pack/modules/aioseop_feature_manager', + 'url' => site_url() . '/wp-admin/admin.php?page=aioseop%2Fmodules%2Faioseop_feature_manager.php', + 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/admin.php?page=aioseop%2Fmodules%2Faioseop_feature_manager.php', + ), + ); + + } +} diff --git a/tests/classes/aioseop-notices/test-ajax.php b/tests/classes/aioseop-notices/test-ajax.php new file mode 100644 index 000000000..504580569 --- /dev/null +++ b/tests/classes/aioseop-notices/test-ajax.php @@ -0,0 +1,572 @@ +old_aioseop_notices = $aioseop_notices; + } + $this->old_aioseop_notices_options = get_option( 'aioseop_notices' ); + + $this->clean_aioseop_notices(); + } + + /** + * PHPUnit Fixture - tearDown() + * + * @since 3.0 + * + * @link https://make.wordpress.org/core/handbook/testing/automated-testing/writing-phpunit-tests/#shared-setup-between-related-tests + */ + public function tearDown() { + $this->clean_aioseop_notices(); + + global $aioseop_notices; + if ( isset( $this->old_aioseop_notices ) && ! empty( $this->old_aioseop_notices ) ) { + $aioseop_notices = $this->old_aioseop_notices; + $GLOBALS['aioseop_notices'] = $this->old_aioseop_notices; + } + if ( $this->old_aioseop_notices_options ) { + update_option( 'aioseop_notices', $this->old_aioseop_notices_options ); + } + + parent::tearDown(); + } + + /** + * Clean Options AIOSEOP Notices + * + * @since 3.0 + * + * @return boolean True if deleted, and false if it doesn't exist. + */ + public function clean_aioseop_notices() { + global $aioseop_notices; + if ( isset( $aioseop_notices ) && ! empty( $aioseop_notices ) ) { + $aioseop_notices = null; + unset( $GLOBALS['aioseop_notices'] ); + } + + return delete_option( 'aioseop_notices' ); + } + + /** + * Mock Single Notice + * + * @since 3.0 + * + * @return array + */ + protected function mock_notice() { + return array( + 'slug' => 'notice_delay_ajax', + 'delay_time' => 0, + 'message' => __( 'Admin Sample Message.', 'all-in-one-seo-pack' ), + 'action_options' => array( + array( + 'time' => 0, + 'text' => __( 'Link and close', 'all-in-one-seo-pack' ), + 'link' => 'https://wordpress.org/support/plugin/all-in-one-seo-pack', + 'dismiss' => false, + 'class' => '', + ), + array( + 'text' => 'Delay', + 'time' => 30, + 'dismiss' => false, + 'class' => '', + ), + array( + 'time' => 0, + 'text' => 'Dismiss', + 'dismiss' => true, + 'class' => '', + ), + ), + 'target' => 'site', + 'screens' => array(), + ); + } + + /** + * Mock Single Notice + * + * @since 3.0 + * + * @return array + */ + protected function mock_notice_target_user() { + return array( + 'slug' => 'notice_slug_user', + 'delay_time' => 0, + 'message' => __( 'Admin Sample Message.', 'all-in-one-seo-pack' ), + 'action_options' => array( + array( + 'time' => 0, + 'text' => __( 'Link and close', 'all-in-one-seo-pack' ), + 'link' => 'https://wordpress.org/support/plugin/all-in-one-seo-pack', + 'dismiss' => false, + 'class' => '', + ), + array( + 'text' => 'Delay', + 'time' => 2, + 'dismiss' => false, + 'class' => '', + ), + array( + 'time' => 0, + 'text' => 'Dismiss', + 'dismiss' => true, + 'class' => '', + ), + ), + 'target' => 'user', + 'screens' => array(), + ); + } + + /** + * Add Notice + * + * Adds and validates the a (child test) notice being tested. + * + * @since 3.0 + * + * @param array $notice Value from `$aioseop_notices`. + */ + protected function add_notice( $notice = array() ) { + global $aioseop_notices; + if ( null === $aioseop_notices ) { + $aioseop_notices = new AIOSEOP_Notices(); + } + + if ( empty( $notice ) ) { + $notice = $this->mock_notice(); + } + + // Insert Successful and activated. + $this->assertTrue( $aioseop_notices->insert_notice( $notice ) ); + $this->assertTrue( in_array( $notice['slug'], $notice, true ) ); + + $this->assertTrue( isset( $aioseop_notices->active_notices[ $notice['slug'] ] ) ); + $this->assertNotNull( $aioseop_notices->active_notices[ $notice['slug'] ] ); + } + + /** + * Test Notice Missing wp_nonce Error + * + * Function: Returns an error contained in JSON status & message. Normally - Sets the active_notices display time, or dismisses the notification. + * Expected: Operation is not completed and an error is returned within a JSON string. + * Actual: Currently works as expected. + * Reproduce: Dev hardcoded an invalid/missing wp_nonce in `AIOSEOP_Notices::admin_enqueue_scripts()`. + * + * @since 3.0 + */ + public function test_notice_missing_wp_nonce_error() { + $this->add_notice(); + + $ex = null; + try { + $this->_handleAjax( 'aioseop_notice' ); + } catch ( WPAjaxDieStopException $ex ) { + // We expected this, do nothing. + // Fail with missing wp_nonce. + } + + // Check if an exception was thrown. + $this->assertInstanceOf( 'WPAjaxDieStopException', $ex, 'Not an instance of WPAjaxDieStopException.' ); + $this->assertTrue( isset( $ex ) ); + + // Error message is -1 for failure. + $this->assertEquals( '-1', $ex->getMessage() ); + } + + /** + * Test Notice Missing notice_slug Error + * + * Function: Returns an error contained in JSON status & message. Normally - Sets the active_notices display time, or dismisses the notification. + * Expected: Operation is not completed and an error is returned within a JSON string. + * Actual: Currently works as expected. + * Reproduce: Dev hardcoded the notice template with an invalid notice_slug in an element. + * + * @since 3.0 + */ + public function test_notice_missing_notice_slug_error() { + $this->add_notice(); + + // Create the nonce in the POST superglobal. + $_POST['_wpnonce'] = wp_create_nonce( 'aioseop_ajax_notice' ); + + $ex = null; + try { + $this->_handleAjax( 'aioseop_notice' ); + } catch ( WPAjaxDieStopException $ex ) { + // We did not expected this, do nothing & check assert instance of `WPAjaxDieContinueException`. + } catch ( WPAjaxDieContinueException $ex ) { + // We expected this, do nothing. + } + + // Check if an exception was thrown. + $this->assertInstanceOf( 'WPAjaxDieContinueException', $ex, 'Not an instance of WPAjaxDieContinueException.' ); + $this->assertTrue( isset( $ex ) ); + + // No error message on expected failure. + $this->assertEquals( '', $ex->getMessage() ); + + // Check data returned on expected fail. + $response = json_decode( $this->_last_response ); + $this->assertInternalType( 'object', $response ); + $this->assertObjectHasAttribute( 'success', $response ); + $this->assertFalse( $response->success ); + $this->assertObjectHasAttribute( 'data', $response ); + $this->assertEquals( 'Missing values from `notice_slug`.', $response->data ); + } + + /** + * Test Notice Missing Action Index Error + * + * Function: Returns an error contained in JSON status & message. Normally - Sets the active_notices display time, or dismisses the notification. + * Expected: Operation is not completed and an error is returned within a JSON string. + * Actual: Currently works as expected. + * Reproduce: Dev hardcoded the notice template with an invalid action_index in the element ID. + * + * @since 3.0 + */ + public function test_notice_missing_action_index_error() { + $notice = $this->mock_notice(); + $this->add_notice(); + + $_POST['_wpnonce'] = wp_create_nonce( 'aioseop_ajax_notice' ); + $_POST['notice_slug'] = $notice['slug']; + + $ex = null; + try { + $this->_handleAjax( 'aioseop_notice' ); + } catch ( WPAjaxDieStopException $ex ) { + // We did not expected this, do nothing & check assert instance of `WPAjaxDieContinueException`. + } catch ( WPAjaxDieContinueException $ex ) { + // We expected this, do nothing. + } + + // Check if an exception was thrown. + $this->assertInstanceOf( 'WPAjaxDieContinueException', $ex, 'Not an instance of WPAjaxDieContinueException.' ); + $this->assertTrue( isset( $ex ) ); + + // No error message on expected failure. + $this->assertEquals( '', $ex->getMessage() ); + + // Check data returned on expected fail. + $response = json_decode( $this->_last_response ); + $this->assertInternalType( 'object', $response ); + $this->assertObjectHasAttribute( 'success', $response ); + $this->assertFalse( $response->success ); + $this->assertObjectHasAttribute( 'data', $response ); + $this->assertEquals( 'Missing values from `action_index`.', $response->data ); + } + + /** + * Test Action Delay Time + * + * Function: Sets the active_notices display time, or dismisses the notification. + * Expected: No/zero delay or false dismiss makes no changes, 1+ delay changes the active_notice display time and time_set, + * and true dismiss will remove notice from active_notices but will still remain in AIOSEOP_Notices:notices. + * Actual: Currently works as expected. + * Reproduce: Have a notice added to the database and rendered (after set delay_time). Within the admin notice, there + * would be buttons/links (aka action_options). Clicking on any of them will initiate the AJAX event. + * + * @since 3.0 + */ + public function test_notice_action_delay_time() { + global $aioseop_notices; + $notice = $this->mock_notice(); + $this->add_notice(); + + /* + * Action_Options 0 - No delay, no dismiss. + */ + + // Create the nonce in the POST superglobal. + $_POST['_wpnonce'] = wp_create_nonce( 'aioseop_ajax_notice' ); + + // The slug from `$this->mock_notice()`. + $_POST['notice_slug'] = $notice['slug']; + + // Key value from action_option array index. + $_POST['action_index'] = 0; + + try { + $this->_handleAjax( 'aioseop_notice' ); + } catch ( WPAjaxDieStopException $ex ) { + // We did not expected this, do nothing & check on assertion. + } catch ( WPAjaxDieContinueException $ex ) { + // We did not expected this, do nothing & check on assertion. + } + + $response = json_decode( $this->_last_response ); + $this->assertInternalType( 'object', $response ); + $this->assertObjectHasAttribute( 'success', $response ); + $this->assertTrue( $response->success ); + $this->assertObjectHasAttribute( 'data', $response ); + $this->assertEquals( 'Notice updated successfully.', $response->data ); + + // Check if notice is still active. + $this->assertArrayHasKey( $notice['slug'], $aioseop_notices->notices, 'AJAX Notice should still be added.' ); + $this->assertArrayHasKey( $notice['slug'], $aioseop_notices->active_notices, 'AJAX Notice should still be active.' ); + // Check delay time. + $expected_time = $aioseop_notices->notices[ $notice['slug'] ]['time_set'] + $aioseop_notices->notices[ $notice['slug'] ]['action_options']['0']['time']; + // Add 1 to compensate for exact time display. + $actual_time = $aioseop_notices->active_notices[ $notice['slug'] ] + 1; + + $this->assertGreaterThanOrEqual( $expected_time, $actual_time ); + $this->assertLessThanOrEqual( ( $expected_time + 1 ), $actual_time ); + + /* + * Action_Options 1 - 2 sec delay, no dismiss. + */ + + $this->_last_response = ''; + // Key value from action_option array index. + $_POST['action_index'] = 1; + + try { + $this->_handleAjax( 'aioseop_notice' ); + } catch ( WPAjaxDieStopException $ex ) { + // We did not expected this, do nothing & check on assertion. + } catch ( WPAjaxDieContinueException $ex ) { + // We did not expected this, do nothing & check on assertion. + } + + $response = json_decode( $this->_last_response ); + $this->assertInternalType( 'object', $response ); + $this->assertObjectHasAttribute( 'success', $response ); + $this->assertTrue( $response->success ); + $this->assertObjectHasAttribute( 'data', $response ); + $this->assertEquals( 'Notice updated successfully.', $response->data ); + + // Check if notice is still active. + $this->assertArrayHasKey( $notice['slug'], $aioseop_notices->notices, 'AJAX Notice should still be added.' ); + $this->assertArrayHasKey( $notice['slug'], $aioseop_notices->active_notices, 'AJAX Notice should still be active.' ); + + // Check delay time. + $expected_time = $aioseop_notices->notices[ $notice['slug'] ]['time_set'] + $aioseop_notices->notices[ $notice['slug'] ]['action_options']['1']['time']; + // Add 1 to compensate for exact time display. + $actual_time = $aioseop_notices->active_notices[ $notice['slug'] ] + 1; + + $this->assertGreaterThanOrEqual( $expected_time, $actual_time, 'Expected: ' . $expected_time . ' Actual: ' . $actual_time ); + $this->assertLessThanOrEqual( ( $expected_time + 1 ), $actual_time, 'Expected: ' . $expected_time . ' Actual: ' . $actual_time ); + + /* + * Action_Options 2 - NA delay, dismiss. + */ + + $this->_last_response = ''; + // Key value from action_option array index. + $_POST['action_index'] = 2; + + try { + $this->_handleAjax( 'aioseop_notice' ); + } catch ( WPAjaxDieStopException $ex ) { + // We did not expected this, do nothing & check on assertion. + } catch ( WPAjaxDieContinueException $ex ) { + // We did not expected this, do nothing & check on assertion. + } + + $response = json_decode( $this->_last_response ); + $this->assertInternalType( 'object', $response ); + $this->assertObjectHasAttribute( 'success', $response ); + $this->assertTrue( $response->success ); + $this->assertObjectHasAttribute( 'data', $response ); + $this->assertEquals( 'Notice updated successfully.', $response->data ); + + // Check if notice is still active. + $this->assertArrayHasKey( $notice['slug'], $aioseop_notices->notices, 'AJAX Notice should still be added.' ); + $this->assertArrayNotHasKey( $notice['slug'], $aioseop_notices->active_notices, 'AJAX Notice should not be active still.' ); + // No delay time to check. + } + + /** + * Test Dismiss Sitewide for All Users + * + * Function: Dismisses the notice for all admins/aiosp_manage_seo. + * Expected: When dismissed, the notice should not display for the use dismissing and all other users. + * Actual: Currently works as expected. + * Reproduce: Dev create a notice without `target` being set. then navigate to wp-admin. Repeat with alternate user. + * + * @since 3.0 + */ + public function test_dismiss_sitewide_all_users() { + + global $aioseop_notices; + $notice = $this->mock_notice(); + $this->add_notice( $notice ); + + // Create the nonce in the POST superglobal. + $_POST['_wpnonce'] = wp_create_nonce( 'aioseop_ajax_notice' ); + $_POST['notice_slug'] = $notice['slug']; + $_POST['action_index'] = 2; // Within mock_notice, it's the action_option (index) that contains the dismissal. + + set_current_screen( 'dashboard' ); + $aioseop_notices->admin_enqueue_scripts(); + + ob_start(); + $aioseop_notices->display_notice_default(); + $buffer = ob_get_contents(); + ob_end_clean(); + + $this->assertNotEmpty( $buffer ); + + try { + $this->_handleAjax( 'aioseop_notice' ); + } catch ( WPAjaxDieStopException $ex ) { + // We did not expected this, do nothing & check on assertion. + } catch ( WPAjaxDieContinueException $ex ) { + // We did not expected this, do nothing & check on assertion. + } + + ob_start(); + $aioseop_notices->display_notice_default(); + $buffer = ob_get_contents(); + ob_end_clean(); + + $this->assertEmpty( $buffer ); + + // Switch user. + $user_id = $this->factory()->user->create( + array( + 'user_login' => 'user_ajax', + 'user_nicename' => 'userajax', + 'user_pass' => 'password', + 'first_name' => 'John', + 'last_name' => 'Doe', + 'display_name' => 'John Doe', + 'user_email' => 'placeholder@email.com', + 'user_url' => 'http://semperplugins.com', + 'role' => 'administrator', + 'nickname' => 'Johnny', + 'description' => 'I am a WordPress user.', + ) + ); + wp_set_current_user( $user_id ); + + ob_start(); + $aioseop_notices->display_notice_default(); + $buffer = ob_get_contents(); + ob_end_clean(); + + $this->assertEmpty( $buffer ); + } + + /** + * Test Dismiss Sitewide for All Users + * + * Function: Dismisses the notice for admin dismissing the notice, but other users the notice is able to display still. + * Expected: When dismissed, the notice should not display for the use dismissing but doesn't effect other users. + * Actual: Currently works as expected. + * Reproduce: Dev create a notice with `target` being set to `user`. then navigate to wp-admin. Repeat with alternate user. + * + * @since 3.0 + */ + public function test_dismiss_user_single_users() { + global $aioseop_notices; + $notice = $this->mock_notice_target_user(); + $this->add_notice( $notice ); + + // Create the nonce in the POST superglobal. + $_POST['_wpnonce'] = wp_create_nonce( 'aioseop_ajax_notice' ); + $_POST['notice_slug'] = $notice['slug']; + $_POST['action_index'] = 2; // Within mock_notice, it's the action_option (index) that contains the dismissal. + + set_current_screen( 'dashboard' ); + $aioseop_notices->admin_enqueue_scripts(); + + ob_start(); + $aioseop_notices->display_notice_default(); + $buffer = ob_get_contents(); + ob_end_clean(); + + $this->assertNotEmpty( $buffer ); + + try { + $this->_handleAjax( 'aioseop_notice' ); + } catch ( WPAjaxDieStopException $ex ) { + // We did not expected this, do nothing & check on assertion. + } catch ( WPAjaxDieContinueException $ex ) { + // We did not expected this, do nothing & check on assertion. + } + + ob_start(); + $aioseop_notices->display_notice_default(); + $buffer = ob_get_contents(); + ob_end_clean(); + + $this->assertEmpty( $buffer ); + + // Switch user. + $user_id = $this->factory()->user->create( + array( + 'user_login' => 'user_ajax', + 'user_nicename' => 'userajax', + 'user_pass' => 'password', + 'first_name' => 'John', + 'last_name' => 'Doe', + 'display_name' => 'John Doe', + 'user_email' => 'placeholder@email.com', + 'user_url' => 'http://semperplugins.com', + 'role' => 'administrator', + 'nickname' => 'Johnny', + 'description' => 'I am a WordPress user.', + ) + ); + wp_set_current_user( $user_id ); + + ob_start(); + $aioseop_notices->display_notice_default(); + $buffer = ob_get_contents(); + ob_end_clean(); + + $this->assertNotEmpty( $buffer ); + } +} diff --git a/tests/classes/aioseop-notices/test-delay-time.php b/tests/classes/aioseop-notices/test-delay-time.php new file mode 100644 index 000000000..e4e91b809 --- /dev/null +++ b/tests/classes/aioseop-notices/test-delay-time.php @@ -0,0 +1,128 @@ + 'notice_delay_delay_time', + 'delay_time' => 2, // 1 Hour. + 'message' => __( 'Admin Sample Message.', 'all-in-one-seo-pack' ), + 'action_options' => array( + array( + 'time' => 0, + 'text' => __( 'Link and close', 'all-in-one-seo-pack' ), + 'link' => 'https://wordpress.org/support/plugin/all-in-one-seo-pack', + 'dismiss' => false, + 'class' => '', + ), + array( + 'text' => 'Delay', + 'time' => 432000, + 'dismiss' => false, + 'class' => '', + ), + array( + 'time' => 0, + 'text' => 'Dismiss', + 'dismiss' => true, + 'class' => '', + ), + ), + 'target' => 'site', + 'screens' => array(), + ); + } + + /** + * Test Enqueue Scripts on Screens + * + * Override and skip. + * + * @since 3.0 + */ + public function test_enqueue_scripts_on_screens() { + $this->markTestSkipped('Skip'); + } + + /** + * Test Notice Delay Time + * + * Function: Displays Notice when the delayed time has been reached. + * Expected: Noticed doesn't render before the delay time, and when the delayed time is reach the notice will render. + * Actual: Currently works as expected. + * Reproduce: Have a notice inserted, and wait for X amount of time to pass. + * + * @since 3.0 + */ + public function test_notice_delay_time() { + global $aioseop_notices; + $this->add_notice(); + + set_current_screen( 'dashboard' ); + + ob_start(); + $aioseop_notices->display_notice_default(); + $buffer = ob_get_contents(); + ob_end_clean(); + $this->assertEmpty( $buffer ); + + sleep( 3 ); + + ob_start(); + $aioseop_notices->display_notice_default(); + $buffer = ob_get_contents(); + ob_end_clean(); + $this->assertNotEmpty( $buffer ); + } +} diff --git a/tests/classes/aioseop-notices/test-enqueue-scripts.php b/tests/classes/aioseop-notices/test-enqueue-scripts.php new file mode 100644 index 000000000..5eb0fd411 --- /dev/null +++ b/tests/classes/aioseop-notices/test-enqueue-scripts.php @@ -0,0 +1,111 @@ +validate_class_aioseop_notices( $aioseop_notices ); + + // Should be empty. + $this->assertTrue( empty( $aioseop_notices->active_notices ) ); + + $notice = $this->mock_notice(); + + // Insert Successful and activated. + $this->assertTrue( $aioseop_notices->insert_notice( $notice ) ); + $this->assertTrue( in_array( $notice['slug'], $notice, true ) ); + + $this->assertTrue( isset( $aioseop_notices->active_notices[ $notice['slug'] ] ) ); + $this->assertNotNull( $aioseop_notices->active_notices[ $notice['slug'] ] ); + + $this->validate_class_aioseop_notices( $aioseop_notices ); + + wp_deregister_script( 'aioseop-admin-notice-js' ); + wp_deregister_style( 'aioseop-admin-notice-css' ); + $this->assertFalse( wp_script_is( 'aioseop-admin-notice-js', 'registered' ), 'Screen: ' . $screen_id ); + + set_current_screen( $screen_id ); + $this->go_to( $url ); + + $aioseop_notices = new AIOSEOP_Notices(); + + set_current_screen( $screen_id ); + + $this->assertFalse( wp_script_is( 'aioseop-admin-notice-js', 'registered' ), 'Screen: ' . $screen_id ); + + do_action( 'admin_enqueue_scripts' ); + + $this->assertTrue( wp_script_is( 'aioseop-admin-notice-js', 'registered' ), 'Screen: ' . $screen_id ); + $this->assertTrue( wp_script_is( 'aioseop-admin-notice-js', 'enqueued' ) ); + } +} diff --git a/tests/classes/aioseop-notices/test-init.php b/tests/classes/aioseop-notices/test-init.php new file mode 100644 index 000000000..6ccdea021 --- /dev/null +++ b/tests/classes/aioseop-notices/test-init.php @@ -0,0 +1,260 @@ +clean_aioseop_notices(); + } + + /** + * PHPUnit Fixture - tearDown() + * + * @since 3.0 + * + * @link https://make.wordpress.org/core/handbook/testing/automated-testing/writing-phpunit-tests/#shared-setup-between-related-tests + */ + public function tearDown() { + $this->clean_aioseop_notices(); + + parent::tearDown(); + } + + /** + * Mock Single Notice + * + * @since 3.0 + * + * @return array + */ + protected function mock_notice() { + return array( + 'slug' => 'notice_slug_1', + 'delay_time' => 3600, // 1 Hour. + 'message' => __( 'Admin Sample Message.', 'all-in-one-seo-pack' ), + 'action_options' => array( + array( + 'time' => 0, + 'text' => __( 'Link and close', 'all-in-one-seo-pack' ), + 'link' => 'https://wordpress.org/support/plugin/all-in-one-seo-pack', + 'dismiss' => false, + 'class' => '', + ), + array( + 'text' => 'Delay', + 'time' => 432000, + 'dismiss' => false, + 'class' => '', + ), + array( + 'time' => 0, + 'text' => 'Dismiss', + 'dismiss' => true, + 'class' => '', + ), + ), + 'target' => 'user', + 'screens' => array(), + ); + } + + /** + * Test Enqueue Scripts on Screens + * + * Override and skip. + * + * @since 3.0 + */ + public function test_enqueue_scripts_on_screens() { + $this->markTestSkipped('Skip'); + } + + /** + * Test AIOSEOP_Notices' initial values. + * + * Statically called. + * + * Function: Contructs the object to be used with the server. + * Expected: The class should initialize and set it's internal variables. + * Actual: Currently, as expected. + * Reproduce: The class is loaded and initialized when the plugin is activated and loaded. + * + * TODO Rename: _static_new_* + * + * @since 3.0 + */ + public function test_static_construct() { + + global $aioseop_notices; + $this->assertNull( $aioseop_notices, 'The Global, \'$aioseop_options\', isn\' being cleaned upon setUp' ); + + $wp_options_aioseop_options = get_option( 'aioseop_notices' ); + $this->assertFalse( $wp_options_aioseop_options, 'The WP Options, \'aioseop_options\', isn\' being cleaned upon setUp' ); + + $aioseop_notices = new AIOSEOP_Notices(); + + $this->validate_class_aioseop_notices( $aioseop_notices ); + } + + /** + * Test Add Notice + * + * Function: Inserts, and Updates, a single notice into wp_options. + * Expected: If no notice exists, it shouldn't be operational, and new notices should insert instead of update. Then + * should be able to update without effecting the active notices. + * Actual: As expected; no current issue. + * Result: Inserts and Updates successfully to the database (wp_options). + * + * @since 3.0 + * + * @param array $notice Notice to test. + */ + public function test_add_notice( $notice = array() ) { + if ( empty( $notice ) ) { + $notice = $this->mock_notice(); + } + + global $aioseop_notices; + $this->assertNull( $aioseop_notices, 'The Global, \'$aioseop_options\', isn\' being cleaned upon setUp' ); + + $wp_options_aioseop_options = get_option( 'aioseop_notices' ); + $this->assertFalse( $wp_options_aioseop_options, 'The WP Options, \'aioseop_options\', isn\' being cleaned upon setUp' ); + + $aioseop_notices = new AIOSEOP_Notices(); + + parent::test_add_notice( $notice ); + + $this->validate_attr_notices( $aioseop_notices->notices ); + } +} + +/** + * ADDITIONAL DEV NOTES + * + * Objectives & Notes with target concepts/senarios. Possible for future use. + * + * Legend. + * * = Completed + */ + +/* + * SETUP + * + * *The object's wp_options will need to be deleted to force a full reset. + */ + +/* + * OBJECT OPTIONS TO DATABASE + * + * *Test get_options are set as default, and if the saved options are the expected output. + * + * Test Filter Hooks firing when they should. Both Admin_Init and Current_Screen. + * + * *Test for basic notice save. + */ + +/* + * NOTICE OPTIONS/DATABASE - _Notice_TestCase::add_notice() does most of this. + * + * *Test for default notice, and default actions + * + * *Test Insert_Notice. True on new notice, and false (no modifications) if already exists. Test it is rendered. + * + * *Test Update_Notice. True on old notice, and false if it doesn't exist. Test it doesn't reset a dismissed notice. + * + * Test Remove_Notice. True on success, and doesn't render. False on failure, and should not render assumed notice or change any others. + * + * *Test Activate_notice. + */ + +/* + * SCRIPTS AND STYLES. + * + * *Test for enqueued scripts and styles with multiple admin screens. + * + * Test for Display Notice returning false when there is no JS to fire AJAX; which is required. + * + * *Test if scripts have been deregistered. Both statically and on page expected to have no script. + */ + +/* + * NOTICE RENDERING - GENERAL OPERATIONS + * + * Test the differentiation between sitewide and user. + * - Sitewide: displays to admin group, and only needs 1 admin to dismiss/delay. + * - TODO Could have a buffer incase someone else dismisses when the webmaster delays, or vice-versa. + * TODO OR Could have it as the first come first serve. + * - Users: displays individually set to admins, and is dismissed/delayed seperately. + * + * *Test for notice delayed/timed rendering. Will need to Mock Time/Date. + * + * *Test for notice delay/dismiss, and rendering at a later time. ( Simular to Enqueue test, but will do the opposite ). + * + * *Test for notice activation + * + * Test DISABLE_NAG_NOTICES when set to true. + */ + +/* + * NOTICE AJAX DISMISS/DELAY + * + * *Test the response from the server. + * + * Test the response from server on failure. + * *1. Controlled/expected fail. + * 2. Unexpected PHP error. + * *3. Security threat with invalid/null wp_nonce value. + */ + +/* + * NOTICE USER PERMISSIONS & RESTRICTIONS + * + * Test rendering for target user-roles. + * + * Test not rendering for non-target user-roles. + */ + + + + +/* + * EACH NOTICE FUNCTION + * + * Test seperately firing the notice with the plugin conditions, and manual use of the notice function. + * + * Test that it is rendered, and if delayed, test delay then render. + * + * Test delay and/or dismiss works as intended. + * + * Test User perms & restrictions. + */ diff --git a/tests/classes/aioseop-notices/test-user.php b/tests/classes/aioseop-notices/test-user.php new file mode 100644 index 000000000..ff4d353ed --- /dev/null +++ b/tests/classes/aioseop-notices/test-user.php @@ -0,0 +1,210 @@ + 'notice_slug_user', + 'delay_time' => 0, // 1 Hour. + 'message' => __( 'Admin Sample Message.', 'all-in-one-seo-pack' ), + 'action_options' => array( + array( + 'time' => 0, + 'text' => __( 'Link and close', 'all-in-one-seo-pack' ), + 'link' => 'https://wordpress.org/support/plugin/all-in-one-seo-pack', + 'dismiss' => false, + 'class' => '', + ), + array( + 'text' => 'Delay', + 'time' => 432000, + 'dismiss' => false, + 'class' => '', + ), + array( + 'time' => 0, + 'text' => 'Dismiss', + 'dismiss' => true, + 'class' => '', + ), + ), + 'target' => 'user', + 'screens' => array(), + ); + } + + /** + * Test Enqueue Scripts on Screens + * + * Override and skip. + * + * @since 3.0 + */ + public function test_enqueue_scripts_on_screens() { + $this->markTestSkipped('Skip'); + } + + /** + * Test for notices showing to only admins, or manage aioseop perms. + * + * @since 3.0 + * + * @dataProvider data_user_roles + */ + public function test_notice_admin_perms( $role, $expect_display ) { + global $aioseop_notices_test; + $this->add_notice(); + + $user_id = $this->factory()->user->create( + array( + 'user_login' => 'user_' . $role, + 'user_nicename' => 'user' . $role, + 'user_pass' => 'password', + 'first_name' => 'John', + 'last_name' => 'Doe', + 'display_name' => 'John Doe', + 'user_email' => 'placeholder@email.com', + 'user_url' => 'http://semperplugins.com', + 'role' => $role, + 'nickname' => 'Johnny', + 'description' => 'I am a WordPress user.', + ) + ); + + wp_set_current_user( $user_id ); + set_current_screen( 'dashboard' ); + + // Test User Perms. + $user_can = current_user_can( 'aiosp_manage_seo' ); + if ( $expect_display ) { + $this->assertTrue( $user_can ); + } else { + $this->assertFalse( $user_can ); + } + + // After construction, check hooks added only for users with `aiosp_manage_seo`. + $aioseop_notices_test = new AIOSEOP_Notices(); + + if ( $expect_display ) { + $this->assertTrue( has_action( 'admin_init', array( $aioseop_notices_test, 'init' ) ) ? true : false ); + $this->assertTrue( has_action( 'current_screen', array( $aioseop_notices_test, 'admin_screen' ) ) ? true : false ); + } else { + $this->assertFalse( has_action( 'admin_init', array( $aioseop_notices_test, 'init' ) ) ? true : false ); + $this->assertFalse( has_action( 'current_screen', array( $aioseop_notices_test, 'admin_screen' ) ) ? true : false ); + } + + // After `current_screen` action hook, check for hooks added. + set_current_screen( 'dashboard' ); + + if ( $expect_display ) { + $this->assertTrue( has_action( 'admin_enqueue_scripts', array( $aioseop_notices_test, 'admin_enqueue_scripts' ) ) ? true : false ); + $this->assertTrue( has_action( 'all_admin_notices', array( $aioseop_notices_test, 'display_notice_default' ) ) ? true : false ); + } else { + $this->assertFalse( has_action( 'admin_enqueue_scripts', array( $aioseop_notices_test, 'admin_enqueue_scripts' ) ) ? true : false ); + $this->assertFalse( has_action( 'all_admin_notices', array( $aioseop_notices_test, 'display_notice_default' ) ) ? true : false ); + } + + ob_start(); + $aioseop_notices_test->display_notice_default(); + $buffer = ob_get_contents(); + ob_end_clean(); + + if ( $expect_display ) { + $this->assertNotEmpty( $buffer ); + } else { + $this->assertEmpty( $buffer ); + } + } + + /** + * Data User Roles + * + * @since 3.0 + * + * @return array + */ + public function data_user_roles() { + return array( + array( + 'role' => 'administrator', + 'expect_display' => true, + ), + array( + 'role' => 'editor', + 'expect_display' => false, + ), + array( + 'role' => 'author', + 'expect_display' => false, + ), + array( + 'role' => 'contributor', + 'expect_display' => false, + ), + array( + 'role' => 'subscriber', + 'expect_display' => false, + ), + ); + } + +} From 0fc500615fc4477badc2e3bca922bddecf85af9e Mon Sep 17 00:00:00 2001 From: EkoJR Date: Wed, 6 Mar 2019 06:34:11 -0800 Subject: [PATCH 006/121] Change Help Text Dropdown to Tooltips (#2236) * Change Help Text Dropdown to Tooltips * Dev-Fix duplicate links webmaster settings tooltips * Dev-Add missing help tooltip * Dev-Change cursor to point on help icon * Dev-Change Cursor style * Dev-Change review edits * Dev-Remove phpcs:disable * Run Grunt --- admin/aioseop_module_class.php | 111 +-- admin/class-aioseop-helper.php | 1134 +++++++++++++++++++++++++ aioseop_class.php | 314 ------- css/modules/aioseop_module.css | 3 +- js/aioseop-helper.js | 56 ++ js/aioseop-helper.min.js | 1 + modules/aioseop_bad_robots.php | 16 - modules/aioseop_file_editor.php | 8 - modules/aioseop_importer_exporter.php | 19 - modules/aioseop_opengraph.php | 102 --- modules/aioseop_performance.php | 14 - modules/aioseop_robots.php | 12 - modules/aioseop_sitemap.php | 52 -- 13 files changed, 1239 insertions(+), 603 deletions(-) create mode 100644 admin/class-aioseop-helper.php create mode 100644 js/aioseop-helper.js create mode 100644 js/aioseop-helper.min.js diff --git a/admin/aioseop_module_class.php b/admin/aioseop_module_class.php index ff7109fb6..c98df8bbf 100644 --- a/admin/aioseop_module_class.php +++ b/admin/aioseop_module_class.php @@ -1657,58 +1657,6 @@ function get_the_image_by_scan( $p = null ) { return false; } - - /** - * @param $default_options - * @param $options - * @param string $help_link - */ - function help_text_helper( &$default_options, $options, $help_link = '' ) { - foreach ( $options as $o ) { - $ht = ''; - if ( ! empty( $this->help_text[ $o ] ) ) { - $ht = $this->help_text[ $o ]; - } elseif ( ! empty( $default_options[ $o ]['help_text'] ) ) { - $ht = $default_options[ $o ]['help_text']; - } - if ( $ht && ! is_array( $ht ) ) { - $ha = ''; - $hl = $help_link; - if ( strpos( $o, 'ga_' ) === 0 ) { // special case -- pdb - $hl = 'https://semperplugins.com/documentation/advanced-google-analytics-settings/'; - } - if ( ! empty( $this->help_anchors[ $o ] ) ) { - $ha = $this->help_anchors[ $o ]; - } - if ( ! empty( $ha ) && ( $pos = strrpos( $hl, '#' ) ) ) { - $hl = substr( $hl, 0, $pos ); - } - if ( ! empty( $ha ) && ( $ha[0] == 'h' ) ) { - $hl = ''; - } - if ( ! empty( $ha ) || ! isset( $this->help_anchors[ $o ] ) ) { - $ht .= "
" . __( 'Click here for documentation on this setting', 'all-in-one-seo-pack' ) . ''; - } - $default_options[ $o ]['help_text'] = $ht; - } - } - } - - function add_help_text_links() { - if ( ! empty( $this->help_text ) ) { - foreach ( $this->layout as $k => $v ) { - $this->help_text_helper( $this->default_options, $v['options'], $v['help_link'] ); - } - if ( ! empty( $this->locations ) ) { - foreach ( $this->locations as $k => $v ) { - if ( ! empty( $v['default_options'] ) && ! empty( $v['options'] ) ) { - $this->help_text_helper( $this->locations[ $k ]['default_options'], $v['options'], $v['help_link'] ); - } - } - } - } - } - /** * Load scripts and styles for metaboxes. * edit-tags exists only for pre 4.5 support... remove when we drop 4.5 support. @@ -1770,9 +1718,12 @@ function enqueue_metabox_scripts() { * Add hook in \All_in_One_SEO_Pack_Module::add_page_hooks - Function itself is hooked based on the screen_id/page. * * @since 2.9 + * @since 3.0 Added jQuery UI CSS missing from WP. #1850 * * @see 'admin_enqueue_scripts' hook * @link https://developer.wordpress.org/reference/hooks/admin_enqueue_scripts/ + * @uses wp_scripts() Gets the Instance of WP Scripts. + * @link https://developer.wordpress.org/reference/functions/wp_scripts/ * * @param string $hook_suffix */ @@ -1785,6 +1736,16 @@ function admin_enqueue_styles( $hook_suffix ) { if ( function_exists( 'is_rtl' ) && is_rtl() ) { wp_enqueue_style( 'aioseop-module-style-rtl', AIOSEOP_PLUGIN_URL . 'css/modules/aioseop_module-rtl.css', array( 'aioseop-module-style' ), AIOSEOP_VERSION ); } + + // Uses WP Scripts to load the current platform version of jQuery UI CSS . + $wp_scripts = wp_scripts(); + wp_enqueue_style( + 'aioseop-jquery-ui-css', + 'https://ajax.googleapis.com/ajax/libs/jqueryui/' . $wp_scripts->registered['jquery-ui-core']->ver . '/themes/smoothness/jquery-ui.min.css', + false, + AIOSEOP_VERSION, + false + ); } /** @@ -1798,6 +1759,7 @@ function admin_enqueue_styles( $hook_suffix ) { * @since ? * @since 2.3.12.3 Add missing wp_enqueue_media. * @since 2.9 Switch to admin_enqueue_scripts; both the hook and function name. + * @since 3.0 Add enqueue footer JS for jQuery UI Compatability. #1850 * * @see 'admin_enqueue_scripts' hook * @link https://developer.wordpress.org/reference/hooks/admin_enqueue_scripts/ @@ -1829,6 +1791,14 @@ public function admin_enqueue_scripts( $hook_suffix ) { wp_enqueue_media(); } + $helper_dep = array( + 'jquery', + 'jquery-ui-core', + 'jquery-ui-widget', + 'jquery-ui-position', + 'jquery-ui-tooltip', + ); + // AIOSEOP Script enqueue. wp_enqueue_script( 'aioseop-module-script', @@ -1836,6 +1806,13 @@ public function admin_enqueue_scripts( $hook_suffix ) { array(), AIOSEOP_VERSION ); + wp_enqueue_script( + 'aioseop-helper-js', + AIOSEOP_PLUGIN_URL . 'js/aioseop-helper.js', + $helper_dep, + AIOSEOP_VERSION, + true + ); // Localize aiosp_data in JS. if ( ! empty( $this->script_data ) ) { @@ -2398,15 +2375,12 @@ function get_option_html( $args ) { return $buf; } - const DISPLAY_HELP_START = ''; - const DISPLAY_HELP_END = ''; - const DISPLAY_LABEL_FORMAT = '%s'; - const DISPLAY_TOP_LABEL = "\n
\n"; - const DISPLAY_ROW_TEMPLATE = '
%s
%s
%s

'; - /** * Format a row for an option on a settings page. * + * @since ? + * @since 3.0 Added Helper Class for jQuery Tooltips. #1850 + * * @param $name * @param $opts * @param $args @@ -2414,7 +2388,10 @@ function get_option_html( $args ) { * @return string */ function get_option_row( $name, $opts, $args ) { - $label_text = $input_attr = $help_text_2 = $id_attr = ''; + $label_text = $input_attr = $id_attr = ''; + + require_once( AIOSEOP_PLUGIN_DIR . 'admin/class-aioseop-helper.php' ); + $info = new AIOSEOP_Helper( get_class( $this ) ); $align = 'right'; if ( $opts['label'] == 'top' ) { @@ -2424,22 +2401,26 @@ function get_option_row( $name, $opts, $args ) { $id_attr .= " id=\"{$opts['id']}_div\" "; } if ( $opts['label'] != 'none' ) { - if ( isset( $opts['help_text'] ) ) { - $help_text = sprintf( All_in_One_SEO_Pack_Module::DISPLAY_HELP_START, __( 'Click for Help!', 'all-in-one-seo-pack' ), $name, $opts['name'] ); - $help_text_2 = sprintf( All_in_One_SEO_Pack_Module::DISPLAY_HELP_END, $name, $opts['help_text'] ); + $tmp_help_text = $info->get_help_text( $name ); + if ( isset( $tmp_help_text ) && ! empty( $tmp_help_text ) ) { + $display_help = ''; + $help_text = sprintf( $display_help, $info->get_help_text( $name ), $opts['name'] ); } else { $help_text = $opts['name']; } - $label_text = sprintf( All_in_One_SEO_Pack_Module::DISPLAY_LABEL_FORMAT, $align, $help_text ); + + $display_label_format = '%s'; + $label_text = sprintf( $display_label_format, $align, $help_text ); } else { $input_attr .= ' aioseop_no_label '; } if ( $opts['label'] == 'top' ) { - $label_text .= All_in_One_SEO_Pack_Module::DISPLAY_TOP_LABEL; + $label_text .= "
"; } $input_attr .= " aioseop_{$opts['type']}_type"; - return sprintf( All_in_One_SEO_Pack_Module::DISPLAY_ROW_TEMPLATE, $input_attr, $name, $label_text, $id_attr, $this->get_option_html( $args ), $help_text_2 ); + $display_row_template = '
%s
%s

'; + return sprintf( $display_row_template, $input_attr, $name, $label_text, $id_attr, $this->get_option_html( $args ) ); } /** diff --git a/admin/class-aioseop-helper.php b/admin/class-aioseop-helper.php new file mode 100644 index 000000000..d349dfbf5 --- /dev/null +++ b/admin/class-aioseop-helper.php @@ -0,0 +1,1134 @@ +_set_help_text( $module ); + } + } + + /** + * Set this Help Text + * + * Sets the Help Text according to the module/class in use, but if there is + * no class name in $module, then this Help Text will add all module help texts. + * + * @ignore + * @since 2.4.2 + * @access private + * + * @param string $module All_in_One_SEO_Pack module. + */ + private function _set_help_text( $module ) { + + switch ( $module ) { + case 'All_in_One_SEO_Pack': + $this->help_text = $this->help_text_general(); + $this->help_text = array_merge( $this->help_text, $this->help_text_post_meta() ); + break; + case 'All_in_One_SEO_Pack_Performance': + $this->help_text = $this->help_text_performance(); + break; + case 'All_in_One_SEO_Pack_Sitemap': + $this->help_text = $this->help_text_sitemap(); + break; + case 'All_in_One_SEO_Pack_Opengraph': + $this->help_text = $this->help_text_opengraph(); + break; + case 'All_in_One_SEO_Pack_Robots': + $this->help_text = $this->help_text_robots_generator(); + break; + case 'All_in_One_SEO_Pack_File_Editor': + $this->help_text = $this->help_text_file_editor(); + break; + case 'All_in_One_SEO_Pack_Importer_Exporter': + $this->help_text = $this->help_text_importer_exporter(); + break; + case 'All_in_One_SEO_Pack_Bad_Robots': + $this->help_text = $this->help_text_bad_robots(); + break; + default: + $this->help_text = array_merge( + $this->help_text, + $this->help_text_general(), + $this->help_text_performance(), + $this->help_text_sitemap(), + $this->help_text_opengraph(), + $this->help_text_robots_generator(), + $this->help_text_file_editor(), + $this->help_text_importer_exporter(), + $this->help_text_bad_robots(), + $this->help_text_post_meta() + ); + break; + } + + if ( AIOSEOPPRO ) { + $help_text = aioseop_add_pro_help( $this->help_text ); + + // TODO - Get Prefix from PRO Version. + foreach ( $help_text as $key => $text ) { + $this->help_text[ $key ] = $text; + } + } + + } + + /** + * Help Text General Settings + * + * @ignore + * @since 2.4.2 + * @access private + * + * @return array + */ + private function help_text_general() { + /* + * Consider changing the construction of the macros. + * + * The name of the macro should NOT be inside _e() or __() because it does not make sense as it + * won't change with the language. + * + * Moreover, it will confuse WPCS and it will try to replace %c (as in %category%) to %$1c. + * Placeholder %s (%something) has been bug fixed. + * @link https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/issues/698 + */ + // phpcs:disable WordPress.WP.I18n.MissingTranslatorsComment + // phpcs:disable WordPress.WP.I18n.UnorderedPlaceholdersText + $rtn_help_text = array( + // General Settings. + 'aiosp_can' => __( 'This option will automatically generate Canonical URLs for your entire WordPress installation. This will help to prevent duplicate content penalties by Google', 'all-in-one-seo-pack' ), + 'aiosp_no_paged_canonical_links' => __( 'Checking this option will set the Canonical URL for all paginated content to the first page.', 'all-in-one-seo-pack' ), + 'aiosp_customize_canonical_links' => __( 'Checking this option will allow you to customize Canonical URLs for specific posts.', 'all-in-one-seo-pack' ), + 'aiosp_use_original_title' => __( 'Use wp_title to get the title used by the theme; this is disabled by default. If you use this option, set your title formats appropriately, as your theme might try to do its own title SEO as well.', 'all-in-one-seo-pack' ), + 'aiosp_schema_markup' => __( 'Check this to support Schema.org markup, i.e., itemprop on supported metadata.', 'all-in-one-seo-pack' ), + 'aiosp_do_log' => __( 'Check this and All in One SEO Pack will create a log of important events (all-in-one-seo-pack.log) in its plugin directory which might help debugging. Make sure this directory is writable.', 'all-in-one-seo-pack' ), + + // Home Page Settings. + 'aiosp_home_title' => __( 'As the name implies, this will be the Meta Title of your homepage. This is independent of any other option. If not set, the default Site Title (found in WordPress under Settings, General, Site Title) will be used.', 'all-in-one-seo-pack' ), + 'aiosp_home_description' => __( 'This will be the Meta Description for your homepage. This is independent of any other option. The default is no Meta Description at all if this is not set.', 'all-in-one-seo-pack' ), + 'aiosp_home_keywords' => __( 'Enter a comma separated list of your most important keywords for your site that will be written as Meta Keywords on your homepage. Do not stuff everything in here.', 'all-in-one-seo-pack' ), + 'aiosp_use_static_home_info' => __( 'Checking this option uses the title, description, and keywords set on your static Front Page.', 'all-in-one-seo-pack' ), + + // Title Settings. + 'aiosp_rewrite_titles' => __( "Note that this is all about the title tag. This is what you see in your browser's window title bar. This is NOT visible on a page, only in the title bar and in the source code. If enabled, all page, post, category, search and archive page titles get rewritten. You can specify the format for most of them. For example: Using the default post title format below, Rewrite Titles will write all post titles as 'Post Title | Blog Name'. If you have manually defined a title using All in One SEO Pack, this will become the title of your post in the format string.", 'all-in-one-seo-pack' ), + 'aiosp_home_page_title_format' => + __( 'This controls the format of the title tag for your Home Page.', 'all-in-one-seo-pack' ) . '
' . + __( 'The following macros are supported:', 'all-in-one-seo-pack' ) . + '
    ' . + '
  • ' . + __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%page_title% - The original title of the page', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( "%page_author_login% - This page's author' login", 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( "%page_author_nicename% - This page's author' nicename", 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( "%page_author_firstname% - This page's author' first name (capitalized)", 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( "%page_author_lastname% - This page's author' last name (capitalized)", 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%current_date% - The current date (localized)', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%cf_fieldname% - Custom field name', 'all-in-one-seo-pack' ) . + '
  • ' . + '
', + 'aiosp_page_title_format' => + __( 'This controls the format of the title tag for Pages.', 'all-in-one-seo-pack' ) . '
' . + __( 'The following macros are supported:', 'all-in-one-seo-pack' ) . + '
    ' . + '
  • ' . + __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%page_title% - The original title of the page', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( "%page_author_login% - This page's author' login", 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( "%page_author_nicename% - This page's author' nicename", 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( "%page_author_firstname% - This page's author' first name (capitalized)", 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( "%page_author_lastname% - This page's author' last name (capitalized)", 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%current_date% - The current date (localized)', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%post_date% - The date the page was published (localized)', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%post_year% - The year the page was published (localized)', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%post_month% - The month the page was published (localized)', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%cf_fieldname% - Custom field name', 'all-in-one-seo-pack' ) . + '
  • ' . + '
', + 'aiosp_post_title_format' => + __( 'This controls the format of the title tag for Posts.', 'all-in-one-seo-pack' ) . '
' . + __( 'The following macros are supported:', 'all-in-one-seo-pack' ) . + '
    ' . + '
  • ' . + __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%post_title% - The original title of the post', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%category_title% - The (main) category of the post', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%category% - Alias for %category_title%', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( "%post_author_login% - This post's author' login", 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( "%post_author_nicename% - This post's author' nicename", 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( "%post_author_firstname% - This post's author' first name (capitalized)", 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( "%post_author_lastname% - This post's author' last name (capitalized)", 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%current_date% - The current date (localized)', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%post_date% - The date the post was published (localized)', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%post_year% - The year the post was published (localized)', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%post_month% - The month the post was published (localized)', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%cf_fieldname% - Custom field name', 'all-in-one-seo-pack' ) . + '
  • ' . + '
', + 'aiosp_category_title_format' => + __( 'This controls the format of the title tag for Category Archives.', 'all-in-one-seo-pack' ) . '
' . + __( 'The following macros are supported:', 'all-in-one-seo-pack' ) . + '
    ' . + '
  • ' . + __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%category_title% - The original title of the category', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%category_description% - The description of the category', 'all-in-one-seo-pack' ) . + '
  • ' . + '
', + 'aiosp_archive_title_format' => + __( 'This controls the format of the title tag for Custom Post Archives.', 'all-in-one-seo-pack' ) . '
' . + __( 'The following macros are supported:', 'all-in-one-seo-pack' ) . + '
    ' . + '
  • ' . + __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%archive_title - The original archive title given by wordpress', 'all-in-one-seo-pack' ) . + '
  • ' . + '
', + 'aiosp_date_title_format' => + __( 'This controls the format of the title tag for Date Archives.', 'all-in-one-seo-pack' ) . '
' . + __( 'The following macros are supported:', 'all-in-one-seo-pack' ) . + '
    ' . + '
  • ' . + __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%date% - The original archive title given by wordpress, e.g. "2007" or "2007 August"', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%day% - The original archive day given by wordpress, e.g. "17"', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%month% - The original archive month given by wordpress, e.g. "August"', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%year% - The original archive year given by wordpress, e.g. "2007"', 'all-in-one-seo-pack' ) . + '
  • ' . + '
', + 'aiosp_author_title_format' => + __( 'This controls the format of the title tag for Author Archives.', 'all-in-one-seo-pack' ) . '
' . + __( 'The following macros are supported:', 'all-in-one-seo-pack' ) . + '
    ' . + '
  • ' . + __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%author% - The original archive title given by wordpress, e.g. "Steve" or "John Smith"', 'all-in-one-seo-pack' ) . + '
  • ' . + '
', + 'aiosp_tag_title_format' => + __( 'This controls the format of the title tag for Tag Archives.', 'all-in-one-seo-pack' ) . '
' . + __( 'The following macros are supported:', 'all-in-one-seo-pack' ) . + '
    ' . + '
  • ' . + __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%tag% - The name of the tag', 'all-in-one-seo-pack' ) . + '
  • ' . + '
', + 'aiosp_search_title_format' => + __( 'This controls the format of the title tag for the Search page.', 'all-in-one-seo-pack' ) . '
' . + __( 'The following macros are supported:', 'all-in-one-seo-pack' ) . + '
    ' . + '
  • ' . + __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%search% - What was searched for', 'all-in-one-seo-pack' ) . + '
  • ' . + '
', + 'aiosp_description_format' => + __( 'This controls the format of Meta Descriptions.The following macros are supported:', 'all-in-one-seo-pack' ) . + '
    ' . + '
  • ' . + __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%description% - This outputs the description you write for each page/post or the autogenerated description, if you have that option enabled. Auto-generated descriptions are generated from the Post Excerpt, or the first 160 characters of the post content if there is no Post Excerpt.', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%post_title% - The original title of the post', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%wp_title% - The original WordPress title, e.g. post_title for posts', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%current_date% - The current date (localized)', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%post_date% - The date the page/post was published (localized)', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%post_year% - The year the page/post was published (localized)', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%post_month% - The month the page/post was published (localized)', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%cf_fieldname% - Custom field name', 'all-in-one-seo-pack' ) . + '
  • ' . + '
', + 'aiosp_404_title_format' => + __( 'This controls the format of the title tag for the 404 page.', 'all-in-one-seo-pack' ) . '
' . + __( 'The following macros are supported:', 'all-in-one-seo-pack' ) . + '
    ' . + '
  • ' . + __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%request_url% - The original URL path, like "/url-that-does-not-exist/"', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%request_words% - The URL path in human readable form, like "Url That Does Not Exist"', 'all-in-one-seo-pack' ) . + '
  • ' . + '
  • ' . + __( '%404_title% - Additional 404 title input', 'all-in-one-seo-pack' ) . + '
  • ' . + '
', + 'aiosp_paged_format' => + __( 'This string gets appended/prepended to titles of paged index pages (like home or archive pages).', 'all-in-one-seo-pack' ) . + __( 'The following macros are supported:', 'all-in-one-seo-pack' ) . + '
    ' . + '
  • ' . + __( '%page% - The page number', 'all-in-one-seo-pack' ) . + '
  • ' . + '
', + //phpcs:enable + + // Custom Post Type Settings. + 'aiosp_cpostactive' => __( 'Use these checkboxes to select which Content Types you want to use All in One SEO Pack with.', 'all-in-one-seo-pack' ), + + // Display Settings. + 'aiosp_posttypecolumns' => __( 'This lets you select which screens display the SEO Title, SEO Keywords and SEO Description columns.', 'all-in-one-seo-pack' ), + + // Webmaster Verification. + 'aiosp_google_verify' => __( 'Enter your verification code here to verify your site with Google Search Console.', 'all-in-one-seo-pack' ), + 'aiosp_bing_verify' => __( 'Enter your verification code here to verify your site with Bing Webmaster Tools.', 'all-in-one-seo-pack' ), + 'aiosp_pinterest_verify' => __( 'Enter your verification code here to verify your site with Pinterest.', 'all-in-one-seo-pack' ), + + // Google Settings. + 'aiosp_google_publisher' => __( 'Enter your Google+ Profile URL here to add the rel=“author” tag to your site for Google authorship. It is recommended that the URL you enter here should be your personal Google+ profile. Use the Advanced Authorship Options below if you want greater control over the use of authorship.', 'all-in-one-seo-pack' ), + 'aiosp_google_disable_profile' => __( 'Check this to remove the Google Plus field from the user profile screen.', 'all-in-one-seo-pack' ), + 'aiosp_google_sitelinks_search' => __( 'Add markup to display the Google Sitelinks Search Box next to your search results in Google.', 'all-in-one-seo-pack' ), + 'aiosp_google_set_site_name' => __( 'Add markup to tell Google the preferred name for your website.', 'all-in-one-seo-pack' ), + 'aiosp_google_specify_site_name' => __( 'Enter your site name.', 'all-in-one-seo-pack' ), + 'aiosp_google_author_advanced' => __( 'Enable this to display advanced options for controlling Google Plus authorship information on your website.', 'all-in-one-seo-pack' ), + 'aiosp_google_author_location' => __( 'This option allows you to control which types of pages you want to display rel=\"author\" on for Google authorship. The options include the Front Page (the homepage of your site), Posts, Pages, and any Custom Post Types. The Everywhere Else option includes 404, search, categories, tags, custom taxonomies, date archives, author archives and any other page template.', 'all-in-one-seo-pack' ), + 'aiosp_google_enable_publisher' => __( 'This option allows you to control whether rel=\"publisher\" is displayed on the homepage of your site. Google recommends using this if the site is a business website.', 'all-in-one-seo-pack' ), + 'aiosp_google_specify_publisher' => __( 'The Google+ profile you enter here will appear on your homepage only as the rel=\"publisher\" tag. It is recommended that the URL you enter here should be the Google+ profile for your business.', 'all-in-one-seo-pack' ), + 'aiosp_google_analytics_id' => __( 'Enter your Google Analytics ID here to track visitor behavior on your site using Google Analytics.', 'all-in-one-seo-pack' ), + 'aiosp_ga_advanced_options' => __( 'Check to use advanced Google Analytics options.', 'all-in-one-seo-pack' ), + 'aiosp_ga_domain' => __( 'Enter your domain name without the http:// to set your cookie domain.', 'all-in-one-seo-pack' ), + 'aiosp_ga_multi_domain' => __( 'Use this option to enable tracking of multiple or additional domains.', 'all-in-one-seo-pack' ), + 'aiosp_ga_addl_domains' => __( 'Add a list of additional domains to track here. Enter one domain name per line without the http://.', 'all-in-one-seo-pack' ), + 'aiosp_ga_anonymize_ip' => __( 'This enables support for IP Anonymization in Google Analytics.', 'all-in-one-seo-pack' ), + 'aiosp_ga_display_advertising' => __( 'This enables support for the Display Advertiser Features in Google Analytics.', 'all-in-one-seo-pack' ), + 'aiosp_ga_exclude_users' => __( 'Exclude logged-in users from Google Analytics tracking by role.', 'all-in-one-seo-pack' ), + 'aiosp_ga_track_outbound_links' => __( 'Check this if you want to track outbound links with Google Analytics.', 'all-in-one-seo-pack' ), + 'aiosp_ga_link_attribution' => __( 'This enables support for the Enhanced Link Attribution in Google Analytics.', 'all-in-one-seo-pack' ), + 'aiosp_ga_enhanced_ecommerce' => __( 'This enables support for the Enhanced Ecommerce in Google Analytics.', 'all-in-one-seo-pack' ), + + // Noindex Settings. + 'aiosp_cpostnoindex' => __( 'Set the default NOINDEX setting for each Post Type.', 'all-in-one-seo-pack' ), + 'aiosp_cpostnofollow' => __( 'Set the default NOFOLLOW setting for each Post Type.', 'all-in-one-seo-pack' ), + 'aiosp_category_noindex' => __( 'Check this to ask search engines not to index Category Archives. Useful for avoiding duplicate content.', 'all-in-one-seo-pack' ), + 'aiosp_archive_date_noindex' => __( 'Check this to ask search engines not to index Date Archives. Useful for avoiding duplicate content.', 'all-in-one-seo-pack' ), + 'aiosp_archive_author_noindex' => __( 'Check this to ask search engines not to index Author Archives. Useful for avoiding duplicate content.', 'all-in-one-seo-pack' ), + 'aiosp_tags_noindex' => __( 'Check this to ask search engines not to index Tag Archives. Useful for avoiding duplicate content.', 'all-in-one-seo-pack' ), + 'aiosp_search_noindex' => __( 'Check this to ask search engines not to index the Search page. Useful for avoiding duplicate content.', 'all-in-one-seo-pack' ), + 'aiosp_404_noindex' => __( 'Check this to ask search engines not to index the 404 page.', 'all-in-one-seo-pack' ), + 'aiosp_paginated_noindex' => __( 'Check this to ask search engines not to index paginated pages/posts. Useful for avoiding duplicate content.', 'all-in-one-seo-pack' ), + 'aiosp_paginated_nofollow' => __( 'Check this to ask search engines not to follow links from paginated pages/posts. Useful for avoiding duplicate content.', 'all-in-one-seo-pack' ), + 'aiosp_tax_noindex' => __( 'Check this to ask search engines not to index custom Taxonomy archive pages. Useful for avoiding duplicate content.', 'all-in-one-seo-pack' ), + + // Advanced Settings. + 'aiosp_generate_descriptions' => __( 'Check this and your Meta Descriptions for any Post Type will be auto-generated using the Post Excerpt, or the first 160 characters of the post content if there is no Post Excerpt. You can overwrite any auto-generated Meta Description by editing the post or page.', 'all-in-one-seo-pack' ), + 'aiosp_skip_excerpt' => __( 'This option will auto generate your meta descriptions from your post content instead of your post excerpt. This is useful if you want to use your content for your autogenerated meta descriptions instead of the excerpt. WooCommerce users should read the documentation regarding this setting.', 'all-in-one-seo-pack' ), + 'aiosp_run_shortcodes' => __( 'Check this and shortcodes will get executed for descriptions auto-generated from content.', 'all-in-one-seo-pack' ), + 'aiosp_hide_paginated_descriptions' => __( 'Check this and your Meta Descriptions will be removed from page 2 or later of paginated content.', 'all-in-one-seo-pack' ), + 'aiosp_dont_truncate_descriptions' => __( 'Check this to prevent your Description from being truncated regardless of its length.', 'all-in-one-seo-pack' ), + 'aiosp_unprotect_meta' => __( "Check this to unprotect internal postmeta fields for use with XMLRPC. If you don't know what that is, leave it unchecked.", 'all-in-one-seo-pack' ), + 'aiosp_redirect_attachement_parent' => __( 'Redirect attachment pages to post parent.', 'all-in-one-seo-pack' ), + 'aiosp_ex_pages' => __( 'Enter a comma separated list of pages here to be excluded by All in One SEO Pack. This is helpful when using plugins which generate their own non-WordPress dynamic pages. Ex: /forum/, /contact/ For instance, if you want to exclude the virtual pages generated by a forum plugin, all you have to do is add forum or /forum or /forum/ or and any URL with the word \"forum\" in it, such as http://mysite.com/forum or http://mysite.com/forum/someforumpage here and it will be excluded from All in One SEO Pack.', 'all-in-one-seo-pack' ), + 'aiosp_post_meta_tags' => __( 'What you enter here will be copied verbatim to the header of all Posts. You can enter whatever additional headers you want here, even references to stylesheets.', 'all-in-one-seo-pack' ), + 'aiosp_page_meta_tags' => __( 'What you enter here will be copied verbatim to the header of all Pages. You can enter whatever additional headers you want here, even references to stylesheets.', 'all-in-one-seo-pack' ), + 'aiosp_front_meta_tags' => __( 'What you enter here will be copied verbatim to the header of the front page if you have set a static page in Settings, Reading, Front Page Displays. You can enter whatever additional headers you want here, even references to stylesheets. This will fall back to using Additional Page Headers if you have them set and nothing is entered here.', 'all-in-one-seo-pack' ), + 'aiosp_home_meta_tags' => __( 'What you enter here will be copied verbatim to the header of the home page if you have Front page displays your latest posts selected in Settings, Reading.  It will also be copied verbatim to the header on the Posts page if you have one set in Settings, Reading. You can enter whatever additional headers you want here, even references to stylesheets.', 'all-in-one-seo-pack' ), + + // Keyword Settings. + 'aiosp_togglekeywords' => __( 'This option allows you to toggle the use of Meta Keywords throughout the whole of the site.', 'all-in-one-seo-pack' ), + 'aiosp_use_categories' => __( 'Check this if you want your categories for a given post used as the Meta Keywords for this post (in addition to any keywords you specify on the Edit Post screen).', 'all-in-one-seo-pack' ), + 'aiosp_use_tags_as_keywords' => __( 'Check this if you want your tags for a given post used as the Meta Keywords for this post (in addition to any keywords you specify on the Edit Post screen).', 'all-in-one-seo-pack' ), + 'aiosp_dynamic_postspage_keywords' => __( 'Check this if you want your keywords on your Posts page (set in WordPress under Settings, Reading, Front Page Displays) and your archive pages to be dynamically generated from the keywords of the posts showing on that page. If unchecked, it will use the keywords set in the edit page screen for the posts page.', 'all-in-one-seo-pack' ), + + // Unknown Location. + 'aiosp_license_key' => __( 'This will be the license key received when the product was purchased. This is used for automatic upgrades.', 'all-in-one-seo-pack' ), + 'aiosp_taxactive' => __( 'Use these checkboxes to select which Taxonomies you want to use All in One SEO Pack with.', 'all-in-one-seo-pack' ), + 'aiosp_google_connect' => __( 'Press the connect button to connect with Google Analytics; or if already connected, press the disconnect button to disable and remove any stored analytics credentials.', 'all-in-one-seo-pack' ), + + ); + + // phpcs:disable WordPress.WP.I18n.MissingTranslatorsComment + $post_types = get_post_types( '', 'names' ); + foreach ( $post_types as $v1_pt ) { + if ( ! isset( $rtn_help_text[ 'aiosp_' . $v1_pt . '_title_format' ] ) ) { + $help_text_fields = array(); + array_push( + $help_text_fields, + __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ), + __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ), + __( '%post_title% - The original title of the page', 'all-in-one-seo-pack' ) + ); + $pt_obj_taxes = get_object_taxonomies( $v1_pt, 'objects' ); + foreach ( $pt_obj_taxes as $k2_slug => $v2_tax_obj ) { + array_push( + $help_text_fields, + sprintf( __( "%%tax_%1\$s%% - This post's associated %2\$s taxonomy title", 'all-in-one-seo-pack' ), $k2_slug, $v2_tax_obj->label ) + ); + } + array_push( + $help_text_fields, + __( '%post_author_login% - This page\'s author\' login', 'all-in-one-seo-pack' ), + __( '%post_author_nicename% - This page\'s author\' nicename', 'all-in-one-seo-pack' ), + __( '%post_author_firstname% - This page\'s author\' first name (capitalized)', 'all-in-one-seo-pack' ), + __( '%post_author_lastname% - This page\'s author\' last name (capitalized)', 'all-in-one-seo-pack' ), + __( '%current_date% - The current date (localized)', 'all-in-one-seo-pack' ), + __( '%post_date% - The date the page was published (localized)', 'all-in-one-seo-pack' ), + __( '%post_year% - The year the page was published (localized)', 'all-in-one-seo-pack' ), + __( '%post_month% - The month the page was published (localized)', 'all-in-one-seo-pack' ) + ); + + $cpt_help_text = '
    '; + foreach ( $help_text_fields as $v2_field ) { + $cpt_help_text .= '
  • ' . $v2_field . '
  • '; + } + $cpt_help_text .= '
'; + + $rtn_help_text[ 'aiosp_' . $v1_pt . '_title_format' ] = __( 'The following macros are supported:', 'all-in-one-seo-pack' ) . $cpt_help_text . '
' . __( 'Click here for documentation on this setting', 'all-in-one-seo-pack' ) . ''; + } + } + // phpcs:enable + + $help_doc_link = array( + // General Settings. + 'aiosp_can' => 'https://semperplugins.com/documentation/general-settings/#canonical-urls', + 'aiosp_no_paged_canonical_links' => 'https://semperplugins.com/documentation/general-settings/#no-pagination-for-canonical-urls', + 'aiosp_customize_canonical_links' => 'https://semperplugins.com/documentation/general-settings/#enable-custom-canonical-urls', + 'aiosp_use_original_title' => 'https://semperplugins.com/documentation/general-settings/#use-original-title', + 'aiosp_schema_markup' => 'https://semperplugins.com/documentation/general-settings/#use-schema-markup', + 'aiosp_do_log' => 'https://semperplugins.com/documentation/general-settings/#log-important-events', + + // Home Page Settings. + 'aiosp_home_title' => 'https://semperplugins.com/documentation/home-page-settings/#home-title', + 'aiosp_home_description' => 'https://semperplugins.com/documentation/home-page-settings/#home-description', + 'aiosp_home_keywords' => 'https://semperplugins.com/documentation/home-page-settings/#home-keywords', + 'aiosp_use_static_home_info' => 'https://semperplugins.com/documentation/home-page-settings/#use-static-front-page-instead', + + // Title Settings. + 'aiosp_rewrite_titles' => 'https://semperplugins.com/documentation/title-settings/#rewrite-titles', + 'aiosp_home_page_title_format' => 'https://semperplugins.com/documentation/title-settings/#title-format-fields', + 'aiosp_page_title_format' => 'https://semperplugins.com/documentation/title-settings/#title-format-fields', + 'aiosp_post_title_format' => 'https://semperplugins.com/documentation/title-settings/#title-format-fields', + 'aiosp_category_title_format' => 'https://semperplugins.com/documentation/title-settings/#title-format-fields', + 'aiosp_archive_title_format' => 'https://semperplugins.com/documentation/title-settings/#title-format-fields', + 'aiosp_date_title_format' => 'https://semperplugins.com/documentation/title-settings/#title-format-fields', + 'aiosp_author_title_format' => 'https://semperplugins.com/documentation/title-settings/#title-format-fields', + 'aiosp_tag_title_format' => 'https://semperplugins.com/documentation/title-settings/#title-format-fields', + 'aiosp_search_title_format' => 'https://semperplugins.com/documentation/title-settings/#title-format-fields', + 'aiosp_description_format' => 'https://semperplugins.com/documentation/title-settings/#title-format-fields', + 'aiosp_404_title_format' => 'https://semperplugins.com/documentation/title-settings/#title-format-fields', + 'aiosp_paged_format' => 'https://semperplugins.com/documentation/title-settings/#title-format-fields', + + // Custom Post Type Settings. + 'aiosp_cpostactive' => 'https://semperplugins.com/documentation/custom-post-type-settings/#seo-on-only-these-post-types', + + // Display Settings. + 'aiosp_posttypecolumns' => 'https://semperplugins.com/documentation/display-settings/#show-column-labels-for-custom-post-types', + + // Webmaster Verification. + 'aiosp_google_verify' => 'https://semperplugins.com/documentation/google-search-console-verification/', + 'aiosp_bing_verify' => 'https://semperplugins.com/documentation/bing-webmaster-verification/', + 'aiosp_pinterest_verify' => 'https://semperplugins.com/documentation/pinterest-site-verification/', + + // Google Settings. + 'aiosp_google_publisher' => 'https://semperplugins.com/documentation/google-settings/#google-plus-default-profile', + 'aiosp_google_disable_profile' => 'https://semperplugins.com/documentation/google-settings/#disable-google-plus-profile', + 'aiosp_google_sitelinks_search' => 'https://semperplugins.com/documentation/google-settings/#display-sitelinks-search-box', + 'aiosp_google_set_site_name' => 'https://semperplugins.com/documentation/google-settings/#set-preferred-site-name', + // Missing documentation link. + // 'aiosp_google_specify_site_name' => 'https://semperplugins.com/documentation/google-settings/#set-preferred-site-name', + 'aiosp_google_author_advanced' => 'https://semperplugins.com/documentation/google-settings/#advanced-authorship-options', + 'aiosp_google_author_location' => 'https://semperplugins.com/documentation/google-settings/#display-google-authorship', + 'aiosp_google_enable_publisher' => 'https://semperplugins.com/documentation/google-settings/#display-publisher-meta-on-front-page', + 'aiosp_google_specify_publisher' => 'https://semperplugins.com/documentation/google-settings/#specify-publisher-url', + 'aiosp_google_analytics_id' => 'https://semperplugins.com/documentation/setting-up-google-analytics/', + 'aiosp_ga_advanced_options' => 'https://semperplugins.com/documentation/advanced-google-analytics-settings/', + 'aiosp_ga_domain' => 'https://semperplugins.com/documentation/advanced-google-analytics-settings/#tracking-domain', + 'aiosp_ga_multi_domain' => 'https://semperplugins.com/documentation/advanced-google-analytics-settings/#track-multiple-domains-additional-domains', + 'aiosp_ga_addl_domains' => 'https://semperplugins.com/documentation/advanced-google-analytics-settings/#track-multiple-domains-additional-domains', + 'aiosp_ga_anonymize_ip' => 'https://semperplugins.com/documentation/advanced-google-analytics-settings/#anonymize-ip-addresses', + 'aiosp_ga_display_advertising' => 'https://semperplugins.com/documentation/advanced-google-analytics-settings/#display-advertiser-tracking', + 'aiosp_ga_exclude_users' => 'https://semperplugins.com/documentation/advanced-google-analytics-settings/#exclude-users-from-tracking', + 'aiosp_ga_track_outbound_links' => 'https://semperplugins.com/documentation/advanced-google-analytics-settings/#track-outbound-links', + 'aiosp_ga_link_attribution' => 'https://semperplugins.com/documentation/advanced-google-analytics-settings/#enhanced-link-attribution', + 'aiosp_ga_enhanced_ecommerce' => 'https://semperplugins.com/documentation/advanced-google-analytics-settings/#enhanced-ecommerce', + + // Noindex Settings. + 'aiosp_cpostnoindex' => 'https://semperplugins.com/documentation/noindex-settings/#noindex', + 'aiosp_cpostnofollow' => 'https://semperplugins.com/documentation/noindex-settings/#nofollow', + 'aiosp_category_noindex' => 'https://semperplugins.com/documentation/noindex-settings/#noindex-settings', + 'aiosp_archive_date_noindex' => 'https://semperplugins.com/documentation/noindex-settings/#noindex-settings', + 'aiosp_archive_author_noindex' => 'https://semperplugins.com/documentation/noindex-settings/#noindex-settings', + 'aiosp_tags_noindex' => 'https://semperplugins.com/documentation/noindex-settings/#noindex-settings', + 'aiosp_search_noindex' => 'https://semperplugins.com/documentation/noindex-settings/#use-noindex-for-the-search-page', + 'aiosp_404_noindex' => 'https://semperplugins.com/documentation/noindex-settings/#use-noindex-for-the-404-page', + 'aiosp_paginated_noindex' => 'https://semperplugins.com/documentation/noindex-settings/#use-noindex-for-paginated-pages-posts', + 'aiosp_paginated_nofollow' => 'https://semperplugins.com/documentation/noindex-settings/#use-nofollow-for-paginated-pages-posts', + 'aiosp_tax_noindex' => 'https://semperplugins.com/documentation/noindex-settings/#use-noindex-for-the-taxonomy-archives', + + // Advanced Settings. + 'aiosp_generate_descriptions' => 'https://semperplugins.com/documentation/all-in-one-seo-pack-advanced-settings/#autogenerate-descriptions', + 'aiosp_skip_excerpt' => 'https://semperplugins.com/documentation/all-in-one-seo-pack-advanced-settings/#remove-descriptions-for-paginated-pages', + 'aiosp_run_shortcodes' => 'https://semperplugins.com/documentation/all-in-one-seo-pack-advanced-settings/#never-shorten-long-descriptions', + 'aiosp_hide_paginated_descriptions' => 'https://semperplugins.com/documentation/all-in-one-seo-pack-advanced-settings/#unprotect-post-meta-fields', + 'aiosp_dont_truncate_descriptions' => 'https://semperplugins.com/documentation/all-in-one-seo-pack-advanced-settings/#never-shorten-long-descriptions', + 'aiosp_unprotect_meta' => 'https://semperplugins.com/documentation/all-in-one-seo-pack-advanced-settings/#unprotect-post-meta-fields', + 'aiosp_redirect_attachement_parent' => 'https://semperplugins.com/documentation/all-in-one-seo-pack-advanced-settings/#redirect-attachments-to-post-parent', + 'aiosp_ex_pages' => 'https://semperplugins.com/documentation/all-in-one-seo-pack-advanced-settings/#exclude-pages', + 'aiosp_post_meta_tags' => 'https://semperplugins.com/documentation/all-in-one-seo-pack-advanced-settings/#additional-post-headers', + 'aiosp_page_meta_tags' => 'https://semperplugins.com/documentation/all-in-one-seo-pack-advanced-settings/#additional-page-headers', + 'aiosp_front_meta_tags' => 'https://semperplugins.com/documentation/all-in-one-seo-pack-advanced-settings/#additional-front-page-headers', + 'aiosp_home_meta_tags' => 'https://semperplugins.com/documentation/all-in-one-seo-pack-advanced-settings/#additional-blog-page-headers', + + // Keyword Settings. + 'aiosp_togglekeywords' => 'https://semperplugins.com/documentation/keyword-settings/#use-keywords', + 'aiosp_use_categories' => 'https://semperplugins.com/documentation/keyword-settings/#use-categories-for-meta-keywords', + 'aiosp_use_tags_as_keywords' => 'https://semperplugins.com/documentation/keyword-settings/#use-tags-for-meta-keywords', + 'aiosp_dynamic_postspage_keywords' => 'https://semperplugins.com/documentation/keyword-settings/#dynamically-generate-keywords-for-posts-page', + + // Unknown/Pro? + // 'aiosp_license_key' => '', + // 'aiosp_taxactive' => '', + // 'aiosp_google_connect' => '', + ); + + foreach ( $help_doc_link as $k1_slug => $v1_url ) { + // Any help text that ends with a ul or ol element will cause text to start at the next line. + $tooltips_with_ul = array( + 'aiosp_home_page_title_format', + 'aiosp_page_title_format', + 'aiosp_post_title_format', + 'aiosp_category_title_format', + 'aiosp_archive_title_format', + 'aiosp_date_title_format', + 'aiosp_author_title_format', + 'aiosp_tag_title_format', + 'aiosp_search_title_format', + 'aiosp_description_format', + 'aiosp_404_title_format', + 'aiosp_paged_format', + ); + + $br = '

'; + if ( in_array( $k1_slug, $tooltips_with_ul, true ) ) { + $br = '
'; + } + + $rtn_help_text[ $k1_slug ] .= $br . '' . __( 'Click here for documentation on this setting.', 'all-in-one-seo-pack' ) . ''; + } + + return $rtn_help_text; + } + + /** + * Help Text Performance Module + * + * @ignore + * @since 2.4.2 + * @access private + * + * @return array + */ + private function help_text_performance() { + $rtn_help_text = array( + 'aiosp_performance_memory_limit' => __( 'This setting allows you to raise your PHP memory limit to a reasonable value. Note: WordPress core and other WordPress plugins may also change the value of the memory limit.', 'all-in-one-seo-pack' ), + 'aiosp_performance_execution_time' => __( 'This setting allows you to raise your PHP execution time to a reasonable value.', 'all-in-one-seo-pack' ), + 'aiosp_performance_force_rewrites' => __( 'Use output buffering to ensure that the title gets rewritten. Enable this option if you run into issues with the title tag being set by your theme or another plugin.', 'all-in-one-seo-pack' ), + ); + + $help_doc_link = array( + 'aiosp_performance_memory_limit' => 'https://semperplugins.com/documentation/performance-settings/#raise-memory-limit', + 'aiosp_performance_execution_time' => 'https://semperplugins.com/documentation/performance-settings/#raise-execution-time', + 'aiosp_performance_force_rewrites' => 'https://semperplugins.com/documentation/performance-settings/#force-rewrites', + ); + + foreach ( $help_doc_link as $k1_slug => $v1_url ) { + $rtn_help_text[ $k1_slug ] .= '

' . __( 'Click here for documentation on this setting.', 'all-in-one-seo-pack' ) . ''; + } + + return $rtn_help_text; + } + + /** + * Help Text Sitemap Module + * + * @ignore + * @since 2.4.2 + * @access private + * + * @return array + */ + private function help_text_sitemap() { + $rtn_help_text = array( + 'aiosp_sitemap_rss_sitemap' => __( 'Create RSS Sitemap as well.', 'all-in-one-seo-pack' ), + 'aiosp_sitemap_daily_cron' => __( 'Notify search engines based on the selected schedule, and also update static sitemap daily if in use. (this uses WP-Cron, so make sure this is working properly on your server as well)', 'all-in-one-seo-pack' ), + 'aiosp_sitemap_indexes' => __( 'Organize sitemap entries into distinct files in your sitemap. Enable this only if your sitemap contains over 50,000 URLs or the file is over 5MB in size.', 'all-in-one-seo-pack' ), + 'aiosp_sitemap_max_posts' => __( 'Allows you to specify the maximum number of posts in a sitemap (up to 50,000).', 'all-in-one-seo-pack' ), + 'aiosp_sitemap_posttypes' => __( 'Select which Post Types appear in your sitemap.', 'all-in-one-seo-pack' ), + 'aiosp_sitemap_taxonomies' => __( 'Select which taxonomy archives appear in your sitemap', 'all-in-one-seo-pack' ), + 'aiosp_sitemap_archive' => __( 'Include Date Archives in your sitemap.', 'all-in-one-seo-pack' ), + 'aiosp_sitemap_author' => __( 'Include Author Archives in your sitemap.', 'all-in-one-seo-pack' ), + 'aiosp_sitemap_images' => __( 'Exclude Images in your sitemap.', 'all-in-one-seo-pack' ), + 'aiosp_sitemap_gzipped' => __( 'Create a compressed sitemap file in .xml.gz format.', 'all-in-one-seo-pack' ), + 'aiosp_sitemap_robots' => __( 'Places a link to your Sitemap.xml into your virtual Robots.txt file.', 'all-in-one-seo-pack' ), + 'aiosp_sitemap_rewrite' => __( 'Dynamically creates the XML sitemap instead of using a static file.', 'all-in-one-seo-pack' ), + 'aiosp_sitemap_addl_url' => __( 'URL to the page. This field accepts relative URLs or absolute URLs with the protocol specified.', 'all-in-one-seo-pack' ), + 'aiosp_sitemap_addl_prio' => __( 'The priority of the page.', 'all-in-one-seo-pack' ), + 'aiosp_sitemap_addl_freq' => __( 'The frequency of the page.', 'all-in-one-seo-pack' ), + 'aiosp_sitemap_addl_mod' => __( 'Last modified date of the page.', 'all-in-one-seo-pack' ), + 'aiosp_sitemap_excl_categories' => __( 'Entries from these categories will be excluded from the sitemap.', 'all-in-one-seo-pack' ), + 'aiosp_sitemap_excl_pages' => __( 'Use page slugs or page IDs, seperated by commas, to exclude pages from the sitemap.', 'all-in-one-seo-pack' ), + ); + + $parent_prio_help = __( 'Manually set the priority of your ', 'all-in-one-seo-pack' ); + $parent_freq_help = __( 'Manually set the frequency of your ', 'all-in-one-seo-pack' ); + $prio_help = __( 'Manually set the priority for the ', 'all-in-one-seo-pack' ); + $freq_help = __( 'Manually set the frequency for the ', 'all-in-one-seo-pack' ); + $post_name = __( ' Post Type', 'all-in-one-seo-pack' ); + $tax_name = __( ' Taxonomy', 'all-in-one-seo-pack' ); + + $args = array( + 'public' => true, + ); + + $rtn_help_text['aiosp_sitemap_prio_homepage'] = $parent_prio_help . __( 'Homepage.', 'all-in-one-seo-pack' ); + $rtn_help_text['aiosp_sitemap_prio_post'] = $parent_prio_help . __( 'posts.', 'all-in-one-seo-pack' ); + $rtn_help_text['aiosp_sitemap_prio_taxonomies'] = $parent_prio_help . __( 'taxonomies.', 'all-in-one-seo-pack' ); + $rtn_help_text['aiosp_sitemap_prio_archive'] = $parent_prio_help . __( 'archive pages.', 'all-in-one-seo-pack' ); + $rtn_help_text['aiosp_sitemap_prio_author'] = $parent_prio_help . __( 'author pages.', 'all-in-one-seo-pack' ); + + $post_types = get_post_types( $args, 'names' ); + foreach ( $post_types as $pt ) { + $pt_obj = get_post_type_object( $pt ); + $rtn_help_text[ 'aiosp_sitemap_prio_post_' . $pt ] = $prio_help . $pt_obj->label . $post_name; + $rtn_help_text[ 'aiosp_sitemap_freq_post_' . $pt ] = $freq_help . $pt_obj->label . $post_name; + } + + $args = array( + 'public' => true, + ); + + $rtn_help_text['aiosp_sitemap_freq_homepage'] = $parent_freq_help . __( 'Homepage.', 'all-in-one-seo-pack' ); + $rtn_help_text['aiosp_sitemap_freq_post'] = $parent_freq_help . __( 'posts.', 'all-in-one-seo-pack' ); + $rtn_help_text['aiosp_sitemap_freq_taxonomies'] = $parent_freq_help . __( 'taxonomies.', 'all-in-one-seo-pack' ); + $rtn_help_text['aiosp_sitemap_freq_archive'] = $parent_freq_help . __( 'archive pages.', 'all-in-one-seo-pack' ); + $rtn_help_text['aiosp_sitemap_freq_author'] = $parent_freq_help . __( 'author pages.', 'all-in-one-seo-pack' ); + + $taxonomies = get_taxonomies( $args, 'object' ); + foreach ( $taxonomies as $tax ) { + $rtn_help_text[ 'aiosp_sitemap_prio_taxonomies_' . $tax->name ] = $prio_help . $tax->label . $tax_name; + $rtn_help_text[ 'aiosp_sitemap_freq_taxonomies_' . $tax->name ] = $freq_help . $tax->label . $tax_name; + } + + $help_doc_link = array( + // XML Sitemap. + 'aiosp_sitemap_rss_sitemap' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#create-rss_sitemap', + 'aiosp_sitemap_daily_cron' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#schedule-updates', + 'aiosp_sitemap_indexes' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#enable-sitemap-indexes', + 'aiosp_sitemap_max_posts' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#enable-sitemap-indexes', + 'aiosp_sitemap_posttypes' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#post-types-and-taxonomies', + 'aiosp_sitemap_taxonomies' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#post-types-and-taxonomies', + 'aiosp_sitemap_archive' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#include-archive-pages', + 'aiosp_sitemap_author' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#include-archive-pages', + 'aiosp_sitemap_images' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#exclude-images', + 'aiosp_sitemap_gzipped' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#create-compressed-sitemap', + 'aiosp_sitemap_robots' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#link-from-virtual-robots', + 'aiosp_sitemap_rewrite' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#dynamically-generate-sitemap', + + // Additional Pages. + 'aiosp_sitemap_addl_url' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#additional-pages', + 'aiosp_sitemap_addl_prio' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#additional-pages', + 'aiosp_sitemap_addl_freq' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#additional-pages', + 'aiosp_sitemap_addl_mod' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#additional-pages', + + // Exclude Items. + 'aiosp_sitemap_excl_categories' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#excluded-items', + 'aiosp_sitemap_excl_pages' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#excluded-items', + + // Priorities. + 'aiosp_sitemap_prio_homepage' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#priorities-and-frequencies', + 'aiosp_sitemap_prio_post' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#priorities-and-frequencies', + 'aiosp_sitemap_prio_taxonomies' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#priorities-and-frequencies', + 'aiosp_sitemap_prio_archive' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#priorities-and-frequencies', + 'aiosp_sitemap_prio_author' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#priorities-and-frequencies', + + // Frequencies. + 'aiosp_sitemap_freq_homepage' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#priorities-and-frequencies', + 'aiosp_sitemap_freq_post' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#priorities-and-frequencies', + 'aiosp_sitemap_freq_taxonomies' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#priorities-and-frequencies', + 'aiosp_sitemap_freq_archive' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#priorities-and-frequencies', + 'aiosp_sitemap_freq_author' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#priorities-and-frequencies', + + ); + + /* + * Currently has no links, but may be added later. + foreach ( $post_types as $pt ) { + $help_doc_link[ 'aiosp_sitemap_prio_post_' . $pt ] = ''; + $help_doc_link[ 'aiosp_sitemap_freq_post_' . $pt ] = ''; + } + */ + + /* + * Currently has no links, but may be added later. + foreach ( $taxonomies as $tax ) { + $help_doc_link[ 'aiosp_sitemap_prio_taxonomies_' . $tax->name ] = ''; + $help_doc_link[ 'aiosp_sitemap_freq_taxonomies_' . $tax->name ] = ''; + } + */ + + foreach ( $help_doc_link as $k1_slug => $v1_url ) { + $rtn_help_text[ $k1_slug ] .= '

' . __( 'Click here for documentation on this setting.', 'all-in-one-seo-pack' ) . ''; + } + + return $rtn_help_text; + } + + /** + * Help Text Opengraph Module + * + * @ignore + * @since 2.4.2 + * @access private + * + * @return array + */ + private function help_text_opengraph() { + $rtn_help_text = array( + // Home Page Settings. + 'aiosp_opengraph_setmeta' => __( 'Checking this box will use the Home Title and Home Description set in All in One SEO Pack, General Settings as the Open Graph title and description for your home page.', 'all-in-one-seo-pack' ), + 'aiosp_opengraph_sitename' => __( 'The Site Name is the name that is used to identify your website.', 'all-in-one-seo-pack' ), + 'aiosp_opengraph_hometitle' => __( 'The Home Title is the Open Graph title for your home page.', 'all-in-one-seo-pack' ), + 'aiosp_opengraph_description' => __( 'The Home Description is the Open Graph description for your home page.', 'all-in-one-seo-pack' ), + 'aiosp_opengraph_homeimage' => __( 'The Home Image is the Open Graph image for your home page.', 'all-in-one-seo-pack' ), + + // Image Settings. + 'aiosp_opengraph_defimg' => __( 'This option lets you choose which image will be displayed by default for the Open Graph image. You may override this on individual posts.', 'all-in-one-seo-pack' ), + 'aiosp_opengraph_fallback' => __( 'This option lets you fall back to the default image if no image could be found above.', 'all-in-one-seo-pack' ), + 'aiosp_opengraph_dimg' => __( 'This option sets a default image that can be used for the Open Graph image. You can upload an image, select an image from your Media Library or paste the URL of an image here.', 'all-in-one-seo-pack' ), + 'aiosp_opengraph_dimgwidth' => __( 'This option lets you set a default width for your images, where unspecified.', 'all-in-one-seo-pack' ), + 'aiosp_opengraph_dimgheight' => __( 'This option lets you set a default height for your images, where unspecified.', 'all-in-one-seo-pack' ), + 'aiosp_opengraph_meta_key' => __( 'Enter the name of a custom field (or multiple field names separated by commas) to use that field to specify the Open Graph image on Pages or Posts.', 'all-in-one-seo-pack' ), + + // Social Profile Links. + 'aiosp_opengraph_profile_links' => __( 'Add URLs for your website\'s social profiles here (Facebook, Twitter, Google+, Instagram, LinkedIn), one per line.', 'all-in-one-seo-pack' ), + 'aiosp_opengraph_person_or_org' => __( 'Are the social profile links for your website for a person or an organization?', 'all-in-one-seo-pack' ), + 'aiosp_opengraph_social_name' => __( 'Add the name of the person or organization who owns these profiles.', 'all-in-one-seo-pack' ), + + // Facebook Settings. + 'aiosp_opengraph_key' => __( 'Enter your Facebook Admin ID here. You can enter multiple IDs separated by a comma. You can look up your Facebook ID using this tool http://findmyfbid.com/', 'all-in-one-seo-pack' ), + 'aiosp_opengraph_appid' => __( 'Enter your Facebook App ID here. Information about how to get your Facebook App ID can be found at https://developers.facebook.com/docs/apps/register', 'all-in-one-seo-pack' ), + 'aiosp_opengraph_gen_tags' => __( 'Automatically generate article tags for Facebook type article when not provided.', 'all-in-one-seo-pack' ), + 'aiosp_opengraph_gen_keywords' => __( 'Use keywords in generated article tags.', 'all-in-one-seo-pack' ), + 'aiosp_opengraph_gen_categories' => __( 'Use categories in generated article tags.', 'all-in-one-seo-pack' ), + 'aiosp_opengraph_gen_post_tags' => __( 'Use post tags in generated article tags.', 'all-in-one-seo-pack' ), + 'aiosp_opengraph_types' => __( 'Select which Post Types you want to use All in One SEO Pack to set Open Graph meta values for.', 'all-in-one-seo-pack' ), + 'aiosp_opengraph_facebook_publisher' => __( 'Link articles to the Facebook page associated with your website.', 'all-in-one-seo-pack' ), + 'aiosp_opengraph_facebook_author' => __( 'Allows your authors to be identified by their Facebook pages as content authors on the Opengraph meta for their articles.', 'all-in-one-seo-pack' ), + + // Twitter Settings. + 'aiosp_opengraph_defcard' => __( 'Select the default type of Twitter Card to display.', 'all-in-one-seo-pack' ), + 'aiosp_opengraph_twitter_site' => __( 'Enter the Twitter username associated with your website here.', 'all-in-one-seo-pack' ), + 'aiosp_opengraph_twitter_creator' => __( 'Allows your authors to be identified by their Twitter usernames as content creators on the Twitter cards for their posts.', 'all-in-one-seo-pack' ), + 'aiosp_opengraph_twitter_domain' => __( 'Enter the name of your website here.', 'all-in-one-seo-pack' ), + + // Advanced Settings. + 'aiosp_opengraph_title_shortcodes' => __( 'Run shortcodes that appear in social title meta tags.', 'all-in-one-seo-pack' ), + 'aiosp_opengraph_description_shortcodes' => __( 'Run shortcodes that appear in social description meta tags.', 'all-in-one-seo-pack' ), + 'aiosp_opengraph_generate_descriptions' => __( 'This option will auto generate your Open Graph descriptions from your post content instead of your post excerpt. WooCommerce users should read the documentation regarding this setting.', 'all-in-one-seo-pack' ), + + // POST META. + 'aioseop_opengraph_settings_title' => __( 'This is the Open Graph title of this Page or Post.', 'all-in-one-seo-pack' ), + 'aioseop_opengraph_settings_desc' => __( 'This is the Open Graph description of this Page or Post.', 'all-in-one-seo-pack' ), + 'aioseop_opengraph_settings_image' => __( 'This option lets you select the Open Graph image that will be used for this Page or Post, overriding the default settings.', 'all-in-one-seo-pack' ), + 'aioseop_opengraph_settings_customimg' => __( 'This option lets you upload an image to use as the Open Graph image for this Page or Post.', 'all-in-one-seo-pack' ), + 'aioseop_opengraph_settings_imagewidth' => __( 'Enter the width for your Open Graph image in pixels (i.e. 600).', 'all-in-one-seo-pack' ), + 'aioseop_opengraph_settings_imageheight' => __( 'Enter the height for your Open Graph image in pixels (i.e. 600).', 'all-in-one-seo-pack' ), + 'aioseop_opengraph_settings_video' => __( 'This option lets you specify a link to the Open Graph video used on this Page or Post.', 'all-in-one-seo-pack' ), + 'aioseop_opengraph_settings_videowidth' => __( 'Enter the width for your Open Graph video in pixels (i.e. 600).', 'all-in-one-seo-pack' ), + 'aioseop_opengraph_settings_videoheight' => __( 'Enter the height for your Open Graph video in pixels (i.e. 600).', 'all-in-one-seo-pack' ), + 'aioseop_opengraph_settings_category' => __( 'Select the Open Graph type that best describes the content of this Page or Post.', 'all-in-one-seo-pack' ), + 'aioseop_opengraph_settings_facebook_debug' => __( 'Press this button to have Facebook re-fetch and debug this page.', 'all-in-one-seo-pack' ), + 'aioseop_opengraph_settings_section' => __( 'This Open Graph meta allows you to add a general section name that best describes this content.', 'all-in-one-seo-pack' ), + 'aioseop_opengraph_settings_tag' => __( 'This Open Graph meta allows you to add a list of keywords that best describe this content.', 'all-in-one-seo-pack' ), + 'aioseop_opengraph_settings_setcard' => __( 'Select the Twitter Card type to use for this Page or Post, overriding the default setting.', 'all-in-one-seo-pack' ), + 'aioseop_opengraph_settings_customimg_twitter' => __( 'This option lets you upload an image to use as the Twitter image for this Page or Post.', 'all-in-one-seo-pack' ), + ); + + $args = array( + 'public' => true, + ); + + $post_types = get_post_types( $args, 'names' ); + foreach ( $post_types as $pt ) { + $rtn_help_text[ 'aiosp_opengraph_' . $pt . '_fb_object_type' ] = __( 'Choose a default value that best describes the content of your post type.', 'all-in-one-seo-pack' ); + $rtn_help_text[ 'aiosp_opengraph_' . $pt . '_fb_object_type' ] .= '

' . __( 'Click here for documentation on this setting.', 'all-in-one-seo-pack' ) . ''; + } + + $help_doc_link = array( + // Home Page Settings. + 'aiosp_opengraph_setmeta' => 'https://semperplugins.com/documentation/social-meta-module/#use-aioseo-title-and-description', + 'aiosp_opengraph_sitename' => 'https://semperplugins.com/documentation/social-meta-module/#site-name', + 'aiosp_opengraph_hometitle' => 'https://semperplugins.com/documentation/social-meta-module/#home-title-and-description', + 'aiosp_opengraph_description' => 'https://semperplugins.com/documentation/social-meta-module/#home-title-and-description', + 'aiosp_opengraph_homeimage' => 'https://semperplugins.com/documentation/social-meta-module/#home-image', + + // Image Settings. + 'aiosp_opengraph_defimg' => 'https://semperplugins.com/documentation/social-meta-module/#select-og-image-source', + 'aiosp_opengraph_fallback' => 'https://semperplugins.com/documentation/social-meta-module/#use-default-if-no-image-found', + 'aiosp_opengraph_dimg' => 'https://semperplugins.com/documentation/social-meta-module/#default-og-image', + 'aiosp_opengraph_dimgwidth' => 'https://semperplugins.com/documentation/social-meta-module/#default-image-width', + 'aiosp_opengraph_dimgheight' => 'https://semperplugins.com/documentation/social-meta-module/#default-image-height', + 'aiosp_opengraph_meta_key' => 'https://semperplugins.com/documentation/social-meta-module/#use-custom-field-for-image', + + // Social Profile Links. + 'aiosp_opengraph_profile_links' => 'https://semperplugins.com/documentation/social-meta-module/#social-profile-links', + 'aiosp_opengraph_person_or_org' => 'https://semperplugins.com/documentation/social-meta-module/#social-profile-links', + 'aiosp_opengraph_social_name' => 'https://semperplugins.com/documentation/social-meta-module/#social-profile-links', + + // Facebook Settings. + 'aiosp_opengraph_key' => 'https://semperplugins.com/documentation/social-meta-module/#facebook-admin-id', + 'aiosp_opengraph_appid' => 'https://semperplugins.com/documentation/social-meta-module/#facebook-app-id', + 'aiosp_opengraph_gen_tags' => 'https://semperplugins.com/documentation/social-meta-module/#automatically-generate-article-tags', + 'aiosp_opengraph_gen_keywords' => 'https://semperplugins.com/documentation/social-meta-module/#use-keywords-in-article-tags', + 'aiosp_opengraph_gen_categories' => 'https://semperplugins.com/documentation/social-meta-module/#use-categories-in-article-tags', + 'aiosp_opengraph_gen_post_tags' => 'https://semperplugins.com/documentation/social-meta-module/#use-post-tags-in-article-tags', + 'aiosp_opengraph_types' => 'https://semperplugins.com/documentation/social-meta-module/#enable-facebook-meta-for', + 'aiosp_opengraph_facebook_publisher' => 'https://semperplugins.com/documentation/social-meta-module/#show-facebook-publisher-on-articles', + 'aiosp_opengraph_facebook_author' => 'https://semperplugins.com/documentation/social-meta-module/#show-facebook-author-on-articles', + + // Twitter Settings. + 'aiosp_opengraph_defcard' => 'https://semperplugins.com/documentation/social-meta-module/#default-twitter-card', + 'aiosp_opengraph_twitter_site' => 'https://semperplugins.com/documentation/social-meta-module/#twitter-site', + 'aiosp_opengraph_twitter_creator' => 'https://semperplugins.com/documentation/social-meta-module/#show-twitter-author', + 'aiosp_opengraph_twitter_domain' => 'https://semperplugins.com/documentation/social-meta-module/#twitter-domain', + + // Advanced Settings. + 'aiosp_opengraph_title_shortcodes' => 'https://semperplugins.com/documentation/social-meta-module/#run-shortcodes-in-title', + 'aiosp_opengraph_description_shortcodes' => 'https://semperplugins.com/documentation/social-meta-module/#run-shortcodes-in-description', + 'aiosp_opengraph_generate_descriptions' => 'https://semperplugins.com/documentation/social-meta-module/#auto-generate-og-descriptions', + + // POST META. + 'aioseop_opengraph_settings_title' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#title', + 'aioseop_opengraph_settings_desc' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#description', + 'aioseop_opengraph_settings_image' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#image', + 'aioseop_opengraph_settings_customimg' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#custom-image', + 'aioseop_opengraph_settings_imagewidth' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#specify-image-width-height', + 'aioseop_opengraph_settings_imageheight' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#specify-image-width-height', + 'aioseop_opengraph_settings_video' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#custom-video', + 'aioseop_opengraph_settings_videowidth' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#specify-video-width-height', + 'aioseop_opengraph_settings_videoheight' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#specify-video-width-height', + 'aioseop_opengraph_settings_category' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#facebook-object-type', + 'aioseop_opengraph_settings_facebook_debug' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#facebook-debug', + 'aioseop_opengraph_settings_section' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#article-section', + 'aioseop_opengraph_settings_tag' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#article-tags', + 'aioseop_opengraph_settings_setcard' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#twitter-card-type', + 'aioseop_opengraph_settings_customimg_twitter' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#custom-twitter-image', + ); + + foreach ( $help_doc_link as $k1_slug => $v1_url ) { + $rtn_help_text[ $k1_slug ] .= '

' . __( 'Click here for documentation on this setting.', 'all-in-one-seo-pack' ) . ''; + } + + return $rtn_help_text; + } + + /** + * Help Text Robots Generator Module + * + * @ignore + * @since 2.4.2 + * @access private + * + * @return array + */ + private function help_text_robots_generator() { + $rtn_help_text = array( + 'aiosp_robots_type' => __( 'Rule Type', 'all-in-one-seo-pack' ), + 'aiosp_robots_agent' => __( 'User Agent', 'all-in-one-seo-pack' ), + 'aiosp_robots_path' => __( 'Directory Path', 'all-in-one-seo-pack' ), + ); + + return $rtn_help_text; + } + + /** + * Help Text File Editor Module + * + * @ignore + * @since 2.4.2 + * @access private + * + * @return array + */ + private function help_text_file_editor() { + return array( + 'aiosp_file_editor_htaccfile' => __( '.htaccess editor', 'all-in-one-seo-pack' ), + ); + } + + /** + * Help Text Importer Exporter Module + * + * @ignore + * @since 2.4.2 + * @access private + * + * @return array + */ + private function help_text_importer_exporter() { + $rtn_help_text = array( + // Possible HTML link concept IF links become usable inside jQuery UI Tooltips. + 'aiosp_importer_exporter_import_submit' => __( 'Choose a valid All in One SEO Pack ini file and click "Import" to import options from a previous state or install of All in One SEO Pack.', 'all-in-one-seo-pack' ), + 'aiosp_importer_exporter_export_choices' => __( 'You may choose to export settings from active modules, and content from post data.', 'all-in-one-seo-pack' ), + 'aiosp_importer_exporter_export_post_types' => __( 'Select which Post Types you want to export your All in One SEO Pack meta data for.', 'all-in-one-seo-pack' ), + ); + + $help_doc_link = array( + 'aiosp_importer_exporter_import_submit' => 'https://semperplugins.com/documentation/importer-exporter-module/', + 'aiosp_importer_exporter_export_choices' => 'https://semperplugins.com/documentation/importer-exporter-module/', + 'aiosp_importer_exporter_export_post_types' => 'https://semperplugins.com/documentation/importer-exporter-module/', + ); + + foreach ( $help_doc_link as $k1_slug => $v1_url ) { + $rtn_help_text[ $k1_slug ] .= '

' . __( 'Click here for documentation on this setting.', 'all-in-one-seo-pack' ) . ''; + } + + return $rtn_help_text; + } + + /** + * Help Text Bad Robots Module + * + * @ignore + * @since 2.4.2 + * @access private + * + * @return array + */ + private function help_text_bad_robots() { + return array( + 'aiosp_bad_robots_block_bots' => __( 'Block requests from user agents that are known to misbehave with 503.', 'all-in-one-seo-pack' ), + 'aiosp_bad_robots_block_refer' => __( 'Block Referral Spam using HTTP.', 'all-in-one-seo-pack' ), + 'aiosp_bad_robots_track_blocks' => __( 'Log and show recent requests from blocked bots.', 'all-in-one-seo-pack' ), + 'aiosp_bad_robots_edit_blocks' => __( 'Check this to edit the list of disallowed user agents for blocking bad bots.', 'all-in-one-seo-pack' ), + 'aiosp_bad_robots_blocklist' => __( 'This is the list of disallowed user agents used for blocking bad bots.', 'all-in-one-seo-pack' ), + 'aiosp_bad_robots_referlist' => __( 'This is the list of disallowed referers used for blocking bad bots.', 'all-in-one-seo-pack' ), + 'aiosp_bad_robots_blocked_log' => __( 'Shows log of most recent requests from blocked bots. Note: this will not track any bots that were already blocked at the web server / .htaccess level.', 'all-in-one-seo-pack' ), + ); + } + + /** + * Help Text Post Meta (Core Module) + * + * @ignore + * @since 2.4.2 + * @access private + * + * @see self::_help_text_opengraph() Also adds Post Meta info. + * + * @return array + */ + private function help_text_post_meta() { + $rtn_help_text = array( + 'aiosp_snippet' => __( 'A preview of what this page might look like in search engine results.', 'all-in-one-seo-pack' ), + 'aiosp_title' => __( 'A custom title that shows up in the title tag for this page.', 'all-in-one-seo-pack' ), + 'aiosp_description' => __( 'The META description for this page. This will override any autogenerated descriptions.', 'all-in-one-seo-pack' ), + 'aiosp_keywords' => __( 'A comma separated list of your most important keywords for this page that will be written as META keywords.', 'all-in-one-seo-pack' ), + 'aiosp_custom_link' => __( 'Override the canonical URLs for this post.', 'all-in-one-seo-pack' ), + 'aiosp_noindex' => __( 'Check this box to ask search engines not to index this page.', 'all-in-one-seo-pack' ), + 'aiosp_nofollow' => __( 'Check this box to ask search engines not to follow links from this page.', 'all-in-one-seo-pack' ), + 'aiosp_sitemap_exclude' => __( 'Don\'t display this page in the sitemap.', 'all-in-one-seo-pack' ), + 'aiosp_disable' => __( 'Disable SEO on this page.', 'all-in-one-seo-pack' ), + 'aiosp_disable_analytics' => __( 'Disable Google Analytics on this page.', 'all-in-one-seo-pack' ), + ); + + $help_doc_link = array( + 'aiosp_snippet' => 'https://semperplugins.com/documentation/post-settings/#preview-snippet', + 'aiosp_title' => 'https://semperplugins.com/documentation/post-settings/#title', + 'aiosp_description' => 'https://semperplugins.com/documentation/post-settings/#description', + 'aiosp_keywords' => 'https://semperplugins.com/documentation/post-settings/#keywords', + 'aiosp_custom_link' => 'https://semperplugins.com/documentation/post-settings/#custom-canonical-url', + 'aiosp_noindex' => 'https://semperplugins.com/documentation/post-settings/#robots-meta-noindex', + 'aiosp_nofollow' => 'https://semperplugins.com/documentation/post-settings/#robots-meta-nofollow', + 'aiosp_sitemap_exclude' => 'https://semperplugins.com/documentation/post-settings/#exclude-from-sitemap', + 'aiosp_disable' => 'https://semperplugins.com/documentation/post-settings/#disable-on-this-post', + 'aiosp_disable_analytics' => 'https://semperplugins.com/documentation/post-settings/#disable-google-analytics', + ); + + foreach ( $help_doc_link as $k1_slug => $v1_url ) { + $rtn_help_text[ $k1_slug ] .= '

' . __( 'Click here for documentation on this setting.', 'all-in-one-seo-pack' ) . ''; + } + + return $rtn_help_text; + } + + /** + * Get Help Text + * + * Gets an individual help text if it exists, otherwise an error is returned + * to notify the AIOSEOP Devs. + * NOTE: Returning an empty string causes issues with the UI. + * + * @since 2.4.2 + * + * @param string $slug Module option slug. + * @return string + */ + public function get_help_text( $slug ) { + if ( isset( $this->help_text[ $slug ] ) ) { + return esc_html( $this->help_text[ $slug ] ); + } + return 'DEV: Missing Help Text: ' . $slug; + } +} diff --git a/aioseop_class.php b/aioseop_class.php index e88d63f12..406d673f4 100644 --- a/aioseop_class.php +++ b/aioseop_class.php @@ -79,283 +79,6 @@ function __construct() { $blog_name = esc_attr( get_bloginfo( 'name' ) ); parent::__construct(); - /* - * Consider changing the construction of the macros. - * - * The name of the macro should NOT be inside _e() or __() because it does not make sense as it - * won't change with the language. - * - * Moreover, it will confuse WPCS and it will try to replace %c (as in %category%) to %$1c. - * Placeholder %s (%something) has been bug fixed. - * @link https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/issues/698 - */ - // @codingStandardsIgnoreStart - $this->help_text = array( - 'license_key' => __( 'This will be the license key received when the product was purchased. This is used for automatic upgrades.', 'all-in-one-seo-pack' ), - 'can' => __( 'This option will automatically generate Canonical URLs for your entire WordPress installation. This will help to prevent duplicate content penalties by Google', 'all-in-one-seo-pack' ), - 'no_paged_canonical_links' => __( 'Checking this option will set the Canonical URL for all paginated content to the first page.', 'all-in-one-seo-pack' ), - 'customize_canonical_links' => __( 'Checking this option will allow you to customize Canonical URLs for specific posts.', 'all-in-one-seo-pack' ), - 'use_original_title' => __( 'Use wp_title to get the title used by the theme; this is disabled by default. If you use this option, set your title formats appropriately, as your theme might try to do its own title SEO as well.', 'all-in-one-seo-pack' ), - 'do_log' => __( 'Check this and All in One SEO Pack will create a log of important events (all-in-one-seo-pack.log) in its plugin directory which might help debugging. Make sure this directory is writable.', 'all-in-one-seo-pack' ), - 'home_title' => __( 'As the name implies, this will be the Meta Title of your homepage. This is independent of any other option. If not set, the default Site Title (found in WordPress under Settings, General, Site Title) will be used.', 'all-in-one-seo-pack' ), - 'home_description' => __( 'This will be the Meta Description for your homepage. This is independent of any other option. The default is no Meta Description at all if this is not set.', 'all-in-one-seo-pack' ), - 'home_keywords' => __( 'Enter a comma separated list of your most important keywords for your site that will be written as Meta Keywords on your homepage. Do not stuff everything in here.', 'all-in-one-seo-pack' ), - 'use_static_home_info' => __( 'Checking this option uses the title, description, and keywords set on your static Front Page.', 'all-in-one-seo-pack' ), - 'togglekeywords' => __( 'This option allows you to toggle the use of Meta Keywords throughout the whole of the site.', 'all-in-one-seo-pack' ), - 'use_categories' => __( 'Check this if you want your categories for a given post used as the Meta Keywords for this post (in addition to any keywords you specify on the Edit Post screen).', 'all-in-one-seo-pack' ), - 'use_tags_as_keywords' => __( 'Check this if you want your tags for a given post used as the Meta Keywords for this post (in addition to any keywords you specify on the Edit Post screen).', 'all-in-one-seo-pack' ), - 'dynamic_postspage_keywords' => __( 'Check this if you want your keywords on your Posts page (set in WordPress under Settings, Reading, Front Page Displays) and your archive pages to be dynamically generated from the keywords of the posts showing on that page. If unchecked, it will use the keywords set in the edit page screen for the posts page.', 'all-in-one-seo-pack' ), - 'rewrite_titles' => __( "Note that this is all about the title tag. This is what you see in your browser's window title bar. This is NOT visible on a page, only in the title bar and in the source code. If enabled, all page, post, category, search and archive page titles get rewritten. You can specify the format for most of them. For example: Using the default post title format below, Rewrite Titles will write all post titles as 'Post Title | Blog Name'. If you have manually defined a title using All in One SEO Pack, this will become the title of your post in the format string.", 'all-in-one-seo-pack' ), - 'home_page_title_format' => - __( 'This controls the format of the title tag for your Home Page.
The following macros are supported:', 'all-in-one-seo-pack' ) - . '
  • ' . __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%page_title% - The original title of the page', 'all-in-one-seo-pack' ) . '
  • ' . - __( "%page_author_login% - This page's author' login", 'all-in-one-seo-pack' ) . '
  • ' . - __( "%page_author_nicename% - This page's author' nicename", 'all-in-one-seo-pack' ) . '
  • ' . - __( "%page_author_firstname% - This page's author' first name (capitalized)", 'all-in-one-seo-pack' ) . '
  • ' . - __( "%page_author_lastname% - This page's author' last name (capitalized)", 'all-in-one-seo-pack' ) . '
  • ' . - __( '%current_date% - The current date (localized)', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%cf_fieldname% - Custom field name', 'all-in-one-seo-pack' ) . '
', - 'page_title_format' => - __( 'This controls the format of the title tag for Pages.
The following macros are supported:', 'all-in-one-seo-pack' ) - . '
  • ' . __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%page_title% - The original title of the page', 'all-in-one-seo-pack' ) . '
  • ' . - __( "%page_author_login% - This page's author' login", 'all-in-one-seo-pack' ) . '
  • ' . - __( "%page_author_nicename% - This page's author' nicename", 'all-in-one-seo-pack' ) . '
  • ' . - __( "%page_author_firstname% - This page's author' first name (capitalized)", 'all-in-one-seo-pack' ) . '
  • ' . - __( "%page_author_lastname% - This page's author' last name (capitalized)", 'all-in-one-seo-pack' ) . '
  • ' . - __( '%current_date% - The current date (localized)', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%post_date% - The date the page was published (localized)', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%post_year% - The year the page was published (localized)', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%post_month% - The month the page was published (localized)', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%cf_fieldname% - Custom field name', 'all-in-one-seo-pack' ) . '
', - 'post_title_format' => - __( 'This controls the format of the title tag for Posts.
The following macros are supported:', 'all-in-one-seo-pack' ) - . '
  • ' . __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%post_title% - The original title of the post', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%category_title% - The (main) category of the post', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%category% - Alias for %category_title%', 'all-in-one-seo-pack' ) . '
  • ' . - __( "%post_author_login% - This post's author' login", 'all-in-one-seo-pack' ) . '
  • ' . - __( "%post_author_nicename% - This post's author' nicename", 'all-in-one-seo-pack' ) . '
  • ' . - __( "%post_author_firstname% - This post's author' first name (capitalized)", 'all-in-one-seo-pack' ) . '
  • ' . - __( "%post_author_lastname% - This post's author' last name (capitalized)", 'all-in-one-seo-pack' ) . '
  • ' . - __( '%current_date% - The current date (localized)', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%post_date% - The date the post was published (localized)', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%post_year% - The year the post was published (localized)', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%post_month% - The month the post was published (localized)', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%cf_fieldname% - Custom field name', 'all-in-one-seo-pack' ) . '
', - 'category_title_format' => - __( 'This controls the format of the title tag for Category Archives.
The following macros are supported:', 'all-in-one-seo-pack' ) . - '
  • ' . __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%category_title% - The original title of the category', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%category_description% - The description of the category', 'all-in-one-seo-pack' ) . '
', - 'archive_title_format' => - __( 'This controls the format of the title tag for Custom Post Archives.
The following macros are supported:', 'all-in-one-seo-pack' ) . - '
  • ' . __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%archive_title - The original archive title given by wordpress', 'all-in-one-seo-pack' ) . '
', - 'date_title_format' => - __( 'This controls the format of the title tag for Date Archives.
The following macros are supported:', 'all-in-one-seo-pack' ) . - '
  • ' . __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%date% - The original archive title given by wordpress, e.g. "2007" or "2007 August"', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%day% - The original archive day given by wordpress, e.g. "17"', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%month% - The original archive month given by wordpress, e.g. "August"', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%year% - The original archive year given by wordpress, e.g. "2007"', 'all-in-one-seo-pack' ) . '
', - 'author_title_format' => - __( 'This controls the format of the title tag for Author Archives.
The following macros are supported:', 'all-in-one-seo-pack' ) . - '
  • ' . __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%author% - The original archive title given by wordpress, e.g. "Steve" or "John Smith"', 'all-in-one-seo-pack' ) . '
', - 'tag_title_format' => - __( 'This controls the format of the title tag for Tag Archives.
The following macros are supported:', 'all-in-one-seo-pack' ) . - '
  • ' . __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%tag% - The name of the tag', 'all-in-one-seo-pack' ) . '
', - 'search_title_format' => - __( 'This controls the format of the title tag for the Search page.
The following macros are supported:', 'all-in-one-seo-pack' ) . - '
  • ' . __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%search% - What was searched for', 'all-in-one-seo-pack' ) . '
', - 'description_format' => __( 'This controls the format of Meta Descriptions.The following macros are supported:', 'all-in-one-seo-pack' ) . - '
  • ' . __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%description% - This outputs the description you write for each page/post or the autogenerated description, if you have that option enabled. Auto-generated descriptions are generated from the Post Excerpt, or the first 160 characters of the post content if there is no Post Excerpt.', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%post_title% - The original title of the post', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%wp_title% - The original WordPress title, e.g. post_title for posts', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%current_date% - The current date (localized)', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%post_date% - The date the page/post was published (localized)', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%post_year% - The year the page/post was published (localized)', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%post_month% - The month the page/post was published (localized)', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%cf_fieldname% - Custom field name', 'all-in-one-seo-pack' ) . '
', - '404_title_format' => __( 'This controls the format of the title tag for the 404 page.
The following macros are supported:', 'all-in-one-seo-pack' ) . - '
  • ' . __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%request_url% - The original URL path, like "/url-that-does-not-exist/"', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%request_words% - The URL path in human readable form, like "Url That Does Not Exist"', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%404_title% - Additional 404 title input', 'all-in-one-seo-pack' ) . '
', - 'paged_format' => __( 'This string gets appended/prepended to titles of paged index pages (like home or archive pages).', 'all-in-one-seo-pack' ) - . __( 'The following macros are supported:', 'all-in-one-seo-pack' ) - . '
  • ' . __( '%page% - The page number', 'all-in-one-seo-pack' ) . '
', - 'cpostactive' => __( 'Use these checkboxes to select which Content Types you want to use All in One SEO Pack with.', 'all-in-one-seo-pack' ), - 'taxactive' => __( 'Use these checkboxes to select which Taxonomies you want to use All in One SEO Pack with.', 'all-in-one-seo-pack' ), - 'posttypecolumns' => __( 'This lets you select which screens display the SEO Title, SEO Keywords and SEO Description columns.', 'all-in-one-seo-pack' ), - 'google_verify' => __( "Enter your verification code here to verify your site with Google Search Console.
Click here for documentation on this setting", 'all-in-one-seo-pack' ), - 'bing_verify' => __( "Enter your verification code here to verify your site with Bing Webmaster Tools.
Click here for documentation on this setting", 'all-in-one-seo-pack' ), - 'pinterest_verify' => __( "Enter your verification code here to verify your site with Pinterest.
Click here for documentation on this setting", 'all-in-one-seo-pack' ), - 'google_publisher' => __( 'Enter your Google+ Profile URL here to add the rel=“author” tag to your site for Google authorship. It is recommended that the URL you enter here should be your personal Google+ profile. Use the Advanced Authorship Options below if you want greater control over the use of authorship.', 'all-in-one-seo-pack' ), - 'google_disable_profile' => __( 'Check this to remove the Google Plus field from the user profile screen.', 'all-in-one-seo-pack' ), - 'google_author_advanced' => __( 'Enable this to display advanced options for controlling Google Plus authorship information on your website.', 'all-in-one-seo-pack' ), - 'google_author_location' => __( 'This option allows you to control which types of pages you want to display rel=\"author\" on for Google authorship. The options include the Front Page (the homepage of your site), Posts, Pages, and any Custom Post Types. The Everywhere Else option includes 404, search, categories, tags, custom taxonomies, date archives, author archives and any other page template.', 'all-in-one-seo-pack' ), - 'google_enable_publisher' => __( 'This option allows you to control whether rel=\"publisher\" is displayed on the homepage of your site. Google recommends using this if the site is a business website.', 'all-in-one-seo-pack' ), - 'google_specify_publisher' => __( 'The Google+ profile you enter here will appear on your homepage only as the rel=\"publisher\" tag. It is recommended that the URL you enter here should be the Google+ profile for your business.', 'all-in-one-seo-pack' ), - 'google_sitelinks_search' => __( 'Add markup to display the Google Sitelinks Search Box next to your search results in Google.', 'all-in-one-seo-pack' ), - 'google_set_site_name' => __( 'Add markup to tell Google the preferred name for your website.', 'all-in-one-seo-pack' ), - 'google_connect' => __( 'Press the connect button to connect with Google Analytics; or if already connected, press the disconnect button to disable and remove any stored analytics credentials.', 'all-in-one-seo-pack' ), - 'google_analytics_id' => __( 'Enter your Google Analytics ID here to track visitor behavior on your site using Google Analytics.', 'all-in-one-seo-pack' ), - 'ga_advanced_options' => __( 'Check to use advanced Google Analytics options.', 'all-in-one-seo-pack' ), - 'ga_domain' => __( 'Enter your domain name without the http:// to set your cookie domain.', 'all-in-one-seo-pack' ), - 'ga_multi_domain' => __( 'Use this option to enable tracking of multiple or additional domains.', 'all-in-one-seo-pack' ), - 'ga_addl_domains' => __( 'Add a list of additional domains to track here. Enter one domain name per line without the http://.', 'all-in-one-seo-pack' ), - 'ga_anonymize_ip' => __( 'This enables support for IP Anonymization in Google Analytics.', 'all-in-one-seo-pack' ), - 'ga_display_advertising' => __( 'This enables support for the Display Advertiser Features in Google Analytics.', 'all-in-one-seo-pack' ), - 'ga_exclude_users' => __( 'Exclude logged-in users from Google Analytics tracking by role.', 'all-in-one-seo-pack' ), - 'ga_track_outbound_links' => __( 'Check this if you want to track outbound links with Google Analytics.', 'all-in-one-seo-pack' ), - 'ga_link_attribution' => __( 'This enables support for the Enhanced Link Attribution in Google Analytics.', 'all-in-one-seo-pack' ), - 'ga_enhanced_ecommerce' => __( 'This enables support for the Enhanced Ecommerce in Google Analytics.', 'all-in-one-seo-pack' ), - 'cpostnoindex' => __( 'Set the default NOINDEX setting for each Post Type.', 'all-in-one-seo-pack' ), - 'cpostnofollow' => __( 'Set the default NOFOLLOW setting for each Post Type.', 'all-in-one-seo-pack' ), - - 'category_noindex' => __( 'Check this to ask search engines not to index Category Archives. Useful for avoiding duplicate content.', 'all-in-one-seo-pack' ), - 'archive_date_noindex' => __( 'Check this to ask search engines not to index Date Archives. Useful for avoiding duplicate content.', 'all-in-one-seo-pack' ), - 'archive_author_noindex' => __( 'Check this to ask search engines not to index Author Archives. Useful for avoiding duplicate content.', 'all-in-one-seo-pack' ), - 'tags_noindex' => __( 'Check this to ask search engines not to index Tag Archives. Useful for avoiding duplicate content.', 'all-in-one-seo-pack' ), - 'search_noindex' => __( 'Check this to ask search engines not to index the Search page. Useful for avoiding duplicate content.', 'all-in-one-seo-pack' ), - '404_noindex' => __( 'Check this to ask search engines not to index the 404 page.', 'all-in-one-seo-pack' ), - 'tax_noindex' => __( 'Check this to ask search engines not to index custom Taxonomy archive pages. Useful for avoiding duplicate content.', 'all-in-one-seo-pack' ), - 'paginated_noindex' => __( 'Check this to ask search engines not to index paginated pages/posts. Useful for avoiding duplicate content.', 'all-in-one-seo-pack' ), - 'paginated_nofollow' => __( 'Check this to ask search engines not to follow links from paginated pages/posts. Useful for avoiding duplicate content.', 'all-in-one-seo-pack' ), - 'skip_excerpt' => __( 'This option will auto generate your meta descriptions from your post content instead of your post excerpt. This is useful if you want to use your content for your autogenerated meta descriptions instead of the excerpt. WooCommerce users should read the documentation regarding this setting.', 'all-in-one-seo-pack' ), - 'generate_descriptions' => __( 'Check this and your Meta Descriptions for any Post Type will be auto-generated using the Post Excerpt, or the first 160 characters of the post content if there is no Post Excerpt. You can overwrite any auto-generated Meta Description by editing the post or page.', 'all-in-one-seo-pack' ), - 'run_shortcodes' => __( 'Check this and shortcodes will get executed for descriptions auto-generated from content.', 'all-in-one-seo-pack' ), - 'hide_paginated_descriptions' => __( 'Check this and your Meta Descriptions will be removed from page 2 or later of paginated content.', 'all-in-one-seo-pack' ), - 'dont_truncate_descriptions' => __( 'Check this to prevent your Description from being truncated regardless of its length.', 'all-in-one-seo-pack' ), - 'schema_markup' => __( 'Check this to support Schema.org markup, i.e., itemprop on supported metadata.', 'all-in-one-seo-pack' ), - 'unprotect_meta' => __( "Check this to unprotect internal postmeta fields for use with XMLRPC. If you don't know what that is, leave it unchecked.", 'all-in-one-seo-pack' ), - 'redirect_attachement_parent' => __( 'Redirect attachment pages to post parent.', 'all-in-one-seo-pack' ), - 'ex_pages' => __( 'Enter a comma separated list of pages here to be excluded by All in One SEO Pack. This is helpful when using plugins which generate their own non-WordPress dynamic pages. Ex: /forum/, /contact/ For instance, if you want to exclude the virtual pages generated by a forum plugin, all you have to do is add forum or /forum or /forum/ or and any URL with the word \"forum\" in it, such as http://mysite.com/forum or http://mysite.com/forum/someforumpage here and it will be excluded from All in One SEO Pack.', 'all-in-one-seo-pack' ), - 'post_meta_tags' => __( 'What you enter here will be copied verbatim to the header of all Posts. You can enter whatever additional headers you want here, even references to stylesheets.', 'all-in-one-seo-pack' ), - 'page_meta_tags' => __( 'What you enter here will be copied verbatim to the header of all Pages. You can enter whatever additional headers you want here, even references to stylesheets.', 'all-in-one-seo-pack' ), - 'front_meta_tags' => __( 'What you enter here will be copied verbatim to the header of the front page if you have set a static page in Settings, Reading, Front Page Displays. You can enter whatever additional headers you want here, even references to stylesheets. This will fall back to using Additional Page Headers if you have them set and nothing is entered here.', 'all-in-one-seo-pack' ), - 'home_meta_tags' => __( 'What you enter here will be copied verbatim to the header of the home page if you have Front page displays your latest posts selected in Settings, Reading.  It will also be copied verbatim to the header on the Posts page if you have one set in Settings, Reading. You can enter whatever additional headers you want here, even references to stylesheets.', 'all-in-one-seo-pack' ), - ); - // @codingStandardsIgnoreStop - - $this->help_anchors = array( - 'license_key' => '#license-key', - 'can' => '#canonical-urls', - 'no_paged_canonical_links' => '#no-pagination-for-canonical-urls', - 'customize_canonical_links' => '#enable-custom-canonical-urls', - 'use_original_title' => '#use-original-title', - 'schema_markup' => '#use-schema-markup', - 'do_log' => '#log-important-events', - 'home_title' => '#home-title', - 'home_description' => '#home-description', - 'home_keywords' => '#home-keywords', - 'use_static_home_info' => '#use-static-front-page-instead', - 'togglekeywords' => '#use-keywords', - 'use_categories' => '#use-categories-for-meta-keywords', - 'use_tags_as_keywords' => '#use-tags-for-meta-keywords', - 'dynamic_postspage_keywords' => '#dynamically-generate-keywords-for-posts-page', - 'rewrite_titles' => '#rewrite-titles', - 'home_page_title_format' => '#title-format-fields', - 'page_title_format' => '#title-format-fields', - 'post_title_format' => '#title-format-fields', - 'category_title_format' => '#title-format-fields', - 'archive_title_format' => '#title-format-fields', - 'date_title_format' => '#title-format-fields', - 'author_title_format' => '#title-format-fields', - 'tag_title_format' => '#title-format-fields', - 'search_title_format' => '#title-format-fields', - 'description_format' => '#title-format-fields', - '404_title_format' => '#title-format-fields', - 'paged_format' => '#title-format-fields', - 'cpostactive' => '#seo-on-only-these-post-types', - 'taxactive' => '#seo-on-only-these-taxonomies', - 'posttypecolumns' => '#show-column-labels-for-custom-post-types', - 'google_verify' => '', - 'bing_verify' => '', - 'pinterest_verify' => '', - 'google_publisher' => '#google-plus-default-profile', - 'google_disable_profile' => '#disable-google-plus-profile', - 'google_sitelinks_search' => '#display-sitelinks-search-box', - 'google_set_site_name' => '#set-preferred-site-name', - 'google_author_advanced' => '#advanced-authorship-options', - 'google_author_location' => '#display-google-authorship', - 'google_enable_publisher' => '#display-publisher-meta-on-front-page', - 'google_specify_publisher' => '#specify-publisher-url', - 'google_analytics_id' => 'https://semperplugins.com/documentation/setting-up-google-analytics/', - 'ga_domain' => '#tracking-domain', - 'ga_multi_domain' => '#track-multiple-domains-additional-domains', - 'ga_addl_domains' => '#track-multiple-domains-additional-domains', - 'ga_anonymize_ip' => '#anonymize-ip-addresses', - 'ga_display_advertising' => '#display-advertiser-tracking', - 'ga_exclude_users' => '#exclude-users-from-tracking', - 'ga_track_outbound_links' => '#track-outbound-links', - 'ga_link_attribution' => '#enhanced-link-attribution', - 'ga_enhanced_ecommerce' => '#enhanced-ecommerce', - 'cpostnoindex' => '#noindex', - 'cpostnofollow' => '#nofollow', - 'category_noindex' => '#noindex-settings', - 'archive_date_noindex' => '#noindex-settings', - 'archive_author_noindex' => '#noindex-settings', - 'tags_noindex' => '#noindex-settings', - 'search_noindex' => '#use-noindex-for-the-search-page', - '404_noindex' => '#use-noindex-for-the-404-page', - 'tax_noindex' => '#use-noindex-for-the-taxonomy-archives', - 'paginated_noindex' => '#use-noindex-for-paginated-pages-posts', - 'paginated_nofollow' => '#use-nofollow-for-paginated-pages-posts', - 'skip_excerpt' => '#avoid-using-the-excerpt-in-descriptions', - 'generate_descriptions' => '#autogenerate-descriptions', - 'run_shortcodes' => '#run-shortcodes-in-autogenerated-descriptions', - 'hide_paginated_descriptions' => '#remove-descriptions-for-paginated-pages', - 'dont_truncate_descriptions' => '#never-shorten-long-descriptions', - 'unprotect_meta' => '#unprotect-post-meta-fields', - 'redirect_attachement_parent' => '#redirect-attachments-to-post-parent', - 'ex_pages' => '#exclude-pages', - 'post_meta_tags' => '#additional-post-headers', - 'page_meta_tags' => '#additional-page-headers', - 'front_meta_tags' => '#additional-front-page-headers', - 'home_meta_tags' => '#additional-blog-page-headers', - 'snippet' => '#preview-snippet', - 'title' => '#title', - 'description' => '#description', - 'keywords' => '#keywords', - 'custom_link' => '#custom-canonical-url', - 'noindex' => '#robots-meta-noindex', - 'nofollow' => '#robots-meta-nofollow', - 'sitemap_exclude' => '#exclude-from-sitemap', - 'disable' => '#disable-on-this-post', - 'disable_analytics' => '#disable-google-analytics', - ); - - $meta_help_text = array( - 'snippet' => __( 'A preview of what this page might look like in search engine results.', 'all-in-one-seo-pack' ), - 'title' => __( 'A custom title that shows up in the title tag for this page.', 'all-in-one-seo-pack' ), - 'description' => __( 'The META description for this page. This will override any autogenerated descriptions.', 'all-in-one-seo-pack' ), - 'keywords' => __( 'A comma separated list of your most important keywords for this page that will be written as META keywords.', 'all-in-one-seo-pack' ), - 'custom_link' => __( 'Override the canonical URLs for this post.', 'all-in-one-seo-pack' ), - 'noindex' => __( 'Check this box to ask search engines not to index this page.', 'all-in-one-seo-pack' ), - 'nofollow' => __( 'Check this box to ask search engines not to follow links from this page.', 'all-in-one-seo-pack' ), - 'sitemap_exclude' => __( "Don't display this page in the sitemap.", 'all-in-one-seo-pack' ), - 'disable' => __( 'Disable SEO on this page.', 'all-in-one-seo-pack' ), - 'disable_analytics' => __( 'Disable Google Analytics on this page.', 'all-in-one-seo-pack' ), - ); - $this->default_options = array( 'license_key' => array( 'name' => __( 'License Key:', 'all-in-one-seo-pack' ), @@ -966,12 +689,6 @@ function __construct() { ), ); - if ( ! empty( $meta_help_text ) ) { - foreach ( $meta_help_text as $k => $v ) { - $this->locations['aiosp']['default_options'][ $k ]['help_text'] = $v; - } - } - $this->layout = array( 'default' => array( 'name' => __( 'General Settings', 'all-in-one-seo-pack' ), @@ -1095,7 +812,6 @@ function __construct() { if ( AIOSEOPPRO ) { // Add Pro options. $this->default_options = aioseop_add_pro_opt( $this->default_options ); - $this->help_text = aioseop_add_pro_help( $this->help_text ); $this->layout = aioseop_add_pro_layout( $this->layout ); } @@ -1111,7 +827,6 @@ function __construct() { $this->layout['default']['options'] = array_diff( array_keys( $this->default_options ), $other_options ); if ( is_admin() ) { - $this->add_help_text_links(); add_action( 'aioseop_global_settings_header', array( $this, 'display_right_sidebar' ) ); add_action( 'aioseop_global_settings_footer', array( $this, 'display_settings_footer' ) ); add_action( 'output_option', array( $this, 'custom_output_option' ), 10, 2 ); @@ -3196,28 +2911,6 @@ function add_page_hooks() { 'aiosp_cpostactive\[\]' => $p, ), ); - $this->help_text[ $field ] = __( 'The following macros are supported:', 'all-in-one-seo-pack' ) - . '
  • ' . __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%post_title% - The original title of the post.', 'all-in-one-seo-pack' ) . '
  • '; - $taxes = get_object_taxonomies( $p, 'objects' ); - if ( ! empty( $taxes ) ) { - foreach ( $taxes as $n => $t ) { - $this->help_text[ $field ] .= sprintf( __( "%%tax_%1\$s%% - This post's associated %2\$s taxonomy title", 'all-in-one-seo-pack' ), $n, $t->label ) . '
  • '; - } - } - $this->help_text[ $field ] .= - __( "%post_author_login% - This post's author' login", 'all-in-one-seo-pack' ) . '
  • ' . - __( "%post_author_nicename% - This post's author' nicename", 'all-in-one-seo-pack' ) . '
  • ' . - __( "%post_author_firstname% - This post's author' first name (capitalized)", 'all-in-one-seo-pack' ) . '
  • ' . - __( "%post_author_lastname% - This post's author' last name (capitalized)", 'all-in-one-seo-pack' ) . '
  • ' . - __( '%current_date% - The current date (localized)', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%post_date% - The date the post was published (localized)', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%post_year% - The year the post was published (localized)', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%post_month% - The month the post was published (localized)', 'all-in-one-seo-pack' ) . '
  • ' . - '
' . - ''; - $this->help_anchors[ $field ] = '#custom-titles'; $this->layout['cpt']['options'][] = $field; } } @@ -3250,18 +2943,11 @@ function add_page_hooks() { 'aiosp_taxactive\[\]' => $p, ), ); - $this->help_text[ $field ] = __( 'The following macros are supported:', 'all-in-one-seo-pack' ) . - '
  • ' . __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%taxonomy_title% - The original title of the taxonomy', 'all-in-one-seo-pack' ) . '
  • ' . - __( '%taxonomy_description% - The description of the taxonomy', 'all-in-one-seo-pack' ) . '
'; - $this->help_anchors[ $field ] = '#custom-titles'; $this->layout['cpt']['options'][] = $field; } } } $this->setting_options(); - $this->add_help_text_links(); if ( AIOSEOPPRO ) { global $aioseop_update_checker; diff --git a/css/modules/aioseop_module.css b/css/modules/aioseop_module.css index 3889834e5..d8788722f 100644 --- a/css/modules/aioseop_module.css +++ b/css/modules/aioseop_module.css @@ -136,12 +136,13 @@ div.aioseop_tip_icon:before { font-weight: bold; line-height: 19px; display: inline-block; + float: left; text-align: left; - position: absolute; font-family: 'Open Sans', sans-serif; width: 26%; min-width: 120px; max-width: 230px; + cursor: default; } .aioseop_option_div { diff --git a/js/aioseop-helper.js b/js/aioseop-helper.js new file mode 100644 index 000000000..070743d10 --- /dev/null +++ b/js/aioseop-helper.js @@ -0,0 +1,56 @@ +/** + * Use for JavaScript compatability by using anonymous functions; which + * are loaded into the footer. + * + * @summary AIOSEOP Footer JS + * + * @since 2.4.2 + */ +(function($) { + /** + * jQuery UI Tooltips + * + * Initiates the jQuery UI Tooltips on the admin pages with the class and + * title attributes set properly. + * + * @since 2.4.1.1 + * + * @link http://api.jqueryui.com/tooltip/ + */ + function aioseopTooltips() { + $( ".aioseop_help_text_link" ).tooltip({ + open: function( event, ui ) { + ui.tooltip.css( "min-width", "170px" ); + ui.tooltip.css( "max-width", "396px" ); + + if ( 'undefined' === typeof( event.originalEvent ) ) { + return false; + } + + var $id = $( ui.tooltip ).attr( 'id' ); + + // Close any lingering tooltips. + $( 'div.ui-tooltip' ).not( '#' + $id ).remove(); + + // AJAX function to pull in data and add it to the tooltip goes here. + }, + close: function( event, ui ) { + ui.tooltip.hover( + function() { + $( this ).stop( true ).fadeTo( 400, 1 ); + }, + function() { + $( this ).fadeOut( '400', function() { + $( this ).remove(); + }); + } + ); + }, + content: function( callback ) { + callback( $( this ).prop( "title" ) ); + } + }); + } + + aioseopTooltips(); +}(jQuery)); diff --git a/js/aioseop-helper.min.js b/js/aioseop-helper.min.js new file mode 100644 index 000000000..c182cbbfc --- /dev/null +++ b/js/aioseop-helper.min.js @@ -0,0 +1 @@ +!function(n){n(".aioseop_help_text_link").tooltip({open:function(t,o){if(o.tooltip.css("min-width","170px"),o.tooltip.css("max-width","396px"),void 0===t.originalEvent)return!1;var i=n(o.tooltip).attr("id");n("div.ui-tooltip").not("#"+i).remove()},close:function(t,o){o.tooltip.hover(function(){n(this).stop(!0).fadeTo(400,1)},function(){n(this).fadeOut("400",function(){n(this).remove()})})},content:function(t){t(n(this).prop("title"))}})}(jQuery); \ No newline at end of file diff --git a/modules/aioseop_bad_robots.php b/modules/aioseop_bad_robots.php index 47e4b9908..ba5020159 100644 --- a/modules/aioseop_bad_robots.php +++ b/modules/aioseop_bad_robots.php @@ -19,16 +19,6 @@ function __construct() { $this->file = __FILE__; // The current file. parent::__construct(); - $help_text = array( - 'block_bots' => __( 'Block requests from user agents that are known to misbehave with 503.', 'all-in-one-seo-pack' ), - 'block_refer' => __( 'Block Referral Spam using HTTP.', 'all-in-one-seo-pack' ), - 'track_blocks' => __( 'Log and show recent requests from blocked bots.', 'all-in-one-seo-pack' ), - 'edit_blocks' => __( 'Check this to edit the list of disallowed user agents for blocking bad bots.', 'all-in-one-seo-pack' ), - 'blocklist' => __( 'This is the list of disallowed user agents used for blocking bad bots.', 'all-in-one-seo-pack' ), - 'referlist' => __( 'This is the list of disallowed referers used for blocking bad bots.', 'all-in-one-seo-pack' ), - 'blocked_log' => __( 'Shows log of most recent requests from blocked bots. Note: this will not track any bots that were already blocked at the web server / .htaccess level.', 'all-in-one-seo-pack' ), - ); - $this->default_options = array( 'block_bots' => array( 'name' => __( 'Block Bad Bots using HTTP', 'all-in-one-seo-pack' ) ), 'block_refer' => array( 'name' => __( 'Block Referral Spam using HTTP', 'all-in-one-seo-pack' ) ), @@ -67,12 +57,6 @@ function __construct() { ), ); - if ( ! empty( $help_text ) ) { - foreach ( $help_text as $k => $v ) { - $this->default_options[ $k ]['help_text'] = $v; - } - } - add_filter( $this->prefix . 'display_options', array( $this, 'filter_display_options' ) ); // Load initial options / set defaults, diff --git a/modules/aioseop_file_editor.php b/modules/aioseop_file_editor.php index 7454a4b78..955177f75 100644 --- a/modules/aioseop_file_editor.php +++ b/modules/aioseop_file_editor.php @@ -25,9 +25,6 @@ function __construct() { $this->current_tab = $_REQUEST['tab']; } - $help_text = array( - 'htaccfile' => __( '.htaccess editor', 'all-in-one-seo-pack' ), - ); $this->default_options = array( 'htaccfile' => array( 'name' => __( 'Edit .htaccess', 'all-in-one-seo-pack' ), @@ -40,11 +37,6 @@ function __construct() { ), ); - if ( ! empty( $help_text ) ) { - foreach ( $help_text as $k => $v ) { - $this->default_options[ $k ]['help_text'] = $v; - } - } $this->tabs = array( 'htaccess' => array( 'name' => __( '.htaccess' ) ), ); diff --git a/modules/aioseop_importer_exporter.php b/modules/aioseop_importer_exporter.php index 1aeae9ccc..534218ec6 100644 --- a/modules/aioseop_importer_exporter.php +++ b/modules/aioseop_importer_exporter.php @@ -17,20 +17,6 @@ function __construct() { $this->prefix = 'aiosp_importer_exporter_'; // option prefix $this->file = __FILE__; parent::__construct(); - $help_text = array( - 'import_submit' => __( - "Select a valid All in One SEO Pack ini file and click 'Import' to import options from a previous state or install of All in One SEO Pack.
Click here for documentation on this setting", - 'all-in-one-seo-pack' - ), - 'export_choices' => __( - "You may choose to export settings from active modules, and content from post data.
Click here for documentation on this setting", - 'all-in-one-seo-pack' - ), - 'export_post_types' => __( - "Select which Post Types you want to export your All in One SEO Pack meta data for.
Click here for documentation on this setting", - 'all-in-one-seo-pack' - ), - ); $this->warnings = array(); $this->default_options = array( 'import_submit' => array( @@ -70,11 +56,6 @@ function __construct() { ) . '
', ), ); - if ( ! empty( $help_text ) ) { - foreach ( $help_text as $k => $v ) { - $this->default_options[ $k ]['help_text'] = $v; - } - } $this->layout = array( 'default' => array( 'name' => $this->name, diff --git a/modules/aioseop_opengraph.php b/modules/aioseop_opengraph.php index d83ac95ee..e1af5968c 100644 --- a/modules/aioseop_opengraph.php +++ b/modules/aioseop_opengraph.php @@ -81,103 +81,6 @@ function __construct() { ); parent::__construct(); - $this->help_text = array( - 'setmeta' => __( 'Checking this box will use the Home Title and Home Description set in All in One SEO Pack, General Settings as the Open Graph title and description for your home page.', 'all-in-one-seo-pack' ), - 'key' => __( 'Enter your Facebook Admin ID here. You can enter multiple IDs separated by a comma. You can look up your Facebook ID using this tool http://findmyfbid.com/', 'all-in-one-seo-pack' ), - 'appid' => __( 'Enter your Facebook App ID here. Information about how to get your Facebook App ID can be found at https://developers.facebook.com/docs/apps/register', 'all-in-one-seo-pack' ), - 'title_shortcodes' => __( 'Run shortcodes that appear in social title meta tags.', 'all-in-one-seo-pack' ), - 'description_shortcodes' => __( 'Run shortcodes that appear in social description meta tags.', 'all-in-one-seo-pack' ), - 'sitename' => __( 'The Site Name is the name that is used to identify your website.', 'all-in-one-seo-pack' ), - 'hometitle' => __( 'The Home Title is the Open Graph title for your home page.', 'all-in-one-seo-pack' ), - 'description' => __( 'The Home Description is the Open Graph description for your home page.', 'all-in-one-seo-pack' ), - 'homeimage' => __( 'The Home Image is the Open Graph image for your home page.', 'all-in-one-seo-pack' ), - 'generate_descriptions' => __( 'This option will auto generate your Open Graph descriptions from your post content instead of your post excerpt. WooCommerce users should read the documentation regarding this setting.', 'all-in-one-seo-pack' ), - 'defimg' => __( 'This option lets you choose which image will be displayed by default for the Open Graph image. You may override this on individual posts.', 'all-in-one-seo-pack' ), - 'fallback' => __( 'This option lets you fall back to the default image if no image could be found above.', 'all-in-one-seo-pack' ), - 'dimg' => __( 'This option sets a default image that can be used for the Open Graph image. You can upload an image, select an image from your Media Library or paste the URL of an image here.', 'all-in-one-seo-pack' ), - 'dimgwidth' => __( 'This option lets you set a default width for your images, where unspecified.', 'all-in-one-seo-pack' ), - 'dimgheight' => __( 'This option lets you set a default height for your images, where unspecified.', 'all-in-one-seo-pack' ), - 'meta_key' => __( 'Enter the name of a custom field (or multiple field names separated by commas) to use that field to specify the Open Graph image on Pages or Posts.', 'all-in-one-seo-pack' ), - 'image' => __( 'This option lets you select the Open Graph image that will be used for this Page or Post, overriding the default settings.', 'all-in-one-seo-pack' ), - 'customimg' => __( 'This option lets you upload an image to use as the Open Graph image for this Page or Post.', 'all-in-one-seo-pack' ), - 'imagewidth' => __( 'Enter the width for your Open Graph image in pixels (i.e. 600).', 'all-in-one-seo-pack' ), - 'imageheight' => __( 'Enter the height for your Open Graph image in pixels (i.e. 600).', 'all-in-one-seo-pack' ), - 'video' => __( 'This option lets you specify a link to the Open Graph video used on this Page or Post.', 'all-in-one-seo-pack' ), - 'videowidth' => __( 'Enter the width for your Open Graph video in pixels (i.e. 600).', 'all-in-one-seo-pack' ), - 'videoheight' => __( 'Enter the height for your Open Graph video in pixels (i.e. 600).', 'all-in-one-seo-pack' ), - 'defcard' => __( 'Select the default type of Twitter Card to display.', 'all-in-one-seo-pack' ), - 'setcard' => __( 'Select the Twitter Card type to use for this Page or Post, overriding the default setting.', 'all-in-one-seo-pack' ), - 'twitter_site' => __( 'Enter the Twitter username associated with your website here.', 'all-in-one-seo-pack' ), - 'twitter_creator' => __( 'Allows your authors to be identified by their Twitter usernames as content creators on the Twitter cards for their posts.', 'all-in-one-seo-pack' ), - 'twitter_domain' => __( 'Enter the name of your website here.', 'all-in-one-seo-pack' ), - 'customimg_twitter' => __( 'This option lets you upload an image to use as the Twitter image for this Page or Post.', 'all-in-one-seo-pack' ), - 'gen_tags' => __( 'Automatically generate article tags for Facebook type article when not provided.', 'all-in-one-seo-pack' ), - 'gen_keywords' => __( 'Use keywords in generated article tags.', 'all-in-one-seo-pack' ), - 'gen_categories' => __( 'Use categories in generated article tags.', 'all-in-one-seo-pack' ), - 'gen_post_tags' => __( 'Use post tags in generated article tags.', 'all-in-one-seo-pack' ), - 'types' => __( 'Select which Post Types you want to use All in One SEO Pack to set Open Graph meta values for.', 'all-in-one-seo-pack' ), - 'title' => __( 'This is the Open Graph title of this Page or Post.', 'all-in-one-seo-pack' ), - 'desc' => __( 'This is the Open Graph description of this Page or Post.', 'all-in-one-seo-pack' ), - 'category' => __( 'Select the Open Graph type that best describes the content of this Page or Post.', 'all-in-one-seo-pack' ), - 'facebook_debug' => __( 'Press this button to have Facebook re-fetch and debug this page.', 'all-in-one-seo-pack' ), - 'section' => __( 'This Open Graph meta allows you to add a general section name that best describes this content.', 'all-in-one-seo-pack' ), - 'tag' => __( 'This Open Graph meta allows you to add a list of keywords that best describe this content.', 'all-in-one-seo-pack' ), - 'facebook_publisher' => __( 'Link articles to the Facebook page associated with your website.', 'all-in-one-seo-pack' ), - 'facebook_author' => __( 'Allows your authors to be identified by their Facebook pages as content authors on the Opengraph meta for their articles.', 'all-in-one-seo-pack' ), - 'person_or_org' => __( 'Are the social profile links for your website for a person or an organization?', 'all-in-one-seo-pack' ), - 'profile_links' => __( "Add URLs for your website's social profiles here (Facebook, Twitter, Google+, Instagram, LinkedIn), one per line.", 'all-in-one-seo-pack' ), - 'social_name' => __( 'Add the name of the person or organization who owns these profiles.', 'all-in-one-seo-pack' ), - ); - - $this->help_anchors = array( - 'title_shortcodes' => '#run-shortcodes-in-title', - 'description_shortcodes' => '#run-shortcodes-in-description', - 'generate_descriptions' => '#auto-generate-og-descriptions', - 'setmeta' => '#use-aioseo-title-and-description', - 'sitename' => '#site-name', - 'hometitle' => '#home-title-and-description', - 'description' => '#home-title-and-description', - 'homeimage' => '#home-image', - 'defimg' => '#select-og-image-source', - 'fallback' => '#use-default-if-no-image-found', - 'dimg' => '#default-og-image', - 'dimgwidth' => '#default-image-width', - 'dimgheight' => '#default-image-height', - 'meta_key' => '#use-custom-field-for-image', - 'profile_links' => '#social-profile-links', - 'person_or_org' => '#social-profile-links', - 'social_name' => '#social-profile-links', - 'key' => '#facebook-admin-id', - 'appid' => '#facebook-app-id', - 'gen_tags' => '#automatically-generate-article-tags', - 'gen_keywords' => '#use-keywords-in-article-tags', - 'gen_categories' => '#use-categories-in-article-tags', - 'gen_post_tags' => '#use-post-tags-in-article-tags', - 'facebook_publisher' => '#show-facebook-publisher-on-articles', - 'facebook_author' => '#show-facebook-author-on-articles', - 'types' => '#enable-facebook-meta-for', - 'defcard' => '#default-twitter-card', - 'twitter_site' => '#twitter-site', - 'twitter_creator' => '#show-twitter-author', - 'twitter_domain' => '#twitter-domain', - 'scan_header' => '#scan-social-meta', - 'title' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#title', - 'desc' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#description', - 'image' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#image', - 'customimg' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#custom-image', - 'imagewidth' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#specify-image-width-height', - 'imageheight' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#specify-image-width-height', - 'video' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#custom-video', - 'videowidth' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#specify-video-width-height', - 'videoheight' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#specify-video-width-height', - 'category' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#facebook-object-type', - 'facebook_debug' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#facebook-debug', - 'section' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#article-section', - 'tag' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#article-tags', - 'setcard' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#twitter-card-type', - 'customimg_twitter' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#custom-twitter-image', - ); - if ( is_admin() ) { add_action( 'admin_init', array( $this, 'admin_init' ), 5 ); } else { @@ -945,7 +848,6 @@ function filter_settings( $settings, $location, $current ) { if ( isset( $settings[ $prefix . $opt ] ) ) { $settings[ $prefix . $opt ]['type'] = 'hidden'; $settings[ $prefix . $opt ]['label'] = 'none'; - $settings[ $prefix . $opt ]['help_text'] = ''; unset( $settings[ $prefix . $opt ]['count'] ); } } @@ -1744,14 +1646,10 @@ function admin_init() { 'default' => 'article', 'condshow' => array( 'aiosp_opengraph_types\[\]' => $slug ), ); - $this->help_text[ $field ] = __( 'Choose a default value that best describes the content of your post type.', 'all-in-one-seo-pack' ); - $this->help_anchors[ $field ] = '#content-object-types'; $this->locations['opengraph']['options'][] = $field; $this->layout['facebook']['options'][] = $field; } $this->setting_options(); - $this->add_help_text_links(); - } function get_all_images( $options = null, $p = null ) { diff --git a/modules/aioseop_performance.php b/modules/aioseop_performance.php index 5d69ee5cd..7e15fc229 100644 --- a/modules/aioseop_performance.php +++ b/modules/aioseop_performance.php @@ -17,12 +17,6 @@ function __construct( $mod ) { $this->file = __FILE__; // The current file. parent::__construct(); - $this->help_text = array( - 'memory_limit' => __( 'This setting allows you to raise your PHP memory limit to a reasonable value. Note: WordPress core and other WordPress plugins may also change the value of the memory limit.', 'all-in-one-seo-pack' ), - 'execution_time' => __( 'This setting allows you to raise your PHP execution time to a reasonable value.', 'all-in-one-seo-pack' ), - 'force_rewrites' => __( 'Use output buffering to ensure that the title gets rewritten. Enable this option if you run into issues with the title tag being set by your theme or another plugin.', 'all-in-one-seo-pack' ), - ); - $this->default_options = array( 'memory_limit' => array( 'name' => __( 'Raise memory limit', 'all-in-one-seo-pack' ), @@ -51,12 +45,6 @@ function __construct( $mod ) { ), ); - $this->help_anchors = array( - 'memory_limit' => '#raise-memory-limit', - 'execution_time' => '#raise-execution-time', - 'force_rewrites' => '#force-rewrites', - ); - global $aiosp, $aioseop_options; if ( aioseop_option_isset( 'aiosp_rewrite_titles' ) && $aioseop_options['aiosp_rewrite_titles'] ) { $this->default_options['force_rewrites'] = array( @@ -91,8 +79,6 @@ function __construct( $mod ) { $this->default_options = array_merge( $this->default_options, $system_status ); - $this->add_help_text_links(); - add_filter( $this->prefix . 'display_options', array( $this, 'display_options_filter' ), 10, 2 ); add_filter( $this->prefix . 'update_options', array( $this, 'update_options_filter' ), 10, 2 ); add_action( $this->prefix . 'settings_update', array( $this, 'settings_update_action' ), 10, 2 ); diff --git a/modules/aioseop_robots.php b/modules/aioseop_robots.php index d4f6427c1..951355b94 100644 --- a/modules/aioseop_robots.php +++ b/modules/aioseop_robots.php @@ -21,12 +21,6 @@ function __construct() { $this->file = __FILE__; // the current file parent::__construct(); - $help_text = array( - 'type' => __( 'Rule Type', 'all-in-one-seo-pack' ), - 'agent' => __( 'User Agent', 'all-in-one-seo-pack' ), - 'path' => __( 'Directory Path', 'all-in-one-seo-pack' ), - ); - $this->default_options = array( 'usage' => array( 'type' => 'html', @@ -87,12 +81,6 @@ function __construct() { $this->default_options = array_merge( $this->default_options, $this->rule_fields ); - if ( ! empty( $help_text ) ) { - foreach ( $help_text as $k => $v ) { - $this->default_options[ $k ]['help_text'] = $v; - } - } - $this->layout = array( 'default' => array( 'name' => __( 'Create a Robots.txt File', 'all-in-one-seo-pack' ), diff --git a/modules/aioseop_sitemap.php b/modules/aioseop_sitemap.php index 0b66f3c43..0abe47c6b 100644 --- a/modules/aioseop_sitemap.php +++ b/modules/aioseop_sitemap.php @@ -168,48 +168,6 @@ public function __construct() { // TODO This could be move up to the class field default/initial values. $this->comment_string = 'Sitemap %s generated by All in One SEO Pack %s by Michael Torbert of Semper Fi Web Design on %s'; - $this->help_text = array( - 'rss_sitemap' => __( 'Create RSS Sitemap as well.', 'all-in-one-seo-pack' ), - 'daily_cron' => __( 'Notify search engines based on the selected schedule, and also update static sitemap daily if in use. (this uses WP-Cron, so make sure this is working properly on your server as well)', 'all-in-one-seo-pack' ), - 'indexes' => __( 'Organize sitemap entries into distinct files in your sitemap. Enable this only if your sitemap contains over 50,000 URLs or the file is over 5MB in size.', 'all-in-one-seo-pack' ), - 'max_posts' => __( 'Allows you to specify the maximum number of posts in a sitemap (up to 50,000).', 'all-in-one-seo-pack' ), - 'posttypes' => __( 'Select which Post Types appear in your sitemap.', 'all-in-one-seo-pack' ), - 'taxonomies' => __( 'Select which taxonomy archives appear in your sitemap', 'all-in-one-seo-pack' ), - 'archive' => __( 'Include Date Archives in your sitemap.', 'all-in-one-seo-pack' ), - 'author' => __( 'Include Author Archives in your sitemap.', 'all-in-one-seo-pack' ), - 'images' => __( 'Exclude Images in your sitemap.', 'all-in-one-seo-pack' ), - 'gzipped' => __( 'Create a compressed sitemap file in .xml.gz format.', 'all-in-one-seo-pack' ), - 'robots' => __( 'Places a link to your Sitemap.xml into your virtual Robots.txt file.', 'all-in-one-seo-pack' ), - 'rewrite' => __( 'Dynamically creates the XML sitemap instead of using a static file.', 'all-in-one-seo-pack' ), - 'addl_url' => __( 'URL to the page. This field accepts relative URLs or absolute URLs with the protocol specified.', 'all-in-one-seo-pack' ), - 'addl_prio' => __( 'The priority of the page.', 'all-in-one-seo-pack' ), - 'addl_freq' => __( 'The frequency of the page.', 'all-in-one-seo-pack' ), - 'addl_mod' => __( 'Last modified date of the page.', 'all-in-one-seo-pack' ), - 'excl_categories' => __( 'Entries from these categories will be excluded from the sitemap.', 'all-in-one-seo-pack' ), - 'excl_pages' => __( 'Use page slugs or page IDs, seperated by commas, to exclude pages from the sitemap.', 'all-in-one-seo-pack' ), - ); - - $this->help_anchors = array( - 'rss_sitemap' => '#create-rss_sitemap', - 'daily_cron' => '#schedule-updates', - 'indexes' => '#enable-sitemap-indexes', - 'max_posts' => '#enable-sitemap-indexes', - 'posttypes' => '#post-types-and-taxonomies', - 'taxonomies' => '#post-types-and-taxonomies', - 'archive' => '#include-archive-pages', - 'author' => '#include-archive-pages', - 'images' => '#exclude-images', - 'gzipped' => '#create-compressed-sitemap', - 'robots' => '#link-from-virtual-robots', - 'rewrite' => '#dynamically-generate-sitemap', - 'addl_url' => '#additional-pages', - 'addl_prio' => '#additional-pages', - 'addl_freq' => '#additional-pages', - 'addl_mod' => '#additional-pages', - 'excl_categories' => '#excluded-items', - 'excl_pages' => '#excluded-items', - ); - $this->default_options = array( 'rss_sitemap' => array( 'name' => __( 'Create RSS Sitemap', 'all-in-one-seo-pack' ) ), 'daily_cron' => array( @@ -325,8 +283,6 @@ public function __construct() { $arr[ $k . '_' . $opt ] = array( 'name' => $this->ucwords( $val ), - /* translators: Help Text string to display information about multiple different settings. */ - 'help_text' => sprintf( __( 'Manually set the %1$s of your %2$s.', 'all-in-one-seo-pack' ), $v, $val ), 'type' => 'select', 'initial_options' => $iopts, 'default' => 'no', @@ -428,8 +384,6 @@ public function __construct() { $this->default_options = array_merge( $status_options, $this->default_options, $addl_options, $excl_options, $prio_options, $freq_options ); - $this->add_help_text_links(); - add_action( 'after_doing_aioseop_updates', array( @@ -695,8 +649,6 @@ public function add_post_types() { $this->default_options['taxonomies']['default'] = array_keys( $this->default_options['taxonomies']['initial_options'] ); $this->default_options['excl_categories']['initial_options'] = $this->get_category_titles(); - $prio_help = __( 'Manually set the priority for the ', 'all-in-one-seo-pack' ); - $freq_help = __( 'Manually set the frequency for the ', 'all-in-one-seo-pack' ); $post_name = __( ' Post Type', 'all-in-one-seo-pack' ); $tax_name = __( ' Taxonomy', 'all-in-one-seo-pack' ); @@ -708,7 +660,6 @@ public function add_post_types() { array( $key => array( 'name' => $v . $post_name, - 'help_text' => $prio_help . $v . $post_name, 'type' => 'select', 'initial_options' => $this->prio, 'default' => 'no', @@ -724,7 +675,6 @@ public function add_post_types() { array( $key => array( 'name' => $v . $post_name, - 'help_text' => $freq_help . $v . $post_name, 'type' => 'select', 'initial_options' => $this->freq, 'default' => 'no', @@ -742,7 +692,6 @@ public function add_post_types() { array( $key => array( 'name' => $v . $tax_name, - 'help_text' => $prio_help . $v . $tax_name, 'type' => 'select', 'initial_options' => $this->prio, 'default' => 'no', @@ -758,7 +707,6 @@ public function add_post_types() { array( $key => array( 'name' => $v . $tax_name, - 'help_text' => $freq_help . $v . $tax_name, 'type' => 'select', 'initial_options' => $this->freq, 'default' => 'no', From 69adc4580e05cc70960b59acf7c63b6af336aae4 Mon Sep 17 00:00:00 2001 From: Ashish Ravi Date: Wed, 6 Mar 2019 16:21:23 +0530 Subject: [PATCH 007/121] Minimum supported version is WP 4.6 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 607aa5ed9..d3697eec7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,7 @@ matrix: - php: 5.2 dist: precise - env: WP_VERSION=latest - - env: WP_VERSION=4.5 + - env: WP_VERSION=4.6 - env: WP_MULTISITE=1 allow_failures: - env: WP_MULTISITE=1 From af95e7013f5a5a266f4ebd5e1379f3aeea176dec Mon Sep 17 00:00:00 2001 From: contactashish13 Date: Wed, 6 Mar 2019 21:54:00 +0530 Subject: [PATCH 008/121] Integrate Grunt with Travis (#2249) * added info for testing * add grunt to travis * separate task for grunt * travis failure * travis failure * travis failure * reinstate all jobs * failure * reinstate all jobs * only on PRs * test with only grunt job * reinstate all jobs * PR comments --- .travis.yml | 15 +++++++++++++-- PULL_REQUEST_TEMPLATE.md | 6 ++++++ bin/init-grunt.sh | 19 +++++++++++++++++++ package.json | 2 +- 4 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 bin/init-grunt.sh diff --git a/.travis.yml b/.travis.yml index d3697eec7..fba9ea590 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ language: php matrix: fast_finish: true global: - - env: PHPUNIT=global + - env: PHPUNIT=global GRUNT=no include: - php: 7.2 env: PHPUNIT=local @@ -20,6 +20,10 @@ matrix: - env: WP_VERSION=latest - env: WP_VERSION=4.6 - env: WP_MULTISITE=1 + - language: node_js + node_js: + - "8.11.3" + env: GRUNT=yes allow_failures: - env: WP_MULTISITE=1 - php: 5.3 @@ -38,8 +42,15 @@ branches: install: - if [[ $PHPUNIT = "local" ]]; then composer install; fi + - if [[ $GRUNT = "yes" && "$TRAVIS_PULL_REQUEST" != "false" ]]; then chmod +x bin/init-grunt.sh; . bin/init-grunt.sh; fi before_script: - bash bin/install-wp-tests.sh wordpress_test root '' localhost $WP_VERSION -script: if [[ $PHPUNIT = "local" ]]; then ./vendor/bin/phpunit; else phpunit; fi +script: + - if [[ $GRUNT = "yes" && "$TRAVIS_PULL_REQUEST" != "false" ]]; then grunt; fi + - if [[ $PHPUNIT = "local" ]]; then ./vendor/bin/phpunit; else phpunit; fi + +after_failure: +- cat "logs/phpcs.log" +- cat "logs/jslogs.log" diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md index 71d019c3e..a3c7acf1b 100644 --- a/PULL_REQUEST_TEMPLATE.md +++ b/PULL_REQUEST_TEMPLATE.md @@ -19,6 +19,12 @@ _Put an `x` in the boxes that apply. You can also fill these out after creating - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] I have added necessary documentation (if appropriate) +## Testing instructions +-Don't assume the tester knows the entire backstory of the issue, and don't force him/her to decipher the code to try and figure out what -it's doing or how to test it. +-Do provide step by step instructions on how to test. +-Do note things to watch out for. +-Do not what aspects the tester should try and break. + ## Further comments If this is a relatively large or complex change, kick off the discussion by explaining why you chose the solution you did and what alternatives you considered, etc... diff --git a/bin/init-grunt.sh b/bin/init-grunt.sh new file mode 100644 index 000000000..47f7a6bee --- /dev/null +++ b/bin/init-grunt.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +npm install +npm install grunt -g +npm install grunt-cli -g +npm install grunt-mkdir grunt-phpcs grunt-phpcbf grunt-phplint grunt-contrib-jshint grunt-contrib-uglify grunt-eslint + +composer install --no-interaction --ignore-platform-reqs + +COMPOSER_LOCATION=$(composer config home --global) +export PATH="$COMPOSER_LOCATION/vendor/bin:$PATH" +composer self-update + +composer global require "squizlabs/php_codesniffer" + +git clone -b master --depth 1 https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards.git "$HOME/wordpress-coding-standards" +phpenv rehash +phpcs --config-set installed_paths "$HOME/wordpress-coding-standards" +phpenv rehash diff --git a/package.json b/package.json index f446d57f9..57dead130 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "test": "tests" }, "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "test": "grunt" }, "repository": { "type": "git", From dd4fe0cf8688de9363222cb4b75d2b1fd5803bd5 Mon Sep 17 00:00:00 2001 From: EkoJR Date: Thu, 7 Mar 2019 11:05:43 -0800 Subject: [PATCH 009/121] Fix warnings with unit tests for admin_notices --- tests/classes/aioseop-notices/test-delay-time.php | 2 +- tests/classes/aioseop-notices/test-init.php | 2 +- tests/classes/aioseop-notices/test-user.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/classes/aioseop-notices/test-delay-time.php b/tests/classes/aioseop-notices/test-delay-time.php index e4e91b809..253f39c23 100644 --- a/tests/classes/aioseop-notices/test-delay-time.php +++ b/tests/classes/aioseop-notices/test-delay-time.php @@ -91,7 +91,7 @@ protected function mock_notice() { * * @since 3.0 */ - public function test_enqueue_scripts_on_screens() { + public function test_enqueue_scripts_on_screens( $screen_id, $url, $dir ) { $this->markTestSkipped('Skip'); } diff --git a/tests/classes/aioseop-notices/test-init.php b/tests/classes/aioseop-notices/test-init.php index 6ccdea021..e9842f186 100644 --- a/tests/classes/aioseop-notices/test-init.php +++ b/tests/classes/aioseop-notices/test-init.php @@ -95,7 +95,7 @@ protected function mock_notice() { * * @since 3.0 */ - public function test_enqueue_scripts_on_screens() { + public function test_enqueue_scripts_on_screens( $screen_id, $url, $dir ) { $this->markTestSkipped('Skip'); } diff --git a/tests/classes/aioseop-notices/test-user.php b/tests/classes/aioseop-notices/test-user.php index ff4d353ed..8e2aeeeac 100644 --- a/tests/classes/aioseop-notices/test-user.php +++ b/tests/classes/aioseop-notices/test-user.php @@ -99,7 +99,7 @@ protected function mock_notice() { * * @since 3.0 */ - public function test_enqueue_scripts_on_screens() { + public function test_enqueue_scripts_on_screens( $screen_id, $url, $dir ) { $this->markTestSkipped('Skip'); } From 789e0742d516eb78ade5967ed331076f3099dfea Mon Sep 17 00:00:00 2001 From: EkoJR Date: Thu, 7 Mar 2019 11:17:38 -0800 Subject: [PATCH 010/121] Dev-Fix unit tests params passed --- tests/classes/aioseop-notices/test-delay-time.php | 2 ++ tests/classes/aioseop-notices/test-init.php | 2 ++ tests/classes/aioseop-notices/test-user.php | 2 ++ 3 files changed, 6 insertions(+) diff --git a/tests/classes/aioseop-notices/test-delay-time.php b/tests/classes/aioseop-notices/test-delay-time.php index 253f39c23..2729bc435 100644 --- a/tests/classes/aioseop-notices/test-delay-time.php +++ b/tests/classes/aioseop-notices/test-delay-time.php @@ -90,6 +90,8 @@ protected function mock_notice() { * Override and skip. * * @since 3.0 + * + * @dataProvider data_screens */ public function test_enqueue_scripts_on_screens( $screen_id, $url, $dir ) { $this->markTestSkipped('Skip'); diff --git a/tests/classes/aioseop-notices/test-init.php b/tests/classes/aioseop-notices/test-init.php index e9842f186..05bdcafd9 100644 --- a/tests/classes/aioseop-notices/test-init.php +++ b/tests/classes/aioseop-notices/test-init.php @@ -94,6 +94,8 @@ protected function mock_notice() { * Override and skip. * * @since 3.0 + * + * @dataProvider data_screens */ public function test_enqueue_scripts_on_screens( $screen_id, $url, $dir ) { $this->markTestSkipped('Skip'); diff --git a/tests/classes/aioseop-notices/test-user.php b/tests/classes/aioseop-notices/test-user.php index 8e2aeeeac..7197a011b 100644 --- a/tests/classes/aioseop-notices/test-user.php +++ b/tests/classes/aioseop-notices/test-user.php @@ -98,6 +98,8 @@ protected function mock_notice() { * Override and skip. * * @since 3.0 + * + * @dataProvider data_screens */ public function test_enqueue_scripts_on_screens( $screen_id, $url, $dir ) { $this->markTestSkipped('Skip'); From cdb1203637f8eca54fbfd1845c7a6c1164211df4 Mon Sep 17 00:00:00 2001 From: EkoJR Date: Thu, 7 Mar 2019 11:47:11 -0800 Subject: [PATCH 011/121] Dev-Clean JSHint ignore localized variable --- js/admin-notice.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/js/admin-notice.js b/js/admin-notice.js index 7872591ab..16d0d6b2a 100644 --- a/js/admin-notice.js +++ b/js/admin-notice.js @@ -27,7 +27,9 @@ * @param string delayIndex */ function aioseop_notice_delay_ajax_action( noticeSlug, delayIndex ) { - var noticeNonce = aioseop_notice_data.notice_nonce; + // JSHint: 'aioseop_notice_data' is not defined. (W117) + // WP defines the variable through wp_localize_script(). + var noticeNonce = aioseop_notice_data.notice_nonce; // jshint ignore:line var noticeDelayID = "#aioseop-notice-delay-" + noticeSlug + "-" + delayIndex; $( noticeDelayID ).on( "click", function( event ) { var elem_href = $( this ).attr( "href" ); @@ -74,7 +76,9 @@ * @param string noticeSlug */ function aioseop_notice_delay_wp_default_dismiss_ajax_action( noticeSlug ) { - var noticeNonce = aioseop_notice_data.notice_nonce; + // JSHint: 'aioseop_notice_data' is not defined. (W117) + // WP defines the variable through wp_localize_script(). + var noticeNonce = aioseop_notice_data.notice_nonce; // jshint ignore:line var noticeContainer = ".aioseop-notice-" + noticeSlug; $( noticeContainer ).on( "click", "button.notice-dismiss ", function( event ) { // Prevents any unwanted actions. @@ -104,7 +108,9 @@ * * Constructs the actions the user may perform. */ - var noticeDelays = aioseop_notice_data.notice_actions; + // JSHint: 'aioseop_notice_data' is not defined. (W117) + // WP defines the variable through wp_localize_script(). + var noticeDelays = aioseop_notice_data.notice_actions; // jshint ignore:line $.each( noticeDelays, function ( k1NoticeSlug, v1DelayArr ) { $.each( v1DelayArr, function ( k2I, v2DelayIndex ) { From fd2b5c4243dba7b3feda7422a1759502386610fa Mon Sep 17 00:00:00 2001 From: EkoJR Date: Thu, 7 Mar 2019 11:48:11 -0800 Subject: [PATCH 012/121] Dev-Clean run grunt --- admin/display/notice-aioseop.php | 2 +- admin/display/notice-default.php | 2 +- tests/base/class-aioseop-notices-testcase.php | 81 +++++++++---------- .../aioseop-notices/test-delay-time.php | 2 +- tests/classes/aioseop-notices/test-init.php | 2 +- tests/classes/aioseop-notices/test-user.php | 2 +- 6 files changed, 45 insertions(+), 46 deletions(-) diff --git a/admin/display/notice-aioseop.php b/admin/display/notice-aioseop.php index 50c397ddd..7da847902 100644 --- a/admin/display/notice-aioseop.php +++ b/admin/display/notice-aioseop.php @@ -28,7 +28,7 @@ $class .= 'aioseop-delay-' . $key; $class .= ' ' . $action_option['class']; ?> - +

diff --git a/admin/display/notice-default.php b/admin/display/notice-default.php index 8d1ed60fe..cf3a78a51 100644 --- a/admin/display/notice-default.php +++ b/admin/display/notice-default.php @@ -28,7 +28,7 @@ $class .= 'aioseop-delay-' . $key; $class .= ' ' . $action_option['class']; ?> - +

diff --git a/tests/base/class-aioseop-notices-testcase.php b/tests/base/class-aioseop-notices-testcase.php index 6e1bb952d..a84104458 100644 --- a/tests/base/class-aioseop-notices-testcase.php +++ b/tests/base/class-aioseop-notices-testcase.php @@ -490,31 +490,31 @@ protected function data_screens_wp() { 'url' => site_url() . '/wp-admin/post-new.php', 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/post-new.php', ), -// array( -// 'screen_id' => 'post', -// 'url' => site_url() . '/wp-admin/post.php?post=###&action=edit', -// 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/post.php?post=###&action=edit', -// ), + // array( + // 'screen_id' => 'post', + // 'url' => site_url() . '/wp-admin/post.php?post=###&action=edit', + // 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/post.php?post=###&action=edit', + // ), array( 'screen_id' => 'edit-category', 'url' => site_url() . '/wp-admin/edit-tags.php?taxonomy=category', 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/edit-tags.php?taxonomy=category', ), -// array( -// 'screen_id' => 'edit-category', -// 'url' => site_url() . '/wp-admin/edit-tags.php?action=edit&taxonomy=category&tag_ID=###&post_type=post', -// 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/edit-tags.php?action=edit&taxonomy=category&tag_ID=###&post_type=post', -// ), + // array( + // 'screen_id' => 'edit-category', + // 'url' => site_url() . '/wp-admin/edit-tags.php?action=edit&taxonomy=category&tag_ID=###&post_type=post', + // 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/edit-tags.php?action=edit&taxonomy=category&tag_ID=###&post_type=post', + // ), array( 'screen_id' => 'edit-post_tag', 'url' => site_url() . '/wp-admin/edit-tags.php?taxonomy=post_tag', 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/edit-tags.php?taxonomy=post_tag', ), -// array( -// 'screen_id' => 'edit-post_tag', -// 'url' => site_url() . '/wp-admin/edit-tags.php?action=edit&taxonomy=post_tag&tag_ID=###&post_type=post', -// 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/edit-tags.php?action=edit&taxonomy=post_tag&tag_ID=###&post_type=post', -// ), + // array( + // 'screen_id' => 'edit-post_tag', + // 'url' => site_url() . '/wp-admin/edit-tags.php?action=edit&taxonomy=post_tag&tag_ID=###&post_type=post', + // 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/edit-tags.php?action=edit&taxonomy=post_tag&tag_ID=###&post_type=post', + // ), // Custom Post Types. // Custom Taxonomies. array( @@ -527,11 +527,11 @@ protected function data_screens_wp() { 'url' => site_url() . '/wp-admin/media-new.php', 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/media-new.php', ), -// array( -// 'screen_id' => 'attachment', -// 'url' => site_url() . '/wp-admin/post.php?post=###&action=edit', -// 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/post.php?post=###&action=edit', -// ), + // array( + // 'screen_id' => 'attachment', + // 'url' => site_url() . '/wp-admin/post.php?post=###&action=edit', + // 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/post.php?post=###&action=edit', + // ), array( 'screen_id' => 'edit-page', 'url' => site_url() . '/wp-admin/edit.php?post_type=page', @@ -542,21 +542,21 @@ protected function data_screens_wp() { 'url' => site_url() . '/wp-admin/post-new.php?post_type=page', 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/post-new.php?post_type=page', ), -// array( -// 'screen_id' => 'page', -// 'url' => site_url() . '/wp-admin/post.php?post=###&action=edit', -// 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/post.php?post=###&action=edit', -// ), + // array( + // 'screen_id' => 'page', + // 'url' => site_url() . '/wp-admin/post.php?post=###&action=edit', + // 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/post.php?post=###&action=edit', + // ), array( 'screen_id' => 'edit-comments', 'url' => site_url() . '/wp-admin/edit-comments.php', 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/edit-comments.php', ), -// array( -// 'screen_id' => 'comment', -// 'url' => site_url() . '/wp-admin/comment.php?action=editcomment&c=###', -// 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/comment.php?action=editcomment&c=###', -// ), + // array( + // 'screen_id' => 'comment', + // 'url' => site_url() . '/wp-admin/comment.php?action=editcomment&c=###', + // 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/comment.php?action=editcomment&c=###', + // ), array( 'screen_id' => 'themes', 'url' => site_url() . '/wp-admin/themes.php', @@ -577,12 +577,11 @@ protected function data_screens_wp() { 'url' => site_url() . '/wp-admin/theme-editor.php', 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/theme-editor.php', ), -// array( -// 'screen_id' => 'appearance_page_{page}', -// 'url' => site_url() . '/wp-admin/themes.php?page={page}', -// 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/themes.php?page={page}', -// ), - + // array( + // 'screen_id' => 'appearance_page_{page}', + // 'url' => site_url() . '/wp-admin/themes.php?page={page}', + // 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/themes.php?page={page}', + // ), array( 'screen_id' => 'plugins', 'url' => site_url() . '/wp-admin/plugins.php', @@ -609,11 +608,11 @@ protected function data_screens_wp() { 'url' => site_url() . '/wp-admin/user-new.php', 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/user-new.php', ), -// array( -// 'screen_id' => 'user-edit', -// 'url' => site_url() . '/wp-admin/user-edit.php?user_id=###', -// 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/user-edit.php?user_id=###', -// ), + // array( + // 'screen_id' => 'user-edit', + // 'url' => site_url() . '/wp-admin/user-edit.php?user_id=###', + // 'dir' => WP_DEVELOP_DIR . '/src/wp-admin/user-edit.php?user_id=###', + // ), array( 'screen_id' => 'profile', 'url' => site_url() . '/wp-admin/profile.php', diff --git a/tests/classes/aioseop-notices/test-delay-time.php b/tests/classes/aioseop-notices/test-delay-time.php index 2729bc435..b0bad3d47 100644 --- a/tests/classes/aioseop-notices/test-delay-time.php +++ b/tests/classes/aioseop-notices/test-delay-time.php @@ -94,7 +94,7 @@ protected function mock_notice() { * @dataProvider data_screens */ public function test_enqueue_scripts_on_screens( $screen_id, $url, $dir ) { - $this->markTestSkipped('Skip'); + $this->markTestSkipped( 'Skip' ); } /** diff --git a/tests/classes/aioseop-notices/test-init.php b/tests/classes/aioseop-notices/test-init.php index 05bdcafd9..e92a72c4c 100644 --- a/tests/classes/aioseop-notices/test-init.php +++ b/tests/classes/aioseop-notices/test-init.php @@ -98,7 +98,7 @@ protected function mock_notice() { * @dataProvider data_screens */ public function test_enqueue_scripts_on_screens( $screen_id, $url, $dir ) { - $this->markTestSkipped('Skip'); + $this->markTestSkipped( 'Skip' ); } /** diff --git a/tests/classes/aioseop-notices/test-user.php b/tests/classes/aioseop-notices/test-user.php index 7197a011b..99dce97c4 100644 --- a/tests/classes/aioseop-notices/test-user.php +++ b/tests/classes/aioseop-notices/test-user.php @@ -102,7 +102,7 @@ protected function mock_notice() { * @dataProvider data_screens */ public function test_enqueue_scripts_on_screens( $screen_id, $url, $dir ) { - $this->markTestSkipped('Skip'); + $this->markTestSkipped( 'Skip' ); } /** From aec94de3607d3d340c949a49741cc3ca70947bb1 Mon Sep 17 00:00:00 2001 From: EkoJR Date: Thu, 7 Mar 2019 11:48:27 -0800 Subject: [PATCH 013/121] Dev-Clean else if to elseif --- tests/base/class-aioseop-notices-testcase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/base/class-aioseop-notices-testcase.php b/tests/base/class-aioseop-notices-testcase.php index a84104458..a7e55d88d 100644 --- a/tests/base/class-aioseop-notices-testcase.php +++ b/tests/base/class-aioseop-notices-testcase.php @@ -68,7 +68,7 @@ public function define_wp_develop_dir() { $wp_develop_dir = $_tests_dir; $wp_develop_dir = str_replace( '/test/phpunit', '', $wp_develop_dir ); $wp_develop_dir = str_replace( '\test\phpunit', '', $wp_develop_dir ); - } else if ( ! empty( $config_file_path ) ) { + } elseif ( ! empty( $config_file_path ) ) { $wp_develop_dir = $config_file_path; $wp_develop_dir = str_replace( '/wp-tests-config.php', '', $wp_develop_dir ); $wp_develop_dir = str_replace( '\wp-tests-config.php', '', $wp_develop_dir ); From f5af90a60562ee9cda0e77b641c96a3ba37db019 Mon Sep 17 00:00:00 2001 From: EkoJR Date: Thu, 7 Mar 2019 22:31:45 -0800 Subject: [PATCH 014/121] Dev-Change for review --- js/admin-notice.js | 14 ++++---------- tests/classes/aioseop-notices/test-delay-time.php | 2 +- tests/classes/aioseop-notices/test-init.php | 2 +- tests/classes/aioseop-notices/test-user.php | 2 +- 4 files changed, 7 insertions(+), 13 deletions(-) diff --git a/js/admin-notice.js b/js/admin-notice.js index 16d0d6b2a..f47e821ba 100644 --- a/js/admin-notice.js +++ b/js/admin-notice.js @@ -9,7 +9,7 @@ // phpcs:disable PEAR.Functions.FunctionCallSignature.ContentAfterOpenBracket // phpcs:disable PEAR.Functions.FunctionCallSignature.MultipleArguments // phpcs:disable PEAR.Functions.FunctionCallSignature.CloseBracketLine - +/* global aioseop_notice_data */ (function($) { /** @@ -27,9 +27,7 @@ * @param string delayIndex */ function aioseop_notice_delay_ajax_action( noticeSlug, delayIndex ) { - // JSHint: 'aioseop_notice_data' is not defined. (W117) - // WP defines the variable through wp_localize_script(). - var noticeNonce = aioseop_notice_data.notice_nonce; // jshint ignore:line + var noticeNonce = aioseop_notice_data.notice_nonce; var noticeDelayID = "#aioseop-notice-delay-" + noticeSlug + "-" + delayIndex; $( noticeDelayID ).on( "click", function( event ) { var elem_href = $( this ).attr( "href" ); @@ -76,9 +74,7 @@ * @param string noticeSlug */ function aioseop_notice_delay_wp_default_dismiss_ajax_action( noticeSlug ) { - // JSHint: 'aioseop_notice_data' is not defined. (W117) - // WP defines the variable through wp_localize_script(). - var noticeNonce = aioseop_notice_data.notice_nonce; // jshint ignore:line + var noticeNonce = aioseop_notice_data.notice_nonce; var noticeContainer = ".aioseop-notice-" + noticeSlug; $( noticeContainer ).on( "click", "button.notice-dismiss ", function( event ) { // Prevents any unwanted actions. @@ -108,9 +104,7 @@ * * Constructs the actions the user may perform. */ - // JSHint: 'aioseop_notice_data' is not defined. (W117) - // WP defines the variable through wp_localize_script(). - var noticeDelays = aioseop_notice_data.notice_actions; // jshint ignore:line + var noticeDelays = aioseop_notice_data.notice_actions; $.each( noticeDelays, function ( k1NoticeSlug, v1DelayArr ) { $.each( v1DelayArr, function ( k2I, v2DelayIndex ) { diff --git a/tests/classes/aioseop-notices/test-delay-time.php b/tests/classes/aioseop-notices/test-delay-time.php index b0bad3d47..b52a2099b 100644 --- a/tests/classes/aioseop-notices/test-delay-time.php +++ b/tests/classes/aioseop-notices/test-delay-time.php @@ -94,7 +94,7 @@ protected function mock_notice() { * @dataProvider data_screens */ public function test_enqueue_scripts_on_screens( $screen_id, $url, $dir ) { - $this->markTestSkipped( 'Skip' ); + $this->markTestIncomplete( 'Skip' ); } /** diff --git a/tests/classes/aioseop-notices/test-init.php b/tests/classes/aioseop-notices/test-init.php index e92a72c4c..b10ffc704 100644 --- a/tests/classes/aioseop-notices/test-init.php +++ b/tests/classes/aioseop-notices/test-init.php @@ -98,7 +98,7 @@ protected function mock_notice() { * @dataProvider data_screens */ public function test_enqueue_scripts_on_screens( $screen_id, $url, $dir ) { - $this->markTestSkipped( 'Skip' ); + $this->markTestIncomplete( 'Skip' ); } /** diff --git a/tests/classes/aioseop-notices/test-user.php b/tests/classes/aioseop-notices/test-user.php index 99dce97c4..68548335f 100644 --- a/tests/classes/aioseop-notices/test-user.php +++ b/tests/classes/aioseop-notices/test-user.php @@ -102,7 +102,7 @@ protected function mock_notice() { * @dataProvider data_screens */ public function test_enqueue_scripts_on_screens( $screen_id, $url, $dir ) { - $this->markTestSkipped( 'Skip' ); + $this->markTestIncomplete( 'Skip' ); } /** From e489e0f30411a92ed528078f09346e9ff6c41280 Mon Sep 17 00:00:00 2001 From: EkoJR Date: Sat, 9 Mar 2019 11:13:50 -0800 Subject: [PATCH 015/121] Final Grunt run --- admin/display/credits-content.php | 112 +++++++++++++++--------------- aioseop_class.php | 10 +-- inc/aioseop_updates_class.php | 8 +-- js/admin-notice.min.js | 1 + modules/aioseop_opengraph.php | 2 +- 5 files changed, 67 insertions(+), 66 deletions(-) create mode 100644 js/admin-notice.min.js diff --git a/admin/display/credits-content.php b/admin/display/credits-content.php index f54fcbb62..ae9d49682 100644 --- a/admin/display/credits-content.php +++ b/admin/display/credits-content.php @@ -14,11 +14,11 @@ Steve Mortiboy -
  • - - Yuqian Liu - -
  • +
  • + + Yuqian Liu + +
  • @@ -29,16 +29,16 @@ -
  • - - Ashish Ravi - -
  • -
  • - - Ben Reames - -
  • +
  • + + Ashish Ravi + +
  • +
  • + + Ben Reames + +
  • @@ -55,24 +55,24 @@
  • - Rebecca Hum + Rebecca Hum +
  • +
  • + + Mayo Moriyama +
  • +
  • + + Dougal Campbell
  • -
  • - - Mayo Moriyama -
  • -
  • - - Dougal Campbell -
  • Alejandro Mostajo
  • -
  • - - Aaron Brodney -
  • +
  • + + Aaron Brodney +
  • Stanislav Samoilenko @@ -81,34 +81,34 @@ Shohei Tanaka
  • -
  • - - Ross McKay -
  • -
  • - - Adam Silverstein -
  • -
  • - - Vinicius Schettino -
  • -
  • - - Srdjan Jocic -
  • -
  • - - Gennady Kovshenin -
  • +
  • + + Ross McKay +
  • +
  • + + Adam Silverstein +
  • +
  • + + Vinicius Schettino +
  • +
  • + + Srdjan Jocic +
  • +
  • + + Gennady Kovshenin +
  • diff --git a/aioseop_class.php b/aioseop_class.php index 406d673f4..3b4abfdea 100644 --- a/aioseop_class.php +++ b/aioseop_class.php @@ -936,7 +936,7 @@ public function get_title_format( $args ) { $title_format = str_replace( '%current_date%', aioseop_formatted_date(), $title_format ); } - if ( strpos( $title_format, "%post_date%" ) !== false ){ + if ( strpos( $title_format, '%post_date%' ) !== false ) { $title_format = str_replace( '%post_date%', aioseop_formatted_date( get_the_time( 'U' ) ), $title_format ); } if ( strpos( $title_format, '%post_year%' ) !== false ) { @@ -1805,10 +1805,10 @@ function title_placeholder_helper( $title, $post, $type = 'post', $title_format $new_title = str_replace( "%{$type}_author_lastname%", $this->ucwords( $authordata->last_name ), $new_title ); } - if ( strpos( $new_title, "%current_date%" ) !== false ){ + if ( strpos( $new_title, '%current_date%' ) !== false ) { $new_title = str_replace( '%current_date%', aioseop_formatted_date(), $new_title ); } - if ( strpos( $new_title, "%post_date%" ) !== false ){ + if ( strpos( $new_title, '%post_date%' ) !== false ) { $new_title = str_replace( '%post_date%', aioseop_formatted_date( get_the_date( 'U' ) ), $new_title ); } if ( strpos( $new_title, '%post_year%' ) !== false ) { @@ -4192,12 +4192,12 @@ function get_prev_next_links( $post = null ) { if ( ! empty( $prev ) ) { $dom = new DOMDocument(); $dom->loadHTML( $prev ); - $prev = $dom->getElementsByTagName( 'a' )->item(0)->getAttribute( 'href' ); + $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' ); + $next = $dom->getElementsByTagName( 'a' )->item( 0 )->getAttribute( 'href' ); } } diff --git a/inc/aioseop_updates_class.php b/inc/aioseop_updates_class.php index 623a4024e..e60ebc5bc 100644 --- a/inc/aioseop_updates_class.php +++ b/inc/aioseop_updates_class.php @@ -76,7 +76,7 @@ function aioseop_welcome() { if ( get_transient( '_aioseop_activation_redirect' ) ) { delete_transient( '_aioseop_activation_redirect' ); $aioseop_welcome = new aioseop_welcome(); - $aioseop_welcome->init( TRUE ); + $aioseop_welcome->init( true ); } } @@ -120,7 +120,7 @@ function do_version_updates( $old_version ) { ) { $this->bad_bots_remove_semrush_201810(); } - + if ( version_compare( $old_version, '3.0', '<' ) ) { @@ -228,14 +228,14 @@ function bad_bots_remove_semrush_201810() { $aiosp->update_class_option( $aioseop_options ); } } - + /** * Removes Exabot from bad bot blocker to allow Alexabot. (#2105) * * @since 3.0 * @global @aiosp, @aioseop_options */ - function bad_bots_remove_exabot_201902(){ + function bad_bots_remove_exabot_201902() { global $aiosp, $aioseop_options; if ( isset( $aioseop_options['modules']['aiosp_bad_robots_options']['aiosp_bad_robots_blocklist'] ) ) { diff --git a/js/admin-notice.min.js b/js/admin-notice.min.js new file mode 100644 index 000000000..2ee8151de --- /dev/null +++ b/js/admin-notice.min.js @@ -0,0 +1 @@ +!function(i){var a=aioseop_notice_data.notice_actions;i.each(a,function(n,a){var o,t;i.each(a,function(a,e){var o,t,c;o=n,t=e,c=aioseop_notice_data.notice_nonce,i("#aioseop-notice-delay-"+o+"-"+t).on("click",function(a){var e=i(this).attr("href");"#"!==e&&""!==e||(a.stopPropagation(),a.preventDefault());var n=new FormData;n.append("notice_slug",o),n.append("action_index",t),n.append("action","aioseop_notice"),n.append("_ajax_nonce",c),i.ajax({url:ajaxurl,type:"POST",data:n,cache:!1,dataType:"json",processData:!1,contentType:!1,success:function(a,e,n){i(".aioseop-notice-"+o).remove()}})})}),o=n,t=aioseop_notice_data.notice_nonce,i(".aioseop-notice-"+o).on("click","button.notice-dismiss ",function(a){a.stopPropagation(),a.preventDefault();var e=new FormData;e.append("notice_slug",o),e.append("action_index","default"),e.append("action","aioseop_notice"),e.append("_ajax_nonce",t),i.ajax({url:ajaxurl,type:"POST",data:e,cache:!1,dataType:"json",processData:!1,contentType:!1})})})}(jQuery); \ No newline at end of file diff --git a/modules/aioseop_opengraph.php b/modules/aioseop_opengraph.php index e1af5968c..ca62b29e4 100644 --- a/modules/aioseop_opengraph.php +++ b/modules/aioseop_opengraph.php @@ -1181,7 +1181,7 @@ function add_meta() { } else { $description = $post->post_excerpt; } - } + } } if ( empty( $type ) ) { $type = 'article'; From 788d817013e8ae4adbbcd5b570f6820189557813 Mon Sep 17 00:00:00 2001 From: onetarek Date: Tue, 5 Mar 2019 23:47:49 +0600 Subject: [PATCH 016/121] Remove spaces before and after anchor text --- admin/display/general-metaboxes.php | 2 +- aioseop_class.php | 4 ++-- inc/commonstrings.php | 2 +- modules/aioseop_sitemap.php | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/admin/display/general-metaboxes.php b/admin/display/general-metaboxes.php index 16dad82da..77d6c272a 100644 --- a/admin/display/general-metaboxes.php +++ b/admin/display/general-metaboxes.php @@ -91,7 +91,7 @@ static function display_extra_metaboxes( $add, $meta ) { /* translators: %1$s expands to the number of languages All in One SEO Pack has been translated into. $2%s to the percentage translated of the current language, $3%s to the language name, %4$s and %5$s to anchor tags with link to translation page at translate.wordpress.org */ printf( __( - 'All in One SEO Pack has been translated into %1$s languages, but currently the %3$s translation is only %2$s percent complete. %4$s Click here %5$s to help get it to 100 percent.', 'all-in-one-seo-pack' + 'All in One SEO Pack has been translated into %1$s languages, but currently the %3$s translation is only %2$s percent complete. %4$sClick here%5$s to help get it to 100 percent.', 'all-in-one-seo-pack' ), $aiosp_trans->translated_count, $aiosp_trans->percent_translated, diff --git a/aioseop_class.php b/aioseop_class.php index 3b4abfdea..70eae17d8 100644 --- a/aioseop_class.php +++ b/aioseop_class.php @@ -3451,7 +3451,7 @@ function visibility_warning() {

    ', __( 'Warning: You\'re blocking access to search engines.', 'all-in-one-seo-pack' ), - sprintf( __( 'You can %1$s click here%2$s to go to your reading settings and toggle your blog visibility.', 'all-in-one-seo-pack' ), sprintf( '', esc_url( admin_url( 'options-reading.php' ) ) ), '' ) + sprintf( __( 'You can %1$sclick here%2$s to go to your reading settings and toggle your blog visibility.', 'all-in-one-seo-pack' ), sprintf( '', esc_url( admin_url( 'options-reading.php' ) ) ), '' ) ); } elseif ( '1' == get_option( 'blog_public' ) && ! empty( $aioseop_visibility_notice_dismissed ) ) { @@ -3475,7 +3475,7 @@ function woo_upgrade_notice() {

    ', __( 'We\'ve detected you\'re running WooCommerce.', 'all-in-one-seo-pack' ), - sprintf( __( '%1$s Upgrade%2$s to All in One SEO Pack Pro for increased SEO compatibility for your products.', 'all-in-one-seo-pack' ), sprintf( '', esc_url( 'https://semperplugins.com/plugins/all-in-one-seo-pack-pro-version/?loc=woo' ) ), '' ) + sprintf( __( '%1$sUpgrade%2$s to All in One SEO Pack Pro for increased SEO compatibility for your products.', 'all-in-one-seo-pack' ), sprintf( '', esc_url( 'https://semperplugins.com/plugins/all-in-one-seo-pack-pro-version/?loc=woo' ) ), '' ) ); } elseif ( ! class_exists( 'WooCommerce' ) && ! empty( $aioseop_woo_upgrade_notice_dismissed ) ) { diff --git a/inc/commonstrings.php b/inc/commonstrings.php index c9eeeec1d..70905d094 100644 --- a/inc/commonstrings.php +++ b/inc/commonstrings.php @@ -43,7 +43,7 @@ private function __construct() { __( '%s is almost ready.', 'all-in-one-seo-pack' ); __( 'You must enter a valid License Key for it to work.', 'all-in-one-seo-pack' ); __( "There is a new version of %1\$s available. Go to the plugins page for details.", 'all-in-one-seo-pack' ); - sprintf( __( 'Your license has expired. Please %1$s click here %2$s to purchase a new one.', 'all-in-one-seo-pack' ), '', '' ); + sprintf( __( 'Your license has expired. Please %1$sclick here%2$s to purchase a new one.', 'all-in-one-seo-pack' ), '', '' ); __( 'Track Outbound Forms:', 'all-in-one-seo-pack' ); __( 'Track Events:', 'all-in-one-seo-pack' ); __( 'Track URL Changes:', 'all-in-one-seo-pack' ); diff --git a/modules/aioseop_sitemap.php b/modules/aioseop_sitemap.php index 0abe47c6b..2e3100416 100644 --- a/modules/aioseop_sitemap.php +++ b/modules/aioseop_sitemap.php @@ -460,7 +460,7 @@ public function sitemap_notices() { sprintf( // TODO Add esc_* or wp_kses function. /* translators: Links to the current AIOSEOP Sitemap settings. */ - __( '%1$s Click here%2$s to make these recommended changes.', 'all-in-one-seo-pack' ), + __( '%1$sClick here%2$s to make these recommended changes.', 'all-in-one-seo-pack' ), sprintf( '', esc_url( get_admin_url( null, "admin.php?page=$aioseop_plugin_dirname/modules/aioseop_sitemap.php" ) ) From abc75f2572db10000b4f13db39154b83f47dd05a Mon Sep 17 00:00:00 2001 From: contactashish13 Date: Wed, 13 Mar 2019 00:53:55 +0530 Subject: [PATCH 017/121] XML Sitemap - indexes should be reverse chronological order (#2263) * added info for testing * XML Sitemap - indexes should be reverse chronological order * grunt --- modules/aioseop_sitemap.php | 2 +- tests/modules/sitemap/test-sitemap.php | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/modules/aioseop_sitemap.php b/modules/aioseop_sitemap.php index 2e3100416..c3b576961 100644 --- a/modules/aioseop_sitemap.php +++ b/modules/aioseop_sitemap.php @@ -4140,7 +4140,7 @@ public function get_all_post_type_data( $args ) { 'offset' => 0, 'category' => 0, 'orderby' => 'post_date', - 'order' => 'DESC', + 'order' => 'ASC', 'include' => array(), 'exclude' => array(), 'post_type' => 'any', diff --git a/tests/modules/sitemap/test-sitemap.php b/tests/modules/sitemap/test-sitemap.php index 0edf48bde..f524e0202 100644 --- a/tests/modules/sitemap/test-sitemap.php +++ b/tests/modules/sitemap/test-sitemap.php @@ -39,6 +39,12 @@ public function test_only_pages() { $posts = $this->setup_posts( 2 ); $pages = $this->setup_posts( 2, 0, 'page' ); + // create a new page with a delay so that we can test if the sitemap is created in ASCENDING order. + // @issue https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/2217 + sleep( 1 ); + $new_page_id = $this->factory->post->create( array( 'post_type' => 'page' ) ); + $new_page = get_permalink( $new_page_id ); + $custom_options = array(); $custom_options['aiosp_sitemap_indexes'] = ''; $custom_options['aiosp_sitemap_images'] = ''; @@ -47,14 +53,23 @@ public function test_only_pages() { $this->_setup_options( 'sitemap', $custom_options ); - $this->validate_sitemap( + $file = $this->validate_sitemap( array( $pages['without'][0] => true, $pages['without'][1] => true, $posts['without'][0] => false, $posts['without'][1] => false, + $new_page => true, ) ); + + // in an ASCENDING order, the index of the urls will always lie in ascending order. + $index1 = strpos( $file, $pages['without'][0] ); + $index2 = strpos( $file, $pages['without'][1] ); + $index3 = strpos( $file, $new_page ); + + $this->assertGreaterThan( $index1, $index3, 'Sitemap is not in ascending order' ); + $this->assertGreaterThan( $index2, $index3, 'Sitemap is not in ascending order' ); } /** From cd05972e2f029b2a8700c78e1ee4eca8ff6fa9ae Mon Sep 17 00:00:00 2001 From: contactashish13 Date: Wed, 13 Mar 2019 19:16:18 +0530 Subject: [PATCH 018/121] Travis build fails for specific WP_VERSIONs because of PHPUnit version (#2288) * added info for testing * Travis build fails for specific WP_VERSIONs because of PHPUnit version --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index fba9ea590..b201f7183 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,8 +17,8 @@ matrix: dist: precise - php: 5.2 dist: precise - - env: WP_VERSION=latest - - env: WP_VERSION=4.6 + - env: WP_VERSION=latest PHPUNIT=local + - env: WP_VERSION=4.6 PHPUNIT=local - env: WP_MULTISITE=1 - language: node_js node_js: From 920b9243f72073f418b58c29ba31d883aa5f221b Mon Sep 17 00:00:00 2001 From: EkoJR Date: Thu, 14 Mar 2019 06:36:54 -0700 Subject: [PATCH 019/121] Fix smaller width with label elements (#2289) * Fix smaller width with label elements * Fix settings input styling * Add dev note --- admin/aioseop_module_class.php | 2 ++ css/modules/aioseop_module.css | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/admin/aioseop_module_class.php b/admin/aioseop_module_class.php index c98df8bbf..2c2897353 100644 --- a/admin/aioseop_module_class.php +++ b/admin/aioseop_module_class.php @@ -2409,6 +2409,8 @@ function get_option_row( $name, $opts, $args ) { $help_text = $opts['name']; } + // TODO Possible remove text align. + // Currently aligns to the right when everything is being aligned to the left; which is usually a workaround. $display_label_format = '%s'; $label_text = sprintf( $display_label_format, $align, $help_text ); } else { diff --git a/css/modules/aioseop_module.css b/css/modules/aioseop_module.css index d8788722f..f3b166049 100644 --- a/css/modules/aioseop_module.css +++ b/css/modules/aioseop_module.css @@ -139,7 +139,7 @@ div.aioseop_tip_icon:before { float: left; text-align: left; font-family: 'Open Sans', sans-serif; - width: 26%; + width: 81%; min-width: 120px; max-width: 230px; cursor: default; @@ -795,9 +795,9 @@ div.aioseop_feature#aioseop_coming_soon2 .aioseop_featured_image { .aioseop_input { clear: left; - width: 100%; - padding: 5px; - display: inline; + width: 98%; + padding: 5px 1%; + display: inline-block; } .aioseop_option_input { From 5a1d141517e6596bdd928e80f0e5624bac8a7890 Mon Sep 17 00:00:00 2001 From: EkoJR Date: Fri, 15 Mar 2019 09:15:29 -0700 Subject: [PATCH 020/121] Change upgrade to Pro notice to AIOSEOP_Notices (#2292) * Change upgrade to Pro notice to AIOSEOP_Notices #1852 * Add PHPUnit test for pro promo with WooCommerce * Dev-Clean run grunt * Dev-Fix notice activate & deactivate * Dev-Remove deprecated function * Dev-Update phpdoc @since * Dev-Fix testcase * Dev-Change wording in admin notice * Dev-Fix scrutinizer issue --- admin/functions-notice.php | 77 +++++++++++++++++++ aioseop_class.php | 36 +++------ inc/aioseop_functions.php | 5 -- .../notices/test-pro-promo-woocommerce.php | 37 +++++++++ 4 files changed, 126 insertions(+), 29 deletions(-) create mode 100644 tests/classes/aioseop-notices/notices/test-pro-promo-woocommerce.php diff --git a/admin/functions-notice.php b/admin/functions-notice.php index 5c08b59b5..3b08312ce 100644 --- a/admin/functions-notice.php +++ b/admin/functions-notice.php @@ -8,4 +8,81 @@ */ if ( class_exists( 'AIOSEOP_Notices' ) ) { + + /** + * Set Notice with WooCommerce Detected on Non-Pro AIOSEOP + * + * When WC is detected on Non-Pros, and message is displayed to upgrade to + * AIOSEOP Pro. "No Thanks" delays for 30 days. + * + * @since 3.0 + * + * @global AIOSEOP_Notices $aioseop_notices + * + * @param boolean $update Updates the notice with new content and configurations. + * @param boolean $reset Notice are re-initiated. + */ + function aioseop_notice_activate_pro_promo_woocommerce( $update = false, $reset = false ) { + global $aioseop_notices; + + $notice = aioseop_notice_pro_promo_woocommerce(); + + if ( ! $aioseop_notices->insert_notice( $notice ) ) { + if ( $update ) { + $aioseop_notices->update_notice( $notice ); + } + if ( $reset || ! isset( $aioseop_notices->active_notices[ $notice['slug'] ] ) ) { + $aioseop_notices->activate_notice( $notice['slug'] ); + } + } + } + + /** + * Notice - Pro Promotion for WooCommerce + * + * @since 3.0 + * + * @return array + */ + function aioseop_notice_pro_promo_woocommerce() { + return array( + 'slug' => 'woocommerce_detected', + 'delay_time' => 0, + 'message' => __( 'We have detected you are running WooCommerce. Upgrade to All in One SEO Pack Pro to unlock our advanced e-commerce features, including SEO for Product Categories and more.', 'all-in-one-seo-pack' ), + + 'class' => 'notice-info', + 'target' => 'user', + 'screens' => array(), + 'action_options' => array( + array( + 'time' => 0, + 'text' => __( 'Upgrade', 'all-in-one-seo-pack' ), + 'link' => 'https://semperplugins.com/plugins/all-in-one-seo-pack-pro-version/?loc=woo', + 'dismiss' => false, + 'class' => 'button-primary', + ), + array( + 'time' => 2592000, // 30 days. + 'text' => __( 'No Thanks', 'all-in-one-seo-pack' ), + 'link' => '', + 'dismiss' => false, + 'class' => 'button-secondary', + ), + ), + ); + } + + /** + * Disable Notice for WooCommerce/Upgrade-to-Pro + * + * @todo Add to Pro version to disable message set by Non-Pro. + * + * @since 3.0 + * + * @global AIOSEOP_Notices $aioseop_notices + */ + function aioseop_notice_disable_woocommerce_detected_on_nonpro() { + global $aioseop_notices; + $aioseop_notices->deactivate_notice( 'woocommerce_detected' ); + } } diff --git a/aioseop_class.php b/aioseop_class.php index 70eae17d8..505beffe3 100644 --- a/aioseop_class.php +++ b/aioseop_class.php @@ -831,10 +831,8 @@ function __construct() { add_action( 'aioseop_global_settings_footer', array( $this, 'display_settings_footer' ) ); add_action( 'output_option', array( $this, 'custom_output_option' ), 10, 2 ); add_action( 'all_admin_notices', array( $this, 'visibility_warning' ) ); + add_action( 'all_admin_notices', array( $this, 'woo_upgrade_notice' ) ); - if ( ! AIOSEOPPRO ) { - // add_action('all_admin_notices', array( $this, 'woo_upgrade_notice')); - } } if ( AIOSEOPPRO ) { add_action( 'split_shared_term', array( $this, 'split_shared_term' ), 10, 4 ); @@ -3459,27 +3457,17 @@ function visibility_warning() { } } - function woo_upgrade_notice() { - - $aioseop_woo_upgrade_notice_dismissed = get_user_meta( get_current_user_id(), 'aioseop_woo_upgrade_notice_dismissed', true ); - - if ( class_exists( 'WooCommerce' ) && empty( $aioseop_woo_upgrade_notice_dismissed ) && current_user_can( 'manage_options' ) ) { - - printf( - ' -
    -

    - %1$s - %2$s - -

    -
    ', - __( 'We\'ve detected you\'re running WooCommerce.', 'all-in-one-seo-pack' ), - sprintf( __( '%1$sUpgrade%2$s to All in One SEO Pack Pro for increased SEO compatibility for your products.', 'all-in-one-seo-pack' ), sprintf( '
    ', esc_url( 'https://semperplugins.com/plugins/all-in-one-seo-pack-pro-version/?loc=woo' ) ), '' ) - ); - - } elseif ( ! class_exists( 'WooCommerce' ) && ! empty( $aioseop_woo_upgrade_notice_dismissed ) ) { - delete_user_meta( get_current_user_id(), 'aioseop_woo_upgrade_notice_dismissed' ); + /** + * WooCommerce Upgrade Notice + * + * @since ? + * @since 3.0 Changed to AIOSEOP Notices. + */ + public function woo_upgrade_notice() { + if ( class_exists( 'WooCommerce' ) && current_user_can( 'manage_options' ) && ! AIOSEOPPRO ) { + aioseop_notice_activate_pro_promo_woocommerce(); + } else { + aioseop_notice_disable_woocommerce_detected_on_nonpro(); } } diff --git a/inc/aioseop_functions.php b/inc/aioseop_functions.php index 1fc3961ee..b8aa34dd2 100644 --- a/inc/aioseop_functions.php +++ b/inc/aioseop_functions.php @@ -1017,11 +1017,6 @@ function aioseop_update_yst_detected_notice() { update_user_meta( get_current_user_id(), 'aioseop_yst_detected_notice_dismissed', true ); } -function aioseop_woo_upgrade_notice_dismissed() { - - update_user_meta( get_current_user_id(), 'aioseop_woo_upgrade_notice_dismissed', true ); -} - function aioseop_sitemap_max_url_notice_dismissed() { update_user_meta( get_current_user_id(), 'aioseop_sitemap_max_url_notice_dismissed', true ); diff --git a/tests/classes/aioseop-notices/notices/test-pro-promo-woocommerce.php b/tests/classes/aioseop-notices/notices/test-pro-promo-woocommerce.php new file mode 100644 index 000000000..e6dddfdaa --- /dev/null +++ b/tests/classes/aioseop-notices/notices/test-pro-promo-woocommerce.php @@ -0,0 +1,37 @@ + Date: Thu, 21 Mar 2019 02:38:26 +0530 Subject: [PATCH 021/121] Facebook SSL og:image only works if they have a non-SSL version cached (#2299) --- modules/aioseop_opengraph.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/aioseop_opengraph.php b/modules/aioseop_opengraph.php index ca62b29e4..94e687f74 100644 --- a/modules/aioseop_opengraph.php +++ b/modules/aioseop_opengraph.php @@ -1485,6 +1485,12 @@ function add_meta() { $meta['google+'] = array( 'thumbnail' => 'image' ); } + // https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/1848 + if ( is_ssl() ) { + $meta['facebook'] += array( 'thumbnail_1' => 'og:image:secure_url' ); + $thumbnail_1 = $thumbnail; + } + $tags = array( 'facebook' => array( 'name' => 'property', 'value' => 'content' ), 'twitter' => array( 'name' => 'name', 'value' => 'content' ), From 5a2d96a76cd8b4bd21526e239b367a5513e49c2c Mon Sep 17 00:00:00 2001 From: contactashish13 Date: Thu, 21 Mar 2019 02:40:12 +0530 Subject: [PATCH 022/121] Non-existing /sitemap_XXX URLs navigate to empty sitemap instead of 404 (#2272) * added info for testing * Non-existing /sitemap_XXX URLs navigate to empty sitemap instead of 404 * returned null for consistency * travis failing * Revert "travis failing" This reverts commit ce99135678221591389d3c003762c90b8bf0b38a. * change phpdoc to reflect null return * code changed for pedantic reasons * Dev-Change phpDoc Adds since notes for changes in a function's expected return values. --- modules/aioseop_sitemap.php | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/modules/aioseop_sitemap.php b/modules/aioseop_sitemap.php index c3b576961..1ca87778a 100644 --- a/modules/aioseop_sitemap.php +++ b/modules/aioseop_sitemap.php @@ -1435,6 +1435,9 @@ public function log_stats( $sitemap_type = 'static', $compressed = false, $dynam /** * Handle outputting of dynamic sitemaps, logging. * + * @since ? + * @since 3.0 Show 404 template for empty content. #2190 + * * @param $query */ public function sitemap_output_hook( $query ) { @@ -1447,6 +1450,7 @@ public function sitemap_output_hook( $query ) { } $this->start_memory_usage = memory_get_peak_usage(); $sitemap_type = $query->query_vars[ "{$this->prefix}path" ]; + $gzipped = false; if ( $this->substr( $sitemap_type, - 3 ) === '.gz' ) { $gzipped = true; @@ -1468,7 +1472,22 @@ public function sitemap_output_hook( $query ) { if ( $gzipped ) { ob_start(); } - $this->do_rewrite_sitemap( $sitemap_type, $page ); + + $content = $this->do_rewrite_sitemap( $sitemap_type, $page ); + + // if the sitemap has no content, it's probabaly invalid and is being called directly. + // @issue https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/2190 + if ( empty( $content ) ) { + $query->set_404(); + status_header( 404 ); + header( "Content-Type: text/html; charset=$blog_charset", true ); + nocache_headers(); + include( get_404_template() ); + exit(); + } + + echo $content; + if ( $gzipped ) { // TODO Add esc_* function. echo gzencode( ob_get_clean() ); @@ -1546,14 +1565,18 @@ public function get_sitemap_data( $sitemap_type, $page = 0 ) { * * Output sitemaps dynamically based on rewrite rules. * + * @since ? + * @since 3.0 Return a (string) value. #2190 + * * @param $sitemap_type * @param int $page + * @return string */ public function do_rewrite_sitemap( $sitemap_type, $page = 0 ) { $this->add_post_types(); $comment = 'dynamically'; // TODO Add esc_* or wp_kses function. - echo $this->do_build_sitemap( $sitemap_type, $page, '', $comment ); + return $this->do_build_sitemap( $sitemap_type, $page, '', $comment ); } /** @@ -1987,6 +2010,9 @@ public function do_build_sitemap( $sitemap_type, $page = 0, $filename = '', $com if ( ( 'root' === $sitemap_type ) && ! empty( $this->options[ "{$this->prefix}indexes" ] ) ) { return $this->build_sitemap_index( $sitemap_data, sprintf( $comment, $filename ) ); } else { + if ( empty( $sitemap_data ) ) { + return ''; + } return $this->build_sitemap( $sitemap_data, $sitemap_type, sprintf( $comment, $filename ) ); } } From b516594b1df2c223eef61fc346ed59b66943eadc Mon Sep 17 00:00:00 2001 From: EkoJR Date: Wed, 20 Mar 2019 14:11:41 -0700 Subject: [PATCH 023/121] Fixed whitespace in Settings & Edit Page (#2260) * Fixed whitespace in Settings & Edit Page * Dev-Fix help link with IE * Dev-Fix RTL style --- css/modules/aioseop_module.css | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/css/modules/aioseop_module.css b/css/modules/aioseop_module.css index f3b166049..4a10c22d4 100644 --- a/css/modules/aioseop_module.css +++ b/css/modules/aioseop_module.css @@ -27,8 +27,8 @@ .aioseop_help_text_link:active { text-align: left; float: left; - max-width: 300px; - min-width: 1px; + max-width: 30px; + min-width: 20px; padding-top: 2px; outline: none; color: #888; @@ -119,6 +119,8 @@ div.aioseop_tip_icon:before { .aioseop_meta_box_help:active { float: right; text-align: right; + min-width: 56px; + max-width: 90px; text-decoration: none; height: 15px; padding-top: 1px; @@ -139,9 +141,10 @@ div.aioseop_tip_icon:before { float: left; text-align: left; font-family: 'Open Sans', sans-serif; + padding: 2px 0; width: 81%; min-width: 120px; - max-width: 230px; + max-width: 250px; cursor: default; } @@ -173,6 +176,7 @@ div.aioseop_tip_icon:before { line-height: 25px; width: 95%; max-width: 600px; + min-height: 36px; } .aioseop_help_text_div { @@ -294,6 +298,7 @@ div.aioseop_tip_icon:before { Times, serif; font-weight: normal; + min-height: 18px; padding: 7px 10px; margin: 0; line-height: 1; @@ -360,12 +365,12 @@ div.aioseop_tip_icon:before { .aioseop_option_label { float: left; margin: 0; - min-width: 150px; - width: 37%; - max-width: 270px; padding-top: 3px; padding-bottom: 3px; - height: 67px !important; /*added for certain language support*/ + width: 37%; + min-width: 150px; + max-width: 360px; + min-height: 30px; } .aioseop_metabox_text h2 { @@ -1372,7 +1377,6 @@ div.sfwd_debug_error { } .postbox-container .aioseop_input { - display: block; margin-bottom: 10px; padding: 0; } @@ -1427,10 +1431,19 @@ div#aiosp_snippet_wrapper { margin-bottom: 15px; } +#aiosp_snippet_wrapper > .aioseop_input:first-child { + margin-bottom: 0px; +} + div#aiosp_snippet_wrapper .aioseop_option_label { height: auto !important; } +#aiosp_snippet_wrapper > .aioseop_input:first-child .aioseop_option_label { + padding: 0; + min-height: inherit; +} + div#aiosp_snippet_wrapper .aioseop_input.aioseop_top_label .aioseop_option_input { margin: 0; } From a45a020306af80b348bbce8db265f5e4a0dee436 Mon Sep 17 00:00:00 2001 From: Michael Torbert Date: Wed, 20 Mar 2019 17:44:02 -0400 Subject: [PATCH 024/121] 3.0-dev --- readme.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.txt b/readme.txt index 6058df627..201753561 100644 --- a/readme.txt +++ b/readme.txt @@ -3,7 +3,7 @@ Contributors: hallsofmontezuma, semperplugins, wpsmort, arnaudbroes Tags: SEO, Google Search Console, XML Sitemap, meta description, meta title, noindex Requires at least: 4.6 Tested up to: 5.1 -Stable tag: 2.12 +Stable tag: 3.0-dev License: GPLv2 or later Requires PHP: 5.2.4 From 8493de1d450be8ff90dff655f2fd5e44bec11afd Mon Sep 17 00:00:00 2001 From: Michael Torbert Date: Wed, 20 Mar 2019 17:44:16 -0400 Subject: [PATCH 025/121] 3.0-dev --- all_in_one_seo_pack.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/all_in_one_seo_pack.php b/all_in_one_seo_pack.php index 4cdbb682b..1bb31d5ea 100644 --- a/all_in_one_seo_pack.php +++ b/all_in_one_seo_pack.php @@ -4,7 +4,7 @@ Plugin Name: All In One SEO Pack Plugin URI: https://semperplugins.com/all-in-one-seo-pack-pro-version/ Description: Out-of-the-box SEO for your WordPress blog. Features like XML Sitemaps, SEO for custom post types, SEO for blogs or business sites, SEO for ecommerce sites, and much more. More than 50 million downloads since 2007. -Version: 2.12 +Version: 3.0-dev Author: Michael Torbert Author URI: https://semperplugins.com/all-in-one-seo-pack-pro-version/ Text Domain: all-in-one-seo-pack From 1083017c12dfad4d0936e2dbb7bf937f8e17cfaa Mon Sep 17 00:00:00 2001 From: Michael Torbert Date: Wed, 20 Mar 2019 17:44:40 -0400 Subject: [PATCH 026/121] 3.0-dev --- all_in_one_seo_pack.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/all_in_one_seo_pack.php b/all_in_one_seo_pack.php index 1bb31d5ea..d42d196ed 100644 --- a/all_in_one_seo_pack.php +++ b/all_in_one_seo_pack.php @@ -32,14 +32,14 @@ * The original WordPress SEO plugin. * * @package All-in-One-SEO-Pack - * @version 2.12 + * @version 3.0-dev */ if ( ! defined( 'AIOSEOPPRO' ) ) { define( 'AIOSEOPPRO', false ); } if ( ! defined( 'AIOSEOP_VERSION' ) ) { - define( 'AIOSEOP_VERSION', '2.12' ); + define( 'AIOSEOP_VERSION', '3.0-dev' ); } global $aioseop_plugin_name; $aioseop_plugin_name = 'All in One SEO Pack'; From b9b442ba29a29f0f7a90c7e93d595e4b9b0f5d18 Mon Sep 17 00:00:00 2001 From: Michael Torbert Date: Fri, 22 Mar 2019 14:13:32 -0400 Subject: [PATCH 027/121] requires 4.7+ #2311 --- readme.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.txt b/readme.txt index 201753561..6cdfb1a0c 100644 --- a/readme.txt +++ b/readme.txt @@ -1,7 +1,7 @@ === All in One SEO Pack === Contributors: hallsofmontezuma, semperplugins, wpsmort, arnaudbroes Tags: SEO, Google Search Console, XML Sitemap, meta description, meta title, noindex -Requires at least: 4.6 +Requires at least: 4.7 Tested up to: 5.1 Stable tag: 3.0-dev License: GPLv2 or later From 6f85663923af4a09a421543b5a07a51502c55cdd Mon Sep 17 00:00:00 2001 From: EkoJR Date: Fri, 22 Mar 2019 11:24:49 -0700 Subject: [PATCH 028/121] Add review plugin notice to AIOSEOP Notices class (#2295) * Add review plugin notice to AIOSEOP Notices class i-61 * Add Testcase for activation_review_plugin notice * Dev-Clean run grunt * Dev-Change wording in rating notice * Dev-Fix testcase * Dev-Fix wording in rating notice * Dev-Change notice action links * Dev-Change notice wording * Dev-Change review edits --- admin/functions-notice.php | 73 +++++++++++++++++++ all_in_one_seo_pack.php | 4 + .../notices/test-plugin-review.php | 36 +++++++++ 3 files changed, 113 insertions(+) create mode 100644 tests/classes/aioseop-notices/notices/test-plugin-review.php diff --git a/admin/functions-notice.php b/admin/functions-notice.php index 3b08312ce..fbf8047c7 100644 --- a/admin/functions-notice.php +++ b/admin/functions-notice.php @@ -85,4 +85,77 @@ function aioseop_notice_disable_woocommerce_detected_on_nonpro() { global $aioseop_notices; $aioseop_notices->deactivate_notice( 'woocommerce_detected' ); } + + /** + * Set Notice on Activation to Review Plugin + * + * A delayed notice that is set during activation, or initialization (old installs), + * to later display a review/rate AIOSEOP plugin. Delay time: 12 days. + * Delay "...give me a week." 5 days + * + * @since 3.0 + * + * @global AIOSEOP_Notices $aioseop_notices + * + * @param boolean $update Updates the notice with new content and configurations. + * @param boolean $reset Notice are re-initiated. + */ + function aioseop_notice_set_activation_review_plugin( $update = false, $reset = false ) { + global $aioseop_notices; + + // TODO Optimize - Create a callback function/method to store most of the configurations (Avoid Database concept). + // Dynamic variable could be stored in the database. Config functions could go into a config file/folder. + $notice = aioseop_notice_review_plugin(); + + if ( $aioseop_notices->insert_notice( $notice ) ) { + // aioseop_footer_set_review(); + } elseif ( $update ) { + $aioseop_notices->update_notice( $notice ); + + if ( $reset ) { + $aioseop_notices->activate_notice( $notice['slug'] ); + // aioseop_footer_remove_review(); + // aioseop_footer_set_review(); + } + } + } + + /** + * Notice - Review Plugin + * + * @since 3.0 + * + * @return array Notice configuration. + */ + function aioseop_notice_review_plugin() { + return array( + 'slug' => 'activation_review_plugin', + 'delay_time' => 1036800, + 'target' => 'user', + 'screens' => array(), + 'class' => 'notice-info', + 'message' => __( 'You have been using All in One SEO Pack for a while now. That is awesome! If you like All in One SEO Pack, then please leave us a 5-star rating. Huge thanks in advance!', 'all-in-one-seo-pack' ), + 'action_options' => array( + array( + 'time' => 0, + 'text' => __( 'Add a review', 'all-in-one-seo-pack' ), + 'link' => 'https://wordpress.org/support/plugin/all-in-one-seo-pack/reviews?rate=5#new-post', + 'dismiss' => false, + 'class' => '', + ), + array( + 'text' => __( 'Remind me later', 'all-in-one-seo-pack' ), + 'time' => 432000, + 'dismiss' => false, + 'class' => '', + ), + array( + 'time' => 0, + 'text' => __( 'No, thanks', 'all-in-one-seo-pack' ), + 'dismiss' => true, + 'class' => '', + ), + ), + ); + } } diff --git a/all_in_one_seo_pack.php b/all_in_one_seo_pack.php index d42d196ed..91c362c1b 100644 --- a/all_in_one_seo_pack.php +++ b/all_in_one_seo_pack.php @@ -266,6 +266,9 @@ function aioseop_activate() { } $aiosp_activation = true; + require_once( AIOSEOP_PLUGIN_DIR . 'admin/class-aioseop-notices.php' ); + aioseop_notice_set_activation_review_plugin( false, true ); + // These checks might be duplicated in the function being called. if ( ! is_network_admin() || ! isset( $_GET['activate-multi'] ) ) { set_transient( '_aioseop_activation_redirect', true, 30 ); // Sets 30 second transient for welcome screen redirect on activation. @@ -438,6 +441,7 @@ function aioseop_init_class() { add_action( 'init', array( $aiosp, 'add_hooks' ) ); add_action( 'admin_init', array( $aioseop_updates, 'version_updates' ), 11 ); + aioseop_notice_set_activation_review_plugin(); if ( defined( 'DOING_AJAX' ) && ! empty( $_POST ) && ! empty( $_POST['action'] ) && 'aioseop_ajax_scan_header' === $_POST['action'] ) { remove_action( 'init', array( $aiosp, 'add_hooks' ) ); diff --git a/tests/classes/aioseop-notices/notices/test-plugin-review.php b/tests/classes/aioseop-notices/notices/test-plugin-review.php new file mode 100644 index 000000000..a23a90c88 --- /dev/null +++ b/tests/classes/aioseop-notices/notices/test-plugin-review.php @@ -0,0 +1,36 @@ + Date: Sat, 23 Mar 2019 00:02:56 +0530 Subject: [PATCH 029/121] Use jQuery Tabs on Edit Post screen (#2290) * added info for testing * Use jQuery Tabs on Edit Post screen * grunt * mimic old style * PR comments https://github.com/semperfiwebdesign/all-in-one-seo-pack/pull/2290#issuecomment-472989549 * PR comments https://github.com/semperfiwebdesign/all-in-one-seo-pack/pull/2290#issuecomment-473942305 * PR comments https://github.com/semperfiwebdesign/all-in-one-seo-pack/pull/2290#pullrequestreview-216479600 * Dev-Change wpcs long line * Dev-Fix wp_style_is param --- admin/aioseop_module_class.php | 22 +++++---- css/modules/aioseop_module.css | 85 +++++++++++++++++--------------- js/modules/aioseop_module.js | 29 ++--------- js/modules/aioseop_module.min.js | 2 +- 4 files changed, 62 insertions(+), 76 deletions(-) diff --git a/admin/aioseop_module_class.php b/admin/aioseop_module_class.php index 2c2897353..0adc0bc5f 100644 --- a/admin/aioseop_module_class.php +++ b/admin/aioseop_module_class.php @@ -1737,15 +1737,18 @@ function admin_enqueue_styles( $hook_suffix ) { wp_enqueue_style( 'aioseop-module-style-rtl', AIOSEOP_PLUGIN_URL . 'css/modules/aioseop_module-rtl.css', array( 'aioseop-module-style' ), AIOSEOP_VERSION ); } - // Uses WP Scripts to load the current platform version of jQuery UI CSS . - $wp_scripts = wp_scripts(); - wp_enqueue_style( - 'aioseop-jquery-ui-css', - 'https://ajax.googleapis.com/ajax/libs/jqueryui/' . $wp_scripts->registered['jquery-ui-core']->ver . '/themes/smoothness/jquery-ui.min.css', - false, - AIOSEOP_VERSION, - false - ); + // Uses WP Scripts to load the current platform version of jQuery UI CSS. + // Loads only if it is not already loaded in order to not cause a conflict with a generic version. + if ( ! wp_style_is( 'aioseop-jquery-ui', 'registered' ) && ! wp_style_is( 'aioseop-jquery-ui', 'enqueued' ) ) { + $wp_scripts = wp_scripts(); + wp_enqueue_style( + 'aioseop-jquery-ui', + '//ajax.googleapis.com/ajax/libs/jqueryui/' . $wp_scripts->registered['jquery-ui-core']->ver . '/themes/smoothness/jquery-ui.min.css', + false, + AIOSEOP_VERSION, + false + ); + } } /** @@ -1770,6 +1773,7 @@ function admin_enqueue_styles( $hook_suffix ) { public function admin_enqueue_scripts( $hook_suffix ) { wp_enqueue_script( 'sack' ); wp_enqueue_script( 'jquery' ); + wp_enqueue_script( 'jquery-ui-tabs' ); wp_enqueue_script( 'media-upload' ); wp_enqueue_script( 'thickbox' ); wp_enqueue_script( 'common' ); diff --git a/css/modules/aioseop_module.css b/css/modules/aioseop_module.css index 4a10c22d4..8e196ac6b 100644 --- a/css/modules/aioseop_module.css +++ b/css/modules/aioseop_module.css @@ -1202,60 +1202,21 @@ div.aioseop_notice a.aioseop_dismiss_link { width: 98%; } -.aioseop_tabs { - padding-top: 6px; -} - -.aioseop_tabs.hide, -.aioseop_header_tabs.hide { - display: block !important; -} - -.aioseop_header_tabs li { - display: inline; - padding: 0; - margin: 0; -} - -.aioseop_header_tabs { - margin: 0; -} - -.aioseop_header_nav { - margin: 0; -} - -.aioseop_header_tabs li a.aioseop_header_tab.active { - background-color: rgb(255, 255, 255); - border-bottom-color: rgba(255, 255, 255, 0.5); - font-weight: bold; -} - .aioseop_header_tabs li a.aioseop_header_tab { font-size: 14px; line-height: 37px; text-decoration: none; - margin: 5px 5px 0 0; - padding: 10px; cursor: pointer; -webkit-border-top-right-radius: 3px; -webkit-border-top-left-radius: 3px; border-top-right-radius: 3px; border-top-left-radius: 3px; - background-color: #e5e5e5; - border: 1px solid #ccc; + border-bottom: none !important; + padding: 0em 0.5em !important; color: #5F5F5F; } -.aioseop_header_tabs li:first-child a.aioseop_header_tab { - border-left: solid 1px #CCC; - margin-left: 5px; -} - .aioseop_tab { - border: solid 1px #CCC; - background-color: rgb(255, 255, 255); - background-color: rgba(255, 255, 255, 0.5); padding: 10px; } @@ -1269,6 +1230,48 @@ div.aioseop_notice a.aioseop_dismiss_link { vertical-align: bottom; } +.aioseop_tabs.ui-widget-content { + background: none !important; +} + +.aioseop_tab.ui-widget-content { + border: 1px solid #aaa !important; +} + +.aioseop_tab.ui-widget-content a.aioseop_help_text_link { + color: #888 !important; +} + +.aioseop_tabs.ui-widget { + font-size: 13px !important; + border: none !important; +} + +.aioseop_tabs .ui-widget-header { + border: none !important; + background: none !important; + border-bottom-right-radius: 0px !important; + border-bottom-left-radius: 0px !important; +} + +.aioseop_tabs ul { + margin-left: .2em !important; +} + +.aioseop_tabs .ui-tabs .ui-tabs-panel { + border-width: inherit !important; +} + +.aioseop_tabs .ui-state-default, +.aioseop_tabs .ui-widget-content .ui-state-default, +.aioseop_tabs .ui-widget-header .ui-state-default { + background-image: none !important; +} + +.aioseop_tabs .ui-state-active a { + font-weight: bold !important; +} + .aiosp_delete { background-image: url('../../images/delete.png'); display: inline-block; diff --git a/js/modules/aioseop_module.js b/js/modules/aioseop_module.js index bf0fef23f..d0fd49ec2 100644 --- a/js/modules/aioseop_module.js +++ b/js/modules/aioseop_module.js @@ -540,31 +540,10 @@ jQuery( document ).ready( } ); - /** - * @since 1.0.0 - */ - jQuery( ".aioseop_tab:not(:first)" ).hide(); - - /** - * @since 1.0.0 - */ - jQuery( ".aioseop_tab:first" ).show(); - - /** - * @since 1.0.0 - * @return boolean. - */ - jQuery( "a.aioseop_header_tab" ).click( - function() { - var stringref = jQuery( this ).attr( "href" ).split( '#' )[1]; - jQuery( '.aioseop_tab:not(#' + stringref + ')' ).hide( 'slow' ); - jQuery( '.aioseop_tab#' + stringref ).show( 'slow' ); - jQuery( '.aioseop_header_tab[href!="#' + stringref + '"]' ).removeClass( 'active' ); - jQuery( '.aioseop_header_tab[href="#' + stringref + '"]' ).addClass( 'active' ); - return false; - } - ); - + jQuery('.aioseop_tabs').tabs({ + hide: true, + show: true + }); jQuery( "div#aiosp_robots_default_metabox" ) .delegate( diff --git a/js/modules/aioseop_module.min.js b/js/modules/aioseop_module.min.js index f1ea741a4..f975d2e31 100644 --- a/js/modules/aioseop_module.min.js +++ b/js/modules/aioseop_module.min.js @@ -1 +1 @@ -function toggleVisibility(e){var a=document.getElementById(e);"block"===a.style.display?a.style.display="none":a.style.display="block"}function aioseop_get_field_value(e){if(0===e.length)return e;var a=jQuery("[name="+e+"]");if(0===a.length)return e;var o=a.attr("type");return"checkbox"!==o&&"radio"!==o||(a=jQuery("input[name="+e+"]:checked")),a.val()}function aioseop_get_field_values(e){var a=[],o=jQuery("[name="+e+"]");if(0===o.length)return e;var t=o.attr("type");return"checkbox"!==t&&"radio"!==t||jQuery("input[name="+e+"]:checked").each(function(){a.push(jQuery(this).val())}),a.length<=0&&a.push(o.val()),a}function aioseop_eval_condshow_logic(e){var a,o;if("object"==typeof e)switch(a=e.lhs,o=e.rhs,null!==a&&"object"==typeof a&&(a=aioseop_eval_condshow_logic(a)),null!==o&&"object"==typeof o&&(o=aioseop_eval_condshow_logic(o)),a=aioseop_get_field_value(a),o=aioseop_get_field_value(o),e.op){case"NOT":return!a;case"AND":return a&&o;case"OR":return a||o;case"==":return a===o;case"!=":return a!==o;default:return null}return e}function aioseop_do_condshow_match(e,a){if(void 0===a)return!1;var t=!0;return jQuery.each(a,function(e,a){if("object"==typeof a)aioseop_eval_condshow_logic(a)||(t=!1);else{var o=[];e.match(/\\\[\\\]/)?(o=aioseop_get_field_values(e),jQuery.inArray(a,o,0)<0&&(t=!1)):(o=aioseop_get_field_value(e))!=a&&(t=!1)}}),t?jQuery("#"+e+"_wrapper").show():jQuery("#"+e+"_wrapper").hide(),t}function aioseop_add_condshow_handlers(o,t){void 0!==t&&jQuery.each(t,function(e,a){jQuery("[name="+e+"]").bind("change keyup",function(){aioseop_do_condshow_match(o,t)})})}function aioseop_do_condshow(e){void 0!==aiosp_data.condshow&&jQuery.each(aiosp_data.condshow,function(e,a){aioseop_do_condshow_match(e,a),aioseop_add_condshow_handlers(e,a)})}function aiosp_store_radio(){var e={};jQuery('input[type="radio"]').each(function(){jQuery(this).is(":checked")&&(e[jQuery(this).attr("name")]=jQuery(this).val()),jQuery(document).data("radioshack",e)})}function aiosp_reclick_radio(){var e=jQuery(document).data("radioshack");for(var a in e)jQuery('input[name="'+a+'"]').filter('[value="'+e[a]+'"]').trigger("click");jQuery(".wrap").unbind("mouseup")}function aioseop_handle_ajax_call(e,a,o,t){var i=new sack(ajaxurl);i.execute=1,i.method="POST",i.setVar("action",e),i.setVar("settings",a),i.setVar("options",o),void 0!==t&&(i.onCompletion=t),i.setVar("nonce-aioseop",jQuery('input[name="nonce-aioseop"]').val()),i.setVar("nonce-aioseop-edit",jQuery('input[name="nonce-aioseop-edit"]').val()),i.onError=function(){alert("Ajax error on saving.")},i.runAJAX()}function aioseop_handle_post_url(a,o,t,i,s){jQuery("div#aiosp_"+o).fadeOut("fast",function(){var e=' Please wait...';jQuery("div#aiosp_"+o).fadeIn("fast",function(){s?jQuery.ajax({url:ajaxurl,method:"POST",dataType:"json",data:{action:a,options:t,settings:o,"nonce-aioseop":jQuery('input[name="nonce-aioseop"]').val(),"nonce-aioseop-edit":jQuery('input[name="nonce-aioseop-edit"]').val()},success:function(e){i&&i(e)}}):aioseop_handle_ajax_call(a,o,t,i)}),jQuery("div#aiosp_"+o).html(e)})}function aioseop_is_overflowed(e){return e.scrollHeight>e.clientHeight||e.scrollWidth>e.clientWidth}function aioseop_overflow_border(e){aioseop_is_overflowed(e)?e.className="aioseop_option_div aioseop_overflowed":e.className="aioseop_option_div"}function aiospinitAll(){aiospinitSocialMetaInPosts(jQuery),aiospinitCalendar()}function aiospinitCalendar(){0 ul"}))})}),!1}),jQuery(".all-in-one-seo_page_all-in-one-seo-pack-pro-modules-aioseop_feature_manager #aiosp_settings_form .aioseop_settings_left").delegate("input[name='Submit']","click",function(e){return e.preventDefault(),!1}),jQuery(".all-in-one-seo_page_all-in-one-seo-pack-pro-modules-aioseop_feature_manager #aiosp_settings_form").delegate("input[name='Submit']","click",function(e){return e.preventDefault(),aioseop_handle_post_url("aioseop_ajax_save_settings","ajax_settings_message",jQuery("form#aiosp_settings_form").serialize(),function(){jQuery(".wp-has-current-submenu").fadeIn("fast",function(){aioseop_handle_ajax_call("aioseop_ajax_get_menu_links","ajax_settings_message",jQuery.param({target:".wp-has-current-submenu > ul"}))})}),!1});jQuery("div#aiosp_sitemap_addl_pages_metabox").delegate("input[name='Submit']","click",function(){return aioseop_handle_post_url("aioseop_ajax_save_url","sitemap_addl_pages",jQuery("div#aiosp_sitemap_addl_pages_metabox input, div#aiosp_sitemap_addl_pages_metabox select").serialize()),!1}),jQuery("div#aiosp_video_sitemap_addl_pages_metabox").delegate("input[name='Submit']","click",function(){return aioseop_handle_post_url("aioseop_ajax_save_url","video_sitemap_addl_pages",jQuery("div#aiosp_video_sitemap_addl_pages_metabox input, div#aiosp_video_sitemap_addl_pages_metabox select").serialize()),!1}),jQuery("div#aiosp_sitemap_addl_pages_metabox").delegate("a.aiosp_delete_url","click",function(e){return e.preventDefault(),aioseop_handle_post_url("aioseop_ajax_delete_url","sitemap_addl_pages",jQuery(this).attr("title")),!1}),jQuery("div#aiosp_video_sitemap_addl_pages_metabox").delegate("a.aiosp_delete_url","click",function(e){return e.preventDefault(),aioseop_handle_post_url("aioseop_ajax_delete_url","video_sitemap_addl_pages",jQuery(this).attr("title")),!1}),jQuery("div#aiosp_opengraph_scan_header").delegate("input[name='aiosp_opengraph_scan_header']","click",function(e){return e.preventDefault(),aioseop_handle_post_url("aioseop_ajax_scan_header","opengraph_scan_header",jQuery("div#aiosp_opengraph_scan_header").serialize()),!1}),jQuery('input[name="aiosp_sitemap_posttypes[]"][value="all"], input[name="aiosp_video_sitemap_posttypes[]"][value="all"], input[name="aiosp_sitemap_taxonomies[]"][value="all"], input[name="aiosp_video_sitemap_taxonomies[]"][value="all"]').click(function(){jQuery(this).parents("div:eq(0)").find(":checkbox").prop("checked",this.checked)}),jQuery('input[name="aiosp_sitemap_posttypes[]"][value!="all"], input[name="aiosp_video_sitemap_posttypes[]"][value!="all"], input[name="aiosp_sitemap_taxonomies[]"][value!="all"], input[name="aiosp_video_sitemap_taxonomies[]"][value!="all"]').click(function(){this.checked||jQuery(this).parents("div:eq(0)").find('input[value="all"]:checkbox').prop("checked",this.checked)}),jQuery(".aioseop_tab:not(:first)").hide(),jQuery(".aioseop_tab:first").show(),jQuery("a.aioseop_header_tab").click(function(){var e=jQuery(this).attr("href").split("#")[1];return jQuery(".aioseop_tab:not(#"+e+")").hide("slow"),jQuery(".aioseop_tab#"+e).show("slow"),jQuery('.aioseop_header_tab[href!="#'+e+'"]').removeClass("active"),jQuery('.aioseop_header_tab[href="#'+e+'"]').addClass("active"),!1}),jQuery("div#aiosp_robots_default_metabox").delegate("a.aiosp_robots_delete_rule","click",function(e){return e.preventDefault(),aioseop_handle_post_url("aioseop_ajax_delete_rule","robots_rules",jQuery(this).attr("data-id"),function(){window.location.reload()}),!1}),jQuery("div#aiosp_robots_default_metabox").delegate("a.aiosp_robots_edit_rule","click",function(e){return e.preventDefault(),jQuery('input[name="aiosp_robots_agent"]').val(jQuery(this).attr("data-agent")),jQuery('select[name="aiosp_robots_type"]').val(jQuery(this).attr("data-type")),jQuery('input[name="aiosp_robots_path"]').val(jQuery(this).attr("data-path")),jQuery("input.add-edit-rule").val(jQuery(".aioseop_table").attr("data-edit-label")),jQuery("input.edit-rule-id").val(jQuery(this).attr("data-id")),!1}),jQuery("a.aiosp_robots_physical").on("click",function(e){return e.preventDefault(),aioseop_handle_post_url("aioseop_ajax_robots_physical","robots_physical_import_delete",jQuery(this).attr("data-action"),function(e){e.data&&e.data.message&&alert(e.data.message),window.location.reload()},!0),!1}),aiospinitAll()}),jQuery.fn.aioseopImageUploader=function(e){var a=this;a.options=jQuery.extend({success:void 0},e),a.target=jQuery(a).next(),a.uploader=wp.media({title:"Choose Image",button:{text:"Choose Image"},multiple:!1}),a.onSelect=function(){var e=a.uploader.state().get("selection").first().toJSON().url;0<=a.target.length&&jQuery(a.target).val(e),void 0!==a.options.success&&a.options.success(e,a)},a.onClick=function(e){e.preventDefault(),a.uploader.open()},a.uploader.on("select",a.onSelect),jQuery(a).click(a.onClick)}; \ No newline at end of file +function toggleVisibility(e){var a=document.getElementById(e);"block"===a.style.display?a.style.display="none":a.style.display="block"}function aioseop_get_field_value(e){if(0===e.length)return e;var a=jQuery("[name="+e+"]");if(0===a.length)return e;var o=a.attr("type");return"checkbox"!==o&&"radio"!==o||(a=jQuery("input[name="+e+"]:checked")),a.val()}function aioseop_get_field_values(e){var a=[],o=jQuery("[name="+e+"]");if(0===o.length)return e;var t=o.attr("type");return"checkbox"!==t&&"radio"!==t||jQuery("input[name="+e+"]:checked").each(function(){a.push(jQuery(this).val())}),a.length<=0&&a.push(o.val()),a}function aioseop_eval_condshow_logic(e){var a,o;if("object"==typeof e)switch(a=e.lhs,o=e.rhs,null!==a&&"object"==typeof a&&(a=aioseop_eval_condshow_logic(a)),null!==o&&"object"==typeof o&&(o=aioseop_eval_condshow_logic(o)),a=aioseop_get_field_value(a),o=aioseop_get_field_value(o),e.op){case"NOT":return!a;case"AND":return a&&o;case"OR":return a||o;case"==":return a===o;case"!=":return a!==o;default:return null}return e}function aioseop_do_condshow_match(e,a){if(void 0===a)return!1;var t=!0;return jQuery.each(a,function(e,a){if("object"==typeof a)aioseop_eval_condshow_logic(a)||(t=!1);else{var o=[];e.match(/\\\[\\\]/)?(o=aioseop_get_field_values(e),jQuery.inArray(a,o,0)<0&&(t=!1)):(o=aioseop_get_field_value(e))!=a&&(t=!1)}}),t?jQuery("#"+e+"_wrapper").show():jQuery("#"+e+"_wrapper").hide(),t}function aioseop_add_condshow_handlers(o,t){void 0!==t&&jQuery.each(t,function(e,a){jQuery("[name="+e+"]").bind("change keyup",function(){aioseop_do_condshow_match(o,t)})})}function aioseop_do_condshow(e){void 0!==aiosp_data.condshow&&jQuery.each(aiosp_data.condshow,function(e,a){aioseop_do_condshow_match(e,a),aioseop_add_condshow_handlers(e,a)})}function aiosp_store_radio(){var e={};jQuery('input[type="radio"]').each(function(){jQuery(this).is(":checked")&&(e[jQuery(this).attr("name")]=jQuery(this).val()),jQuery(document).data("radioshack",e)})}function aiosp_reclick_radio(){var e=jQuery(document).data("radioshack");for(var a in e)jQuery('input[name="'+a+'"]').filter('[value="'+e[a]+'"]').trigger("click");jQuery(".wrap").unbind("mouseup")}function aioseop_handle_ajax_call(e,a,o,t){var i=new sack(ajaxurl);i.execute=1,i.method="POST",i.setVar("action",e),i.setVar("settings",a),i.setVar("options",o),void 0!==t&&(i.onCompletion=t),i.setVar("nonce-aioseop",jQuery('input[name="nonce-aioseop"]').val()),i.setVar("nonce-aioseop-edit",jQuery('input[name="nonce-aioseop-edit"]').val()),i.onError=function(){alert("Ajax error on saving.")},i.runAJAX()}function aioseop_handle_post_url(a,o,t,i,s){jQuery("div#aiosp_"+o).fadeOut("fast",function(){var e=' Please wait...';jQuery("div#aiosp_"+o).fadeIn("fast",function(){s?jQuery.ajax({url:ajaxurl,method:"POST",dataType:"json",data:{action:a,options:t,settings:o,"nonce-aioseop":jQuery('input[name="nonce-aioseop"]').val(),"nonce-aioseop-edit":jQuery('input[name="nonce-aioseop-edit"]').val()},success:function(e){i&&i(e)}}):aioseop_handle_ajax_call(a,o,t,i)}),jQuery("div#aiosp_"+o).html(e)})}function aioseop_is_overflowed(e){return e.scrollHeight>e.clientHeight||e.scrollWidth>e.clientWidth}function aioseop_overflow_border(e){aioseop_is_overflowed(e)?e.className="aioseop_option_div aioseop_overflowed":e.className="aioseop_option_div"}function aiospinitAll(){aiospinitSocialMetaInPosts(jQuery),aiospinitCalendar()}function aiospinitCalendar(){0 ul"}))})}),!1}),jQuery(".all-in-one-seo_page_all-in-one-seo-pack-pro-modules-aioseop_feature_manager #aiosp_settings_form .aioseop_settings_left").delegate("input[name='Submit']","click",function(e){return e.preventDefault(),!1}),jQuery(".all-in-one-seo_page_all-in-one-seo-pack-pro-modules-aioseop_feature_manager #aiosp_settings_form").delegate("input[name='Submit']","click",function(e){return e.preventDefault(),aioseop_handle_post_url("aioseop_ajax_save_settings","ajax_settings_message",jQuery("form#aiosp_settings_form").serialize(),function(){jQuery(".wp-has-current-submenu").fadeIn("fast",function(){aioseop_handle_ajax_call("aioseop_ajax_get_menu_links","ajax_settings_message",jQuery.param({target:".wp-has-current-submenu > ul"}))})}),!1});jQuery("div#aiosp_sitemap_addl_pages_metabox").delegate("input[name='Submit']","click",function(){return aioseop_handle_post_url("aioseop_ajax_save_url","sitemap_addl_pages",jQuery("div#aiosp_sitemap_addl_pages_metabox input, div#aiosp_sitemap_addl_pages_metabox select").serialize()),!1}),jQuery("div#aiosp_video_sitemap_addl_pages_metabox").delegate("input[name='Submit']","click",function(){return aioseop_handle_post_url("aioseop_ajax_save_url","video_sitemap_addl_pages",jQuery("div#aiosp_video_sitemap_addl_pages_metabox input, div#aiosp_video_sitemap_addl_pages_metabox select").serialize()),!1}),jQuery("div#aiosp_sitemap_addl_pages_metabox").delegate("a.aiosp_delete_url","click",function(e){return e.preventDefault(),aioseop_handle_post_url("aioseop_ajax_delete_url","sitemap_addl_pages",jQuery(this).attr("title")),!1}),jQuery("div#aiosp_video_sitemap_addl_pages_metabox").delegate("a.aiosp_delete_url","click",function(e){return e.preventDefault(),aioseop_handle_post_url("aioseop_ajax_delete_url","video_sitemap_addl_pages",jQuery(this).attr("title")),!1}),jQuery("div#aiosp_opengraph_scan_header").delegate("input[name='aiosp_opengraph_scan_header']","click",function(e){return e.preventDefault(),aioseop_handle_post_url("aioseop_ajax_scan_header","opengraph_scan_header",jQuery("div#aiosp_opengraph_scan_header").serialize()),!1}),jQuery('input[name="aiosp_sitemap_posttypes[]"][value="all"], input[name="aiosp_video_sitemap_posttypes[]"][value="all"], input[name="aiosp_sitemap_taxonomies[]"][value="all"], input[name="aiosp_video_sitemap_taxonomies[]"][value="all"]').click(function(){jQuery(this).parents("div:eq(0)").find(":checkbox").prop("checked",this.checked)}),jQuery('input[name="aiosp_sitemap_posttypes[]"][value!="all"], input[name="aiosp_video_sitemap_posttypes[]"][value!="all"], input[name="aiosp_sitemap_taxonomies[]"][value!="all"], input[name="aiosp_video_sitemap_taxonomies[]"][value!="all"]').click(function(){this.checked||jQuery(this).parents("div:eq(0)").find('input[value="all"]:checkbox').prop("checked",this.checked)}),jQuery(".aioseop_tabs").tabs({hide:!0,show:!0}),jQuery("div#aiosp_robots_default_metabox").delegate("a.aiosp_robots_delete_rule","click",function(e){return e.preventDefault(),aioseop_handle_post_url("aioseop_ajax_delete_rule","robots_rules",jQuery(this).attr("data-id"),function(){window.location.reload()}),!1}),jQuery("div#aiosp_robots_default_metabox").delegate("a.aiosp_robots_edit_rule","click",function(e){return e.preventDefault(),jQuery('input[name="aiosp_robots_agent"]').val(jQuery(this).attr("data-agent")),jQuery('select[name="aiosp_robots_type"]').val(jQuery(this).attr("data-type")),jQuery('input[name="aiosp_robots_path"]').val(jQuery(this).attr("data-path")),jQuery("input.add-edit-rule").val(jQuery(".aioseop_table").attr("data-edit-label")),jQuery("input.edit-rule-id").val(jQuery(this).attr("data-id")),!1}),jQuery("a.aiosp_robots_physical").on("click",function(e){return e.preventDefault(),aioseop_handle_post_url("aioseop_ajax_robots_physical","robots_physical_import_delete",jQuery(this).attr("data-action"),function(e){e.data&&e.data.message&&alert(e.data.message),window.location.reload()},!0),!1}),aiospinitAll()}),jQuery.fn.aioseopImageUploader=function(e){var a=this;a.options=jQuery.extend({success:void 0},e),a.target=jQuery(a).next(),a.uploader=wp.media({title:"Choose Image",button:{text:"Choose Image"},multiple:!1}),a.onSelect=function(){var e=a.uploader.state().get("selection").first().toJSON().url;0<=a.target.length&&jQuery(a.target).val(e),void 0!==a.options.success&&a.options.success(e,a)},a.onClick=function(e){e.preventDefault(),a.uploader.open()},a.uploader.on("select",a.onSelect),jQuery(a).click(a.onClick)}; \ No newline at end of file From 6095342a3eb1edb05b3928f4c354be589cdfa5fe Mon Sep 17 00:00:00 2001 From: Michael Torbert Date: Sun, 24 Mar 2019 14:54:59 -0400 Subject: [PATCH 030/121] remove check for jquery-ui #2274 --- admin/aioseop_module_class.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/admin/aioseop_module_class.php b/admin/aioseop_module_class.php index 0adc0bc5f..efffccd19 100644 --- a/admin/aioseop_module_class.php +++ b/admin/aioseop_module_class.php @@ -1738,8 +1738,6 @@ function admin_enqueue_styles( $hook_suffix ) { } // Uses WP Scripts to load the current platform version of jQuery UI CSS. - // Loads only if it is not already loaded in order to not cause a conflict with a generic version. - if ( ! wp_style_is( 'aioseop-jquery-ui', 'registered' ) && ! wp_style_is( 'aioseop-jquery-ui', 'enqueued' ) ) { $wp_scripts = wp_scripts(); wp_enqueue_style( 'aioseop-jquery-ui', @@ -1748,7 +1746,6 @@ function admin_enqueue_styles( $hook_suffix ) { AIOSEOP_VERSION, false ); - } } /** From 2bf0e899ce0c0ab39c3dfd94d0085a8db3bd4f5b Mon Sep 17 00:00:00 2001 From: contactashish13 Date: Thu, 28 Mar 2019 05:06:51 +0530 Subject: [PATCH 031/121] OG descriptions and twitter descriptions are too big + twitter:title should be truncated (#2297) * added info for testing * OG descriptions are too big * OG descriptions and twitter descriptions are too big (#808) * twitter:title should be truncated (#2296) * grunt * incomplete test * completed test case * update php doc * og:description should be truncated to 200 * og:description should be truncated to 200 * do not truncate manually provided title and description * provide og:description limit through dataProvider * grunt * travis build failure * Code review comments * PR comments https://github.com/semperfiwebdesign/all-in-one-seo-pack/pull/2297#issuecomment-475241230 * Dev-Change WPCS minor edits --- modules/aioseop_opengraph.php | 3753 ++++++++++---------- tests/modules/opengraph/test-opengraph.php | 237 ++ 2 files changed, 2152 insertions(+), 1838 deletions(-) diff --git a/modules/aioseop_opengraph.php b/modules/aioseop_opengraph.php index 94e687f74..470934f7b 100644 --- a/modules/aioseop_opengraph.php +++ b/modules/aioseop_opengraph.php @@ -1,1838 +1,1915 @@ -name = __( 'Social Meta', 'all-in-one-seo-pack' ); // Human-readable name of the plugin - $this->prefix = 'aiosp_opengraph_'; // option prefix - $this->file = __FILE__; // the current file - $this->fb_object_types = array( - 'Activities' => array( - 'activity' => __( 'Activity', 'all-in-one-seo-pack' ), - 'sport' => __( 'Sport', 'all-in-one-seo-pack' ), - ), - 'Businesses' => array( - 'bar' => __( 'Bar', 'all-in-one-seo-pack' ), - 'company' => __( 'Company', 'all-in-one-seo-pack' ), - 'cafe' => __( 'Cafe', 'all-in-one-seo-pack' ), - 'hotel' => __( 'Hotel', 'all-in-one-seo-pack' ), - 'restaurant' => __( 'Restaurant', 'all-in-one-seo-pack' ), - ), - 'Groups' => array( - 'cause' => __( 'Cause', 'all-in-one-seo-pack' ), - 'sports_league' => __( 'Sports League', 'all-in-one-seo-pack' ), - 'sports_team' => __( 'Sports Team', 'all-in-one-seo-pack' ), - ), - 'Organizations' => array( - 'band' => __( 'Band', 'all-in-one-seo-pack' ), - 'government' => __( 'Government', 'all-in-one-seo-pack' ), - 'non_profit' => __( 'Non Profit', 'all-in-one-seo-pack' ), - 'school' => __( 'School', 'all-in-one-seo-pack' ), - 'university' => __( 'University', 'all-in-one-seo-pack' ), - ), - 'People' => array( - 'actor' => __( 'Actor', 'all-in-one-seo-pack' ), - 'athlete' => __( 'Athlete', 'all-in-one-seo-pack' ), - 'author' => __( 'Author', 'all-in-one-seo-pack' ), - 'director' => __( 'Director', 'all-in-one-seo-pack' ), - 'musician' => __( 'Musician', 'all-in-one-seo-pack' ), - 'politician' => __( 'Politician', 'all-in-one-seo-pack' ), - 'profile' => __( 'Profile', 'all-in-one-seo-pack' ), - 'public_figure' => __( 'Public Figure', 'all-in-one-seo-pack' ), - ), - 'Places' => array( - 'city' => __( 'City', 'all-in-one-seo-pack' ), - 'country' => __( 'Country', 'all-in-one-seo-pack' ), - 'landmark' => __( 'Landmark', 'all-in-one-seo-pack' ), - 'state_province' => __( 'State Province', 'all-in-one-seo-pack' ), - ), - 'Products and Entertainment' => array( - 'album' => __( 'Album', 'all-in-one-seo-pack' ), - 'book' => __( 'Book', 'all-in-one-seo-pack' ), - 'drink' => __( 'Drink', 'all-in-one-seo-pack' ), - 'food' => __( 'Food', 'all-in-one-seo-pack' ), - 'game' => __( 'Game', 'all-in-one-seo-pack' ), - 'movie' => __( 'Movie', 'all-in-one-seo-pack' ), - 'product' => __( 'Product', 'all-in-one-seo-pack' ), - 'song' => __( 'Song', 'all-in-one-seo-pack' ), - 'tv_show' => __( 'TV Show', 'all-in-one-seo-pack' ), - 'episode' => __( 'Episode', 'all-in-one-seo-pack' ), - ), - 'Websites' => array( - 'article' => __( 'Article', 'all-in-one-seo-pack' ), - 'website' => __( 'Website', 'all-in-one-seo-pack' ), - ), - ); - parent::__construct(); - - if ( is_admin() ) { - add_action( 'admin_init', array( $this, 'admin_init' ), 5 ); - } else { - add_action( 'wp', array( $this, 'type_setup' ) ); - } - - if ( ! is_admin() || defined( 'DOING_AJAX' ) ) { - $this->do_opengraph(); - } - // Set variables after WordPress load. - add_action( 'init', array( &$this, 'init' ), 999999 ); - add_filter( 'jetpack_enable_open_graph', '__return_false' ); // Avoid having duplicate meta tags - add_filter( $this->prefix . 'meta', array( $this, 'handle_meta_tag' ), 10, 3 ); - // Force refresh of Facebook cache. - add_action( 'post_updated', array( &$this, 'force_fb_refresh_update' ), 10, 3 ); - add_action( 'transition_post_status', array( &$this, 'force_fb_refresh_transition' ), 10, 3 ); - add_action( 'edited_term', array( &$this, 'save_tax_data' ), 10, 3 ); - // Adds special filters - add_filter( 'aioseop_opengraph_placeholder', array( &$this, 'filter_placeholder' ) ); - add_action( 'aiosp_activate_opengraph', array( $this, 'activate_module' ) ); - add_action( 'created_term', array( $this, 'created_term' ), 10, 3 ); - // Call to init to generate menus - $this->init(); - } - - /** - * Handle specific meta tags. - * - * @since 3.0 - * - * @param string $value The value of the meta tag. - * @param string $t The type of network. - * @param string $k The name of the meta tag. - * @return string - */ - function handle_meta_tag( $value, $t, $k ) { - switch ( $k ) { - case 'type': - // https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/1013 - if ( 'blog' === $value ) { - $value = 'website'; - } - break; - } - return $value; - } - - /** - * Sets the terms defaults after a new term is created. - * - * @param int $term_id Term ID. - * @param int $tt_id Term taxonomy ID. - * @param string $taxonomy Taxonomy slug. - */ - function created_term( $term_id, $tt_id, $taxonomy_name ) { - $k = 'settings'; - $prefix = $this->get_prefix( $k ); - $tax = get_taxonomy( $taxonomy_name ); - $this->set_object_type_for_taxonomy( $prefix, $k, $taxonomy_name, $tax, false, array( $term_id ) ); - } - - /** - * Sets the defaults for a taxonomy. - * - * @param string $prefix The prefix of this module. - * @param string $k The key against which the options will be determined/set. - * @param string $taxonomy_name The name of the taxonomy. - * @param Object $tax The taxonomy object. - * @param bool $bail_if_no_terms Bail if the taxonomy has no terms. - * @param array $terms The terms in the taxonomy. - */ - private function set_object_type_for_taxonomy( $prefix, $k, $taxonomy_name, $tax, $bail_if_no_terms = false, $terms = null ) { - $object_type = null; - if ( ! $terms ) { - $terms = get_terms( - $taxonomy_name, array( - 'meta_query' => array( - array( - 'key' => '_' . $prefix . $k, - 'compare' => 'NOT EXISTS', - ), - ), - 'number' => PHP_INT_MAX, - 'fields' => 'ids', - 'hide_empty' => false, - ) - ); - } - - if ( empty( $terms ) && $bail_if_no_terms ) { - return false; - } - - if ( true === $tax->_builtin ) { - $object_type = 'article'; - } else { - // custom taxonomy. Let's get a post against this to determine its post type. - $posts = get_posts( - array( - 'numberposts' => 1, - 'post_type' => 'any', - 'tax_query' => array( - array( - 'taxonomy' => $taxonomy_name, - 'field' => 'term_id', - 'terms' => $terms, - ), - ), - ) - ); - if ( $posts ) { - global $aioseop_options; - $post_type = $posts[0]->post_type; - if ( isset( $aioseop_options['modules'] ) && isset( $aioseop_options['modules'][ $this->prefix . 'options' ] ) ) { - $og_options = $aioseop_options['modules'][ $this->prefix . 'options' ]; - - // now let's see what default object type is set for this post type. - $object_type_set = $og_options[ $this->prefix . $post_type . '_fb_object_type' ]; - if ( ! empty( $object_type_set ) ) { - $object_type = $object_type_set; - } - } - } - } - - if ( $object_type ) { - $opts[ $prefix . $k . '_category' ] = $object_type; - foreach ( $terms as $term_id ) { - update_term_meta( $term_id, '_' . $prefix . $k, $opts ); - } - } - - return true; - } - - /** - * Called when this module is activated. - */ - public function activate_module() { - if ( $this->locations !== null ) { - foreach ( $this->locations as $k => $v ) { - if ( ! isset( $v['type'] ) || 'metabox' !== $v['type'] ) { - continue; - } - $this->set_virgin_tax_terms( $k ); - } - } - } - /** - * This iterates over all taxonomies that do not have a opengraph setting defined and sets the defaults. - * - * @param string $k The key against which the options will be determined/set. - */ - private function set_virgin_tax_terms( $k ) { - $prefix = $this->get_prefix( $k ); - $opts = $this->default_options( $k ); - $taxonomies = get_taxonomies( array( 'public' => true ), 'object' ); - if ( ! $taxonomies ) { - return; - } - foreach ( $taxonomies as $name => $tax ) { - $this->set_object_type_for_taxonomy( $prefix, $k, $name, $tax, true, null ); - - } - } - - /** - * Hook called after WordPress has been loaded. - * - * @since 2.4.14 - */ - public function init() { - $count_desc = __( ' characters. Open Graph allows up to a maximum of %1$s chars for the %2$s.', 'all-in-one-seo-pack' ); - // Create default options - $this->default_options = array( - 'scan_header' => array( - 'name' => __( 'Scan Header', 'all-in-one-seo-pack' ), - 'type' => 'custom', - 'save' => true, - ), - 'setmeta' => array( - 'name' => __( 'Use AIOSEO Title and Description', 'all-in-one-seo-pack' ), - 'type' => 'checkbox', - ), - 'key' => array( - 'name' => __( 'Facebook Admin ID', 'all-in-one-seo-pack' ), - 'default' => '', - 'type' => 'text', - ), - 'appid' => array( - 'name' => __( 'Facebook App ID', 'all-in-one-seo-pack' ), - 'default' => '', - 'type' => 'text', - ), - 'title_shortcodes' => array( - 'name' => __( 'Run Shortcodes In Title', 'all-in-one-seo-pack' ), - ), - 'description_shortcodes' => array( - 'name' => __( 'Run Shortcodes In Description', 'all-in-one-seo-pack' ), - ), - 'sitename' => array( - 'name' => __( 'Site Name', 'all-in-one-seo-pack' ), - 'default' => get_bloginfo( 'name' ), - 'type' => 'text', - ), - 'hometitle' => array( - 'name' => __( 'Home Title', 'all-in-one-seo-pack' ), - 'default' => '', - 'type' => 'textarea', - 'condshow' => array( - 'aiosp_opengraph_setmeta' => array( - 'lhs' => 'aiosp_opengraph_setmeta', - 'op' => '!=', - 'rhs' => 'on', - ), - ), - ), - 'description' => array( - 'name' => __( 'Home Description', 'all-in-one-seo-pack' ), - 'default' => '', - 'type' => 'textarea', - 'condshow' => array( - 'aiosp_opengraph_setmeta' => array( - 'lhs' => 'aiosp_opengraph_setmeta', - 'op' => '!=', - 'rhs' => 'on', - ), - ), - ), - 'homeimage' => array( - 'name' => __( 'Home Image', 'all-in-one-seo-pack' ), - 'type' => 'image', - ), - 'generate_descriptions' => array( - 'name' => __( 'Use Content For Autogenerated OG Descriptions', 'all-in-one-seo-pack' ), - 'default' => 0, - ), - 'defimg' => array( - 'name' => __( 'Select OG:Image Source', 'all-in-one-seo-pack' ), - 'type' => 'select', - 'initial_options' => array( - '' => __( 'Default Image' ), - 'featured' => __( 'Featured Image' ), - 'attach' => __( 'First Attached Image' ), - 'content' => __( 'First Image In Content' ), - 'custom' => __( 'Image From Custom Field' ), - 'author' => __( 'Post Author Image' ), - 'auto' => __( 'First Available Image' ), - ), - ), - 'fallback' => array( - 'name' => __( 'Use Default If No Image Found', 'all-in-one-seo-pack' ), - 'type' => 'checkbox', - ), - 'dimg' => array( - 'name' => __( 'Default OG:Image', 'all-in-one-seo-pack' ), - 'default' => AIOSEOP_PLUGIN_IMAGES_URL . 'default-user-image.png', - 'type' => 'image', - ), - 'dimgwidth' => array( - 'name' => __( 'Default Image Width', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - ), - 'dimgheight' => array( - 'name' => __( 'Default Image Height', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - ), - 'meta_key' => array( - 'name' => __( 'Use Custom Field For Image', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - ), - 'image' => array( - 'name' => __( 'Image', 'all-in-one-seo-pack' ), - 'type' => 'radio', - 'initial_options' => array( - 0 => '', - ), - ), - 'customimg' => array( - 'name' => __( 'Custom Image', 'all-in-one-seo-pack' ), - 'type' => 'image', - ), - 'imagewidth' => array( - 'name' => __( 'Specify Image Width', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - ), - 'imageheight' => array( - 'name' => __( 'Specify Image Height', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - ), - 'video' => array( - 'name' => __( 'Custom Video', 'all-in-one-seo-pack' ), - 'type' => 'text', - ), - 'videowidth' => array( - 'name' => __( 'Specify Video Width', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - 'condshow' => array( - 'aioseop_opengraph_settings_video' => array( - 'lhs' => 'aioseop_opengraph_settings_video', - 'op' => '!=', - 'rhs' => '', - ), - ), - ), - 'videoheight' => array( - 'name' => __( 'Specify Video Height', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - 'condshow' => array( - 'aioseop_opengraph_settings_video' => array( - 'lhs' => 'aioseop_opengraph_settings_video', - 'op' => '!=', - 'rhs' => '', - ), - ), - ), - 'defcard' => array( - 'name' => __( 'Default Twitter Card', 'all-in-one-seo-pack' ), - 'type' => 'select', - 'default' => 'summary', - 'initial_options' => array( - 'summary' => __( 'Summary', 'all-in-one-seo-pack' ), - 'summary_large_image' => __( 'Summary Large Image', 'all-in-one-seo-pack' ), - - /* - REMOVING THIS TWITTER CARD TYPE FROM SOCIAL META MODULE - 'photo' => __( 'Photo', 'all-in-one-seo-pack' ) - */ - ), - ), - 'setcard' => array( - 'name' => __( 'Twitter Card Type', 'all-in-one-seo-pack' ), - 'type' => 'select', - 'initial_options' => array( - 'summary_large_image' => __( 'Summary Large Image', 'all-in-one-seo-pack' ), - 'summary' => __( 'Summary', 'all-in-one-seo-pack' ), - - /* - REMOVING THIS TWITTER CARD TYPE FROM SOCIAL META MODULE - 'photo' => __( 'Photo', 'all-in-one-seo-pack' ) - */ - ), - ), - 'twitter_site' => array( - 'name' => __( 'Twitter Site', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - ), - 'twitter_creator' => array( - 'name' => __( 'Show Twitter Author', 'all-in-one-seo-pack' ), - ), - 'twitter_domain' => array( - 'name' => __( 'Twitter Domain', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - ), - 'customimg_twitter' => array( - 'name' => __( 'Custom Twitter Image', 'all-in-one-seo-pack' ), - 'type' => 'image', - ), - 'gen_tags' => array( - 'name' => __( 'Automatically Generate Article Tags', 'all-in-one-seo-pack' ), - ), - 'gen_keywords' => array( - 'name' => __( 'Use Keywords In Article Tags', 'all-in-one-seo-pack' ), - 'default' => 'on', - 'condshow' => array( 'aiosp_opengraph_gen_tags' => 'on' ), - ), - 'gen_categories' => array( - 'name' => __( 'Use Categories In Article Tags', 'all-in-one-seo-pack' ), - 'default' => 'on', - 'condshow' => array( 'aiosp_opengraph_gen_tags' => 'on' ), - ), - 'gen_post_tags' => array( - 'name' => __( 'Use Post Tags In Article Tags', 'all-in-one-seo-pack' ), - 'default' => 'on', - 'condshow' => array( 'aiosp_opengraph_gen_tags' => 'on' ), - ), - 'types' => array( - 'name' => __( 'Enable Facebook Meta for Post Types', 'all-in-one-seo-pack' ), - 'type' => 'multicheckbox', - 'default' => array( 'post' => 'post', 'page' => 'page' ), - 'initial_options' => $this->get_post_type_titles( array( '_builtin' => false ) ), - ), - 'title' => array( - 'name' => __( 'Title', 'all-in-one-seo-pack' ), - 'default' => '', - 'type' => 'text', - 'size' => 95, - 'count' => 1, - 'count_desc' => $count_desc, - ), - 'desc' => array( - 'name' => __( 'Description', 'all-in-one-seo-pack' ), - 'default' => '', - 'type' => 'textarea', - 'cols' => 250, - 'rows' => 4, - 'count' => 1, - 'count_desc' => $count_desc, - ), - 'category' => array( - 'name' => __( 'Facebook Object Type', 'all-in-one-seo-pack' ), - 'type' => 'select', - 'style' => '', - 'default' => '', - 'initial_options' => $this->fb_object_types, - ), - 'facebook_debug' => array( - 'name' => __( 'Facebook Debug', 'all-in-one-seo-pack' ), - 'type' => 'html', - 'save' => false, - 'default' => '' . __( 'Debug This Post', 'all-in-one-seo-pack' ) . '', - ), - 'section' => array( - 'name' => __( 'Article Section', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - 'condshow' => array( 'aioseop_opengraph_settings_category' => 'article' ), - ), - 'tag' => array( - 'name' => __( 'Article Tags', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - 'condshow' => array( 'aioseop_opengraph_settings_category' => 'article' ), - ), - 'facebook_publisher' => array( - 'name' => __( 'Show Facebook Publisher on Articles', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - ), - 'facebook_author' => array( - 'name' => __( 'Show Facebook Author on Articles', 'all-in-one-seo-pack' ), - ), - 'profile_links' => array( - 'name' => __( 'Social Profile Links', 'all-in-one-seo-pack' ), - 'type' => 'textarea', - 'cols' => 60, - 'rows' => 5, - ), - 'person_or_org' => array( - 'name' => __( 'Person or Organization?', 'all-in-one-seo-pack' ), - 'type' => 'radio', - 'initial_options' => array( - 'person' => __( 'Person', 'all-in-one-seo-pack' ), - 'org' => __( 'Organization', 'all-in-one-seo-pack' ), - ), - ), - 'social_name' => array( - 'name' => __( 'Associated Name', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - ), - ); - // load initial options / set defaults - $this->update_options(); - $display = array(); - if ( isset( $this->options['aiosp_opengraph_types'] ) && ! empty( $this->options['aiosp_opengraph_types'] ) ) { - $display = $this->options['aiosp_opengraph_types']; - } - $this->locations = array( - 'opengraph' => array( - 'name' => $this->name, - 'prefix' => 'aiosp_', - 'type' => 'settings', - 'options' => array( - 'scan_header', - 'setmeta', - 'key', - 'appid', - 'sitename', - 'title_shortcodes', - 'description_shortcodes', - 'hometitle', - 'description', - 'homeimage', - 'generate_descriptions', - 'defimg', - 'fallback', - 'dimg', - 'dimgwidth', - 'dimgheight', - 'meta_key', - 'defcard', - 'profile_links', - 'person_or_org', - 'social_name', - 'twitter_site', - 'twitter_creator', - 'twitter_domain', - 'gen_tags', - 'gen_keywords', - 'gen_categories', - 'gen_post_tags', - 'types', - 'facebook_publisher', - 'facebook_author', - ), - ), - 'settings' => array( - 'name' => __( 'Social Settings', 'all-in-one-seo-pack' ), - 'type' => 'metabox', - 'help_link' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/', - 'options' => array( - 'title', - 'desc', - 'image', - 'customimg', - 'imagewidth', - 'imageheight', - 'video', - 'videowidth', - 'videoheight', - 'category', - 'facebook_debug', - 'section', - 'tag', - 'setcard', - 'customimg_twitter', - ), - 'display' => apply_filters( 'aioseop_opengraph_display', $display ), - 'prefix' => 'aioseop_opengraph_', - ), - ); - $this->layout = array( - 'home' => array( - 'name' => __( 'Home Page Settings', 'all-in-one-seo-pack' ), - 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#use-aioseo-title-and-description', - 'options' => array( 'setmeta', 'sitename', 'hometitle', 'description', 'homeimage' ), - ), - 'image' => array( - 'name' => __( 'Image Settings', 'all-in-one-seo-pack' ), - 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#select-og-image-source', - 'options' => array( 'defimg', 'fallback', 'dimg', 'dimgwidth', 'dimgheight', 'meta_key' ), - ), - 'links' => array( - 'name' => __( 'Social Profile Links', 'all-in-one-seo-pack' ), - 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#social-profile-links', - 'options' => array( 'profile_links', 'person_or_org', 'social_name' ), - ), - 'facebook' => array( - 'name' => __( 'Facebook Settings', 'all-in-one-seo-pack' ), - 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#facebook-settings', - 'options' => array( - 'key', - 'appid', - 'types', - 'gen_tags', - 'gen_keywords', - 'gen_categories', - 'gen_post_tags', - 'facebook_publisher', - 'facebook_author', - ), - ), - 'twitter' => array( - 'name' => __( 'Twitter Settings', 'all-in-one-seo-pack' ), - 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#default-twitter-card', - 'options' => array( 'defcard', 'setcard', 'twitter_site', 'twitter_creator', 'twitter_domain' ), - ), - 'default' => array( - 'name' => __( 'Advanced Settings', 'all-in-one-seo-pack' ), - 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/', - 'options' => array(), // this is set below, to the remaining options -- pdb - ), - 'scan_meta' => array( - 'name' => __( 'Scan Social Meta', 'all-in-one-seo-pack' ), - 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#scan_meta', - 'options' => array( 'scan_header' ), - ), - ); - $other_options = array(); - foreach ( $this->layout as $k => $v ) { - $other_options = array_merge( $other_options, $v['options'] ); - } - - $this->layout['default']['options'] = array_diff( array_keys( $this->default_options ), $other_options ); - } - - /** - * Forces FaceBook OpenGraph to refresh its cache when a post is changed to - * - * @param $new_status - * @param $old_status - * @param $post - * - * @todo this and force_fb_refresh_update can probably have the remote POST extracted out. - * - * @see https://developers.facebook.com/docs/sharing/opengraph/using-objects#update - * @since 2.3.11 - */ - function force_fb_refresh_transition( $new_status, $old_status, $post ) { - if ( 'publish' !== $new_status ) { - return; - } - if ( 'future' !== $old_status ) { - return; - } - - $current_post_type = get_post_type(); - - // Only ping Facebook if Social SEO is enabled on this post type. - if ( $this->option_isset( 'types' ) && is_array( $this->options['aiosp_opengraph_types'] ) && in_array( $current_post_type, $this->options['aiosp_opengraph_types'] ) ) { - $post_url = aioseop_get_permalink( $post->ID ); - $endpoint = sprintf( - 'https://graph.facebook.com/?%s', http_build_query( - array( - 'id' => $post_url, - 'scrape' => true, - ) - ) - ); - wp_remote_post( $endpoint, array( 'blocking' => false ) ); - } - } - - /** - * Forces FaceBook OpenGraph refresh on update. - * - * @param $post_id - * @param $post_after - * - * @see https://developers.facebook.com/docs/sharing/opengraph/using-objects#update - * @since 2.3.11 - */ - function force_fb_refresh_update( $post_id, $post_after ) { - - $current_post_type = get_post_type(); - - // Only ping Facebook if Social SEO is enabled on this post type. - if ( 'publish' === $post_after->post_status && $this->option_isset( 'types' ) && is_array( $this->options['aiosp_opengraph_types'] ) && in_array( $current_post_type, $this->options['aiosp_opengraph_types'] ) ) { - $post_url = aioseop_get_permalink( $post_id ); - $endpoint = sprintf( - 'https://graph.facebook.com/?%s', http_build_query( - array( - 'id' => $post_url, - 'scrape' => true, - ) - ) - ); - wp_remote_post( $endpoint, array( 'blocking' => false ) ); - } - } - - function settings_page_init() { - add_filter( 'aiosp_output_option', array( $this, 'display_custom_options' ), 10, 2 ); - } - - function filter_options( $options, $location ) { - if ( $location == 'settings' ) { - $prefix = $this->get_prefix( $location ) . $location . '_'; - list( $legacy, $images ) = $this->get_all_images( $options ); - if ( isset( $options ) && isset( $options[ "{$prefix}image" ] ) ) { - $thumbnail = $options[ "{$prefix}image" ]; - if ( ctype_digit( (string) $thumbnail ) || ( $thumbnail == 'post' ) ) { - if ( $thumbnail == 'post' ) { - $thumbnail = $images['post1']; - } elseif ( ! empty( $legacy[ $thumbnail ] ) ) { - $thumbnail = $legacy[ $thumbnail ]; - } - } - $options[ "{$prefix}image" ] = $thumbnail; - } - if ( empty( $options[ $prefix . 'image' ] ) ) { - $img = array_keys( $images ); - if ( ! empty( $img ) && ! empty( $img[1] ) ) { - $options[ $prefix . 'image' ] = $img[1]; - } - } - } - - return $options; - } - - /** - * Applies filter to module settings. - * - * @since 2.3.11 - * @since 2.4.14 Added filter for description and title placeholders. - * @since 2.3.15 do_shortcode on description. - * - * @see [plugin]\admin\aioseop_module_class.php > display_options() - */ - function filter_settings( $settings, $location, $current ) { - global $aiosp, $post; - if ( $location == 'opengraph' || $location == 'settings' ) { - $prefix = $this->get_prefix( $location ) . $location . '_'; - if ( $location == 'opengraph' ) { - return $settings; - } - if ( $location == 'settings' ) { - list( $legacy, $settings[ $prefix . 'image' ]['initial_options'] ) = $this->get_all_images( $current ); - $opts = array( 'title', 'desc' ); - $current_post_type = get_post_type(); - if ( isset( $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ] ) ) { - $flat_type_list = array(); - foreach ( $this->fb_object_types as $k => $v ) { - if ( is_array( $v ) ) { - $flat_type_list = array_merge( $flat_type_list, $v ); - } else { - $flat_type_list[ $k ] = $v; - } - } - $default_fb_type = $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ]; - // https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/1013 - // if 'blog' is the selected type but because it is no longer a schema type, we use 'website' instead. - if ( 'blog' === $default_fb_type ) { - $default_fb_type = 'website'; - } - if ( isset( $flat_type_list[ $default_fb_type ] ) ) { - $default_fb_type = $flat_type_list[ $default_fb_type ]; - } - $settings[ $prefix . 'category' ]['initial_options'] = array_merge( - array( - $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ] => __( 'Default ', 'all-in-one-seo-pack' ) . ' - ' . $default_fb_type, - ), - $settings[ $prefix . 'category' ]['initial_options'] - ); - } - if ( isset( $this->options['aiosp_opengraph_defcard'] ) ) { - $settings[ $prefix . 'setcard' ]['default'] = $this->options['aiosp_opengraph_defcard']; - } - $info = $aiosp->get_page_snippet_info(); - $title = $info['title']; - $description = $info['description']; - - // Description options - if ( is_object( $post ) ) { - // Always show excerpt - $description = empty( $this->options['aiosp_opengraph_generate_descriptions'] ) - ? $aiosp->trim_excerpt_without_filters( - $aiosp->internationalize( preg_replace( '/\s+/', ' ', $post->post_excerpt ) ), - 1000 - ) - : $aiosp->trim_excerpt_without_filters( - $aiosp->internationalize( preg_replace( '/\s+/', ' ', $post->post_content ) ), - 1000 - ); - } - - // #1308 - we want to make sure we are ignoring php version only in the admin area while editing the post, so that it does not impact #932. - $screen = get_current_screen(); - $ignore_php_version = is_admin() && isset( $screen->id ) && 'post' == $screen->id; - - // Add filters - $description = apply_filters( 'aioseop_description', $description, false, $ignore_php_version ); - // Add placholders - $settings[ "{$prefix}title" ]['placeholder'] = apply_filters( 'aioseop_opengraph_placeholder', $title ); - $settings[ "{$prefix}desc" ]['placeholder'] = apply_filters( 'aioseop_opengraph_placeholder', $description ); - } - if ( isset( $current[ $prefix . 'setmeta' ] ) && $current[ $prefix . 'setmeta' ] ) { - foreach ( $opts as $opt ) { - if ( isset( $settings[ $prefix . $opt ] ) ) { - $settings[ $prefix . $opt ]['type'] = 'hidden'; - $settings[ $prefix . $opt ]['label'] = 'none'; - unset( $settings[ $prefix . $opt ]['count'] ); - } - } - } - } - - return $settings; - } - - /** - * Applies filter to module options. - * These will display in the "Social Settings" object tab. - * filter:{prefix}override_options - * - * @since 2.3.11 - * @since 2.4.14 Overrides empty og:type values. - * - * @see [plugin]\admin\aioseop_module_class.php > display_options() - * - * @global array $aioseop_options Plugin options. - * - * @param array $options Current options. - * @param string $location Location where filter is called. - * @param array $settings Settings. - * - * @return array - */ - function override_options( $options, $location, $settings ) { - global $aioseop_options; - // Prepare default and prefix - $prefix = $this->get_prefix( $location ) . $location . '_'; - $opts = array(); - - foreach ( $settings as $k => $v ) { - if ( $v['save'] ) { - $opts[ $k ] = $v['default']; - } - } - foreach ( $options as $k => $v ) { - switch ( $k ) { - case $prefix . 'category': - if ( empty( $v ) ) { - // Get post type - $type = isset( get_current_screen()->post_type ) - ? get_current_screen()->post_type - : null; - // Assign default from plugin options - if ( ! empty( $type ) - && isset( $aioseop_options['modules'] ) - && isset( $aioseop_options['modules']['aiosp_opengraph_options'] ) - && isset( $aioseop_options['modules']['aiosp_opengraph_options'][ 'aiosp_opengraph_' . $type . '_fb_object_type' ] ) - ) { - $options[ $prefix . 'category' ] = - $aioseop_options['modules']['aiosp_opengraph_options'][ 'aiosp_opengraph_' . $type . '_fb_object_type' ]; - } - } - break; - } - if ( $v === null ) { - unset( $options[ $k ] ); - } - } - $options = wp_parse_args( $options, $opts ); - - // https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/1013 - $post_types = $this->get_post_type_titles(); - foreach ( $post_types as $slug => $name ) { - $field = 'aiosp_opengraph_' . $slug . '_fb_object_type'; - if ( isset( $options[ $field ] ) && 'blog' === $options[ $field ] ) { - $options[ $field ] = 'website'; - } - } - - return $options; - } - - /** - * Applies filter to metabox settings before they are saved. - * Sets custom as default if a custom image is uploaded. - * filter:{prefix}filter_metabox_options - * filter:{prefix}filter_term_metabox_options - * - * @since 2.3.11 - * @since 2.4.14 Fixes for aioseop-pro #67 and other bugs found. - * - * @see [plugin]\admin\aioseop_module_class.php > save_post_data() - * @see [this file] > save_tax_data() - * - * @param array $options List of current options. - * @param string $location Location where filter is called. - * @param int $id Either post_id or term_id. - * - * @return array - */ - function filter_metabox_options( $options, $location, $post_id ) { - if ( $location == 'settings' ) { - $prefix = $this->get_prefix( $location ) . $location . '_'; - if ( isset( $options[ $prefix . 'customimg_checker' ] ) - && $options[ $prefix . 'customimg_checker' ] - ) { - $options[ $prefix . 'image' ] = $options[ $prefix . 'customimg' ]; - } - } - return $options; - } - - /** Custom settings **/ - function display_custom_options( $buf, $args ) { - if ( $args['name'] == 'aiosp_opengraph_scan_header' ) { - $buf .= '
    '; - $args['options']['type'] = 'submit'; - $args['attr'] = " class='button-primary' "; - $args['value'] = $args['options']['default'] = __( 'Scan Now', 'all-in-one-seo-pack' ); - $buf .= __( 'Scan your site for duplicate social meta tags.', 'all-in-one-seo-pack' ); - $buf .= '

    ' . $this->get_option_html( $args ); - $buf .= '
    '; - } - - return $buf; - } - - function add_attributes( $output ) { - // avoid having duplicate meta tags - $type = $this->type; - if ( empty( $type ) ) { - $type = 'website'; - } - $schema_types = array( - 'album' => 'MusicAlbum', - 'article' => 'Article', - 'bar' => 'BarOrPub', - 'blog' => 'Blog', - 'book' => 'Book', - 'cafe' => 'CafeOrCoffeeShop', - 'city' => 'City', - 'country' => 'Country', - 'episode' => 'Episode', - 'food' => 'FoodEvent', - 'game' => 'Game', - 'hotel' => 'Hotel', - 'landmark' => 'LandmarksOrHistoricalBuildings', - 'movie' => 'Movie', - 'product' => 'Product', - 'profile' => 'ProfilePage', - 'restaurant' => 'Restaurant', - 'school' => 'School', - 'sport' => 'SportsEvent', - 'website' => 'WebSite', - ); - - if ( ! empty( $schema_types[ $type ] ) ) { - $type = $schema_types[ $type ]; - } else { - $type = 'WebSite'; - } - - $attributes = apply_filters( - $this->prefix . 'attributes', array( - 'prefix="og: http://ogp.me/ns#"', - ) - ); - - foreach ( $attributes as $attr ) { - if ( strpos( $output, $attr ) === false ) { - $output .= "\n\t$attr "; - } - } - - return $output; - } - - /** - * Add our social meta. - * - * @since 1.0.0 - * @since 2.3.11.5 Support for multiple fb_admins. - * @since 2.3.13 Adds filter:aioseop_description on description. - * @since 2.4.14 Fixes for aioseop-pro #67. - * @since 2.3.15 Always do_shortcode on descriptions, removed for titles. - * - * @global object $post Current WP_Post object. - * @global object $aiosp All in one seo plugin object. - * @global array $aioseop_options All in one seo plugin options. - * @global object $wp_query WP_Query global instance. - */ - function add_meta() { - global $post, $aiosp, $aioseop_options, $wp_query; - $metabox = $this->get_current_options( array(), 'settings' ); - $key = $this->options['aiosp_opengraph_key']; - $key = $this->options['aiosp_opengraph_key']; - $dimg = $this->options['aiosp_opengraph_dimg']; - $current_post_type = get_post_type(); - $title = $description = $image = $video = ''; - $type = $this->type; - $sitename = $this->options['aiosp_opengraph_sitename']; - - $appid = isset( $this->options['aiosp_opengraph_appid'] ) ? $this->options['aiosp_opengraph_appid'] : ''; - - if ( ! empty( $aioseop_options['aiosp_hide_paginated_descriptions'] ) ) { - $first_page = false; - if ( $aiosp->get_page_number() < 2 ) { - $first_page = true; - } - } else { - $first_page = true; - } - $url = $aiosp->aiosp_mrt_get_url( $wp_query ); - $url = apply_filters( 'aioseop_canonical_url', $url ); - - $setmeta = $this->options['aiosp_opengraph_setmeta']; - $social_links = ''; - if ( is_front_page() ) { - $title = $this->options['aiosp_opengraph_hometitle']; - if ( $first_page ) { - $description = $this->options['aiosp_opengraph_description']; - if ( empty( $description ) ) { - $description = get_bloginfo( 'description' ); - } - } - if ( ! empty( $this->options['aiosp_opengraph_homeimage'] ) ) { - $thumbnail = $this->options['aiosp_opengraph_homeimage']; - } else { - $thumbnail = $this->options['aiosp_opengraph_dimg']; - } - - /* If Use AIOSEO Title and Desc Selected */ - if ( $setmeta ) { - $title = $aiosp->wp_title(); - if ( $first_page ) { - $description = $aiosp->get_aioseop_description( $post ); - } - } - - /* Add some defaults */ - if ( empty( $title ) ) { - $title = get_bloginfo( 'name' ); - } - if ( empty( $sitename ) ) { - $sitename = get_bloginfo( 'name' ); - } - - if ( empty( $description ) && $first_page && ! empty( $post ) && ! post_password_required( $post ) ) { - - if ( ! empty( $post->post_content ) || ! empty( $post->post_excerpt ) ) { - $description = $aiosp->trim_excerpt_without_filters( $aiosp->internationalize( preg_replace( '/\s+/', ' ', $post->post_excerpt ) ), 1000 ); - - if ( ! empty( $this->options['aiosp_opengraph_generate_descriptions'] ) ) { - $description = $aiosp->trim_excerpt_without_filters( $aiosp->internationalize( preg_replace( '/\s+/', ' ', $post->post_content ) ), 1000 ); - } - } - } - - if ( empty( $description ) && $first_page ) { - $description = get_bloginfo( 'description' ); - } - if ( ! empty( $this->options['aiosp_opengraph_profile_links'] ) ) { - $social_links = $this->options['aiosp_opengraph_profile_links']; - if ( ! empty( $this->options['aiosp_opengraph_social_name'] ) ) { - $social_name = $this->options['aiosp_opengraph_social_name']; - } else { - $social_name = ''; - } - if ( $this->options['aiosp_opengraph_person_or_org'] == 'person' ) { - $social_type = 'Person'; - } else { - $social_type = 'Organization'; - } - } - } elseif ( is_singular() && $this->option_isset( 'types' ) - && is_array( $this->options['aiosp_opengraph_types'] ) - && in_array( $current_post_type, $this->options['aiosp_opengraph_types'] ) - ) { - - if ( $type == 'article' ) { - if ( ! empty( $metabox['aioseop_opengraph_settings_section'] ) ) { - $section = $metabox['aioseop_opengraph_settings_section']; - } - if ( ! empty( $metabox['aioseop_opengraph_settings_tag'] ) ) { - $tag = $metabox['aioseop_opengraph_settings_tag']; - } - if ( ! empty( $this->options['aiosp_opengraph_facebook_publisher'] ) ) { - $publisher = $this->options['aiosp_opengraph_facebook_publisher']; - } - } - - if ( ! empty( $this->options['aiosp_opengraph_twitter_domain'] ) ) { - $domain = $this->options['aiosp_opengraph_twitter_domain']; - } - - if ( $type == 'article' && ! empty( $post ) ) { - if ( isset( $post->post_author ) && ! empty( $this->options['aiosp_opengraph_facebook_author'] ) ) { - $author = get_the_author_meta( 'facebook', $post->post_author ); - } - - if ( isset( $post->post_date_gmt ) ) { - $published_time = date( 'Y-m-d\TH:i:s\Z', mysql2date( 'U', $post->post_date_gmt ) ); - } - - if ( isset( $post->post_modified_gmt ) ) { - $modified_time = date( 'Y-m-d\TH:i:s\Z', mysql2date( 'U', $post->post_modified_gmt ) ); - } - } - - $image = $metabox['aioseop_opengraph_settings_image']; - $video = $metabox['aioseop_opengraph_settings_video']; - $title = $metabox['aioseop_opengraph_settings_title']; - $description = $metabox['aioseop_opengraph_settings_desc']; - - /* Add AIOSEO variables if Site Title and Desc from AIOSEOP not selected */ - global $aiosp; - if ( empty( $title ) ) { - $title = $aiosp->wp_title(); - } - if ( empty( $description ) ) { - $description = trim( strip_tags( get_post_meta( $post->ID, '_aioseop_description', true ) ) ); - } - - /* Add default title */ - if ( empty( $title ) ) { - $title = get_the_title(); - } - - // Add default description. - if ( empty( $description ) && ! post_password_required( $post ) ) { - - $description = $post->post_excerpt; - - if ( $this->options['aiosp_opengraph_generate_descriptions'] || empty( $description ) ) { - if ( ! AIOSEOPPRO || ( AIOSEOPPRO && apply_filters( $this->prefix . 'generate_descriptions_from_content', true, $post ) ) ) { - $description = $post->post_content; - } else { - $description = $post->post_excerpt; - } - } - } - if ( empty( $type ) ) { - $type = 'article'; - } - } elseif ( AIOSEOPPRO && ( is_category() || is_tag() || is_tax() ) ) { - if ( isset( $this->options['aioseop_opengraph_settings_category'] ) ) { - $type = $this->options['aioseop_opengraph_settings_category']; - } - if ( isset( $metabox['aioseop_opengraph_settings_category'] ) ) { - $type = $metabox['aioseop_opengraph_settings_category']; - } - if ( $type == 'article' ) { - if ( ! empty( $metabox['aioseop_opengraph_settings_section'] ) ) { - $section = $metabox['aioseop_opengraph_settings_section']; - } - if ( ! empty( $metabox['aioseop_opengraph_settings_tag'] ) ) { - $tag = $metabox['aioseop_opengraph_settings_tag']; - } - if ( ! empty( $this->options['aiosp_opengraph_facebook_publisher'] ) ) { - $publisher = $this->options['aiosp_opengraph_facebook_publisher']; - } - } - if ( ! empty( $this->options['aiosp_opengraph_twitter_domain'] ) ) { - $domain = $this->options['aiosp_opengraph_twitter_domain']; - } - if ( $type == 'article' && ! empty( $post ) ) { - if ( isset( $post->post_author ) && ! empty( $this->options['aiosp_opengraph_facebook_author'] ) ) { - $author = get_the_author_meta( 'facebook', $post->post_author ); - } - - if ( isset( $post->post_date_gmt ) ) { - $published_time = date( 'Y-m-d\TH:i:s\Z', mysql2date( 'U', $post->post_date_gmt ) ); - } - if ( isset( $post->post_modified_gmt ) ) { - $modified_time = date( 'Y-m-d\TH:i:s\Z', mysql2date( 'U', $post->post_modified_gmt ) ); - } - } - $image = $metabox['aioseop_opengraph_settings_image']; - $video = $metabox['aioseop_opengraph_settings_video']; - $title = $metabox['aioseop_opengraph_settings_title']; - $description = $metabox['aioseop_opengraph_settings_desc']; - /* Add AIOSEO variables if Site Title and Desc from AIOSEOP not selected */ - global $aiosp; - if ( empty( $title ) ) { - $title = $aiosp->wp_title(); - } - if ( empty( $description ) ) { - $term_id = isset( $_GET['tag_ID'] ) ? (int) $_GET['tag_ID'] : 0; - $term_id = $term_id ? $term_id : get_queried_object()->term_id; - $description = trim( strip_tags( get_term_meta( $term_id, '_aioseop_description', true ) ) ); - } - // Add default title - if ( empty( $title ) ) { - $title = get_the_title(); - } - // Add default description. - if ( empty( $description ) && ! post_password_required( $post ) ) { - $description = get_queried_object()->description; - } - if ( empty( $type ) ) { - // https://github.com/semperfiwebdesign/aioseop-pro/issues/321 - if ( AIOSEOPPRO && ( is_category() || is_tag() || is_tax() ) ) { - $og_options = $aioseop_options['modules'][ $this->prefix . 'options' ]; - $current_post_type = get_post_type(); - // check if the post type's object type is set. - if ( isset( $og_options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ] ) ) { - $type = $og_options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ]; - } elseif ( in_array( $current_post_type, array( 'post', 'page' ) ) ) { - $type = 'article'; - } - } else { - $type = 'website'; - } - } - } elseif ( is_home() && ! is_front_page() ) { - // This is the blog page but not the homepage. - global $aiosp; - $image = $metabox['aioseop_opengraph_settings_image']; - $video = $metabox['aioseop_opengraph_settings_video']; - $title = $metabox['aioseop_opengraph_settings_title']; - $description = $metabox['aioseop_opengraph_settings_desc']; - - if ( empty( $description ) ) { - // If there's not social description, fall back to the SEO description. - $description = trim( strip_tags( get_post_meta( get_option( 'page_for_posts' ), '_aioseop_description', true ) ) ); - } - if ( empty( $title ) ) { - $title = $aiosp->wp_title(); - } - } else { - return; - } - - if ( $type === 'article' && ! empty( $post ) && is_singular() ) { - if ( ! empty( $this->options['aiosp_opengraph_gen_tags'] ) ) { - if ( ! empty( $this->options['aiosp_opengraph_gen_keywords'] ) ) { - $keywords = $aiosp->get_main_keywords(); - $keywords = $this->apply_cf_fields( $keywords ); - $keywords = apply_filters( 'aioseop_keywords', $keywords ); - if ( ! empty( $keywords ) && ! empty( $tag ) ) { - $tag .= ',' . $keywords; - } elseif ( empty( $tag ) ) { - $tag = $keywords; - } - } - $tag = $aiosp->keyword_string_to_list( $tag ); - if ( ! empty( $this->options['aiosp_opengraph_gen_categories'] ) ) { - $tag = array_merge( $tag, $aiosp->get_all_categories( $post->ID ) ); - } - if ( ! empty( $this->options['aiosp_opengraph_gen_post_tags'] ) ) { - $tag = array_merge( $tag, $aiosp->get_all_tags( $post->ID ) ); - } - } - if ( ! empty( $tag ) ) { - $tag = $aiosp->clean_keyword_list( $tag ); - } - } - - if ( ! empty( $this->options['aiosp_opengraph_title_shortcodes'] ) ) { - $title = do_shortcode( $title ); - } - if ( ! empty( $description ) ) { - $description = $aiosp->internationalize( preg_replace( '/\s+/', ' ', $description ) ); - if ( ! empty( $this->options['aiosp_opengraph_description_shortcodes'] ) ) { - $description = do_shortcode( $description ); - } - $description = $aiosp->trim_excerpt_without_filters( $description, 1000 ); - } - - $title = $this->apply_cf_fields( $title ); - $description = $this->apply_cf_fields( $description ); - - /* Data Validation */ - $title = strip_tags( esc_attr( $title ) ); - $sitename = strip_tags( esc_attr( $sitename ) ); - $description = strip_tags( esc_attr( $description ) ); - - if ( empty( $thumbnail ) && ! empty( $image ) ) { - $thumbnail = $image; - } - - // Add user supplied default image. - if ( empty( $thumbnail ) ) { - if ( empty( $this->options['aiosp_opengraph_defimg'] ) ) { - $thumbnail = $this->options['aiosp_opengraph_dimg']; - } else { - $img_type = $this->options['aiosp_opengraph_defimg']; - if ( ! empty( $post ) ) { - // Customize the type of image per post/post_type. - $img_type = apply_filters( $this->prefix . 'default_image_type', $img_type, $post, $type ); - } - switch ( $img_type ) { - case 'featured': - $thumbnail = $this->get_the_image_by_post_thumbnail(); - break; - case 'attach': - $thumbnail = $this->get_the_image_by_attachment(); - break; - case 'content': - $thumbnail = $this->get_the_image_by_scan(); - break; - case 'custom': - $meta_key = $this->options['aiosp_opengraph_meta_key']; - if ( ! empty( $meta_key ) && ! empty( $post ) ) { - $meta_key = explode( ',', $meta_key ); - $thumbnail = $this->get_the_image_by_meta_key( - array( - 'post_id' => $post->ID, - 'meta_key' => $meta_key, - ) - ); - } - break; - case 'auto': - $thumbnail = $this->get_the_image(); - break; - case 'author': - $thumbnail = $this->get_the_image_by_author(); - break; - default: - $thumbnail = $this->options['aiosp_opengraph_dimg']; - } - } - } - - if ( empty( $thumbnail ) && ! empty( $this->options['aiosp_opengraph_fallback'] ) ) { - $thumbnail = $this->options['aiosp_opengraph_dimg']; - if ( ! empty( $post ) ) { - // Customize the default image per post/post_type. - $thumbnail = apply_filters( $this->prefix . 'default_image', $thumbnail, $post, $type ); - } - } - - if ( ! empty( $thumbnail ) ) { - $thumbnail = esc_url( $thumbnail ); - $thumbnail = set_url_scheme( $thumbnail ); - } - - $width = $height = ''; - if ( ! empty( $thumbnail ) ) { - if ( ! empty( $metabox['aioseop_opengraph_settings_imagewidth'] ) ) { - $width = $metabox['aioseop_opengraph_settings_imagewidth']; - } - if ( ! empty( $metabox['aioseop_opengraph_settings_imageheight'] ) ) { - $height = $metabox['aioseop_opengraph_settings_imageheight']; - } - if ( empty( $width ) && ! empty( $this->options['aiosp_opengraph_dimgwidth'] ) ) { - $width = $this->options['aiosp_opengraph_dimgwidth']; - } - if ( empty( $height ) && ! empty( $this->options['aiosp_opengraph_dimgheight'] ) ) { - $height = $this->options['aiosp_opengraph_dimgheight']; - } - } - - if ( ! empty( $video ) ) { - if ( ! empty( $metabox['aioseop_opengraph_settings_videowidth'] ) ) { - $videowidth = $metabox['aioseop_opengraph_settings_videowidth']; - } - if ( ! empty( $metabox['aioseop_opengraph_settings_videoheight'] ) ) { - $videoheight = $metabox['aioseop_opengraph_settings_videoheight']; - } - } - - $card = 'summary'; - if ( ! empty( $this->options['aiosp_opengraph_defcard'] ) ) { - $card = $this->options['aiosp_opengraph_defcard']; - } - - if ( ! empty( $metabox['aioseop_opengraph_settings_setcard'] ) ) { - $card = $metabox['aioseop_opengraph_settings_setcard']; - } - - // support for changing legacy twitter cardtype-photo to summary large image - if ( $card == 'photo' ) { - $card = 'summary_large_image'; - } - - $site = $domain = $creator = ''; - - if ( ! empty( $this->options['aiosp_opengraph_twitter_site'] ) ) { - $site = $this->options['aiosp_opengraph_twitter_site']; - $site = AIOSEOP_Opengraph_Public::prepare_twitter_username( $site ); - } - - if ( ! empty( $this->options['aiosp_opengraph_twitter_domain'] ) ) { - $domain = $this->options['aiosp_opengraph_twitter_domain']; - } - - if ( ! empty( $post ) && isset( $post->post_author ) && ! empty( $this->options['aiosp_opengraph_twitter_creator'] ) ) { - $creator = get_the_author_meta( 'twitter', $post->post_author ); - $creator = AIOSEOP_Opengraph_Public::prepare_twitter_username( $creator ); - } - - if ( ! empty( $thumbnail ) ) { - $twitter_thumbnail = $thumbnail; // Default Twitter image if custom isn't set. - } - - if ( isset( $metabox['aioseop_opengraph_settings_customimg_twitter'] ) && ! empty( $metabox['aioseop_opengraph_settings_customimg_twitter'] ) ) { - // Set Twitter image from custom. - $twitter_thumbnail = set_url_scheme( $metabox['aioseop_opengraph_settings_customimg_twitter'] ); - } - - // Apply last filters. - $description = apply_filters( 'aioseop_description', $description ); - - $meta = array( - 'facebook' => array( - 'title' => 'og:title', - 'type' => 'og:type', - 'url' => 'og:url', - 'thumbnail' => 'og:image', - 'width' => 'og:image:width', - 'height' => 'og:image:height', - 'video' => 'og:video', - 'videowidth' => 'og:video:width', - 'videoheight' => 'og:video:height', - 'sitename' => 'og:site_name', - 'key' => 'fb:admins', - 'appid' => 'fb:app_id', - 'description' => 'og:description', - 'section' => 'article:section', - 'tag' => 'article:tag', - 'publisher' => 'article:publisher', - 'author' => 'article:author', - 'published_time' => 'article:published_time', - 'modified_time' => 'article:modified_time', - ), - 'twitter' => array( - 'card' => 'twitter:card', - 'site' => 'twitter:site', - 'creator' => 'twitter:creator', - 'domain' => 'twitter:domain', - 'title' => 'twitter:title', - 'description' => 'twitter:description', - 'twitter_thumbnail' => 'twitter:image', - ), - ); - - // Only show if "use schema.org markup is checked". - if ( ! empty( $aioseop_options['aiosp_schema_markup'] ) ) { - $meta['google+'] = array( 'thumbnail' => 'image' ); - } - - // https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/1848 - if ( is_ssl() ) { - $meta['facebook'] += array( 'thumbnail_1' => 'og:image:secure_url' ); - $thumbnail_1 = $thumbnail; - } - - $tags = array( - 'facebook' => array( 'name' => 'property', 'value' => 'content' ), - 'twitter' => array( 'name' => 'name', 'value' => 'content' ), - 'google+' => array( 'name' => 'itemprop', 'value' => 'content' ), - ); - - foreach ( $meta as $t => $data ) { - foreach ( $data as $k => $v ) { - if ( empty( $$k ) ) { - $$k = ''; - } - $filtered_value = $$k; - $filtered_value = apply_filters( $this->prefix . 'meta', $filtered_value, $t, $k ); - if ( ! empty( $filtered_value ) ) { - if ( ! is_array( $filtered_value ) ) { - $filtered_value = array( $filtered_value ); - } - - /** - * This is to accomodate multiple fb:admins on separate lines. - * @TODO Eventually we'll want to put this in its own function so things like images work too. - */ - if ( 'key' === $k ) { - $fbadmins = explode( ',', str_replace( ' ', '', $filtered_value[0] ) ); // Trim spaces then turn comma-separated values into an array. - foreach ( $fbadmins as $fbadmin ) { - echo '' . "\n"; - } - } else { - // For everything else. - foreach ( $filtered_value as $f ) { - // #1363: use esc_attr( $f ) instead of htmlspecialchars_decode( $f, ENT_QUOTES ) - echo '' . "\n"; - } - } - } - } - } - $social_link_schema = ''; - if ( ! empty( $social_links ) ) { - $home_url = esc_url( get_home_url() ); - $social_links = explode( "\n", $social_links ); - foreach ( $social_links as $k => $v ) { - $v = trim( $v ); - if ( empty( $v ) ) { - unset( $social_links[ $k ] ); - } else { - $v = esc_url( $v ); - $social_links[ $k ] = $v; - } - } - $social_links = join( '","', $social_links ); - $social_link_schema = << -{ "@context" : "http://schema.org", - "@type" : "{$social_type}", - "name" : "{$social_name}", - "url" : "{$home_url}", - "sameAs" : ["{$social_links}"] -} - - -END; - } - - // Only show if "use schema.org markup is checked". - if ( ! empty( $aioseop_options['aiosp_schema_markup'] ) ) { - echo apply_filters( 'aiosp_opengraph_social_link_schema', $social_link_schema ); - } - } - - /** - * Do / adds opengraph properties to meta. - * @since 2.3.11 - * - * @global array $aioseop_options AIOSEOP plugin options. - */ - public function do_opengraph() { - global $aioseop_options; - if ( ! empty( $aioseop_options ) - && ! empty( $aioseop_options['aiosp_schema_markup'] ) - ) { - add_filter( 'language_attributes', array( &$this, 'add_attributes' ) ); - } - if ( ! defined( 'DOING_AJAX' ) ) { - add_action( 'aioseop_modules_wp_head', array( &$this, 'add_meta' ), 5 ); - // Add social meta to AMP plugin. - if ( apply_filters( 'aioseop_enable_amp_social_meta', true ) === true ) { - add_action( 'amp_post_template_head', array( &$this, 'add_meta' ), 12 ); - } - } - } - - /** - * Set up types. - * - * @since ? - * @since 2.3.15 Change to website for homepage and blog post index page, default to object. - */ - function type_setup() { - $this->type = 'object'; // Default to type object if we don't have some other rule. - - if ( is_home() || is_front_page() ) { - $this->type = 'website'; // Home page and blog page should be website. - } elseif ( is_singular() && $this->option_isset( 'types' ) ) { - $metabox = $this->get_current_options( array(), 'settings' ); - $current_post_type = get_post_type(); - if ( ! empty( $metabox['aioseop_opengraph_settings_category'] ) ) { - $this->type = $metabox['aioseop_opengraph_settings_category']; - } elseif ( isset( $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ] ) ) { - $this->type = $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ]; - } - } - } - - /** - * Inits hooks and others for admin init. - * action:admin_init. - * - * @since 2.3.11 - * @since 2.4.14 Refactored function name, and new filter added for defaults and missing term metabox. - */ - function admin_init() { - add_filter( $this->prefix . 'display_settings', array( &$this, 'filter_settings' ), 10, 3 ); - add_filter( $this->prefix . 'override_options', array( &$this, 'override_options' ), 10, 3 ); - add_filter( - $this->get_prefix( 'settings' ) . 'default_options', array( - &$this, - 'filter_default_options', - ), 10, 2 - ); - add_filter( - $this->get_prefix( 'settings' ) . 'filter_metabox_options', array( - &$this, - 'filter_metabox_options', - ), 10, 3 - ); - add_filter( - $this->get_prefix( 'settings' ) . 'filter_term_metabox_options', array( - &$this, - 'filter_metabox_options', - ), 10, 3 - ); - $post_types = $this->get_post_type_titles(); - $rempost = array( - 'revision' => 1, - 'nav_menu_item' => 1, - 'custom_css' => 1, - 'customize_changeset' => 1, - ); - $post_types = array_diff_key( $post_types, $rempost ); - $this->default_options['types']['initial_options'] = $post_types; - foreach ( $post_types as $slug => $name ) { - $field = $slug . '_fb_object_type'; - $this->default_options[ $field ] = array( - 'name' => "$name " . __( 'Object Type', 'all-in-one-seo-pack' ) . "
    ($slug)", - 'type' => 'select', - 'style' => '', - 'initial_options' => $this->fb_object_types, - 'default' => 'article', - 'condshow' => array( 'aiosp_opengraph_types\[\]' => $slug ), - ); - $this->locations['opengraph']['options'][] = $field; - $this->layout['facebook']['options'][] = $field; - } - $this->setting_options(); - } - - function get_all_images( $options = null, $p = null ) { - static $img = array(); - if ( ! is_array( $options ) ) { - $options = array(); - } - if ( ! empty( $this->options['aiosp_opengraph_meta_key'] ) ) { - $options['meta_key'] = $this->options['aiosp_opengraph_meta_key']; - } - if ( empty( $img ) ) { - $size = apply_filters( 'post_thumbnail_size', 'large' ); - $default = $this->get_the_image_by_default(); - if ( ! empty( $default ) ) { - $default = set_url_scheme( $default ); - $img[ $default ] = 0; - } - $img = array_merge( $img, parent::get_all_images( $options, null ) ); - } - - if ( ! empty( $options ) && ! empty( $options['aioseop_opengraph_settings_customimg'] ) ) { - $img[ $options['aioseop_opengraph_settings_customimg'] ] = 'customimg'; - } - - if ( ! empty( $options ) && ! empty( $options['aioseop_opengraph_settings_customimg'] ) ) { - $img[ $options['aioseop_opengraph_settings_customimg'] ] = 'customimg'; - $img[ $options['aioseop_opengraph_settings_customimg_twitter'] ] = 'customimg_twitter'; - } - - if ( $author_img = $this->get_the_image_by_author( $p ) ) { - $image['author'] = $author_img; - } - $image = array_flip( $img ); - $images = array(); - if ( ! empty( $image ) ) { - foreach ( $image as $k => $v ) { - $images[ $v ] = ''; - } - } - - return array( $image, $images ); - } - - function get_the_image_by_author( $options = null, $p = null ) { - if ( $p === null ) { - global $post; - } else { - $post = $p; - } - if ( ! empty( $post ) && ! empty( $post->post_author ) ) { - $matches = array(); - $get_avatar = get_avatar( $post->post_author, 300 ); - if ( preg_match( "/src='(.*?)'/i", $get_avatar, $matches ) ) { - return $matches[1]; - } - } - - return false; - } - - function get_the_image( $options = null, $p = null ) { - $meta_key = $this->options['aiosp_opengraph_meta_key']; - - return parent::get_the_image( array( 'meta_key' => $meta_key ), $p ); - } - - function get_the_image_by_default( $args = array() ) { - return $this->options['aiosp_opengraph_dimg']; - } - - function settings_update() { - - } - - /** - * Admin Enqueue Scripts - * - * Add hook in \All_in_One_SEO_Pack_Module::enqueue_metabox_scripts - Bails adding hook if not on target valid screen. - * Add hook in \All_in_One_SEO_Pack_Module::add_page_hooks - Function itself is hooked based on the screen_id/page. - * - * @since 2.9.2 - * - * @see 'admin_enqueue_scripts' hook - * @link https://developer.wordpress.org/reference/hooks/admin_enqueue_scripts/ - * - * @param string $hook_suffix - */ - public function admin_enqueue_scripts( $hook_suffix ) { - wp_enqueue_script( - 'aioseop-opengraph-script', - AIOSEOP_PLUGIN_URL . 'js/modules/aioseop_opengraph.js', - array(), - AIOSEOP_VERSION - ); - - // Dev note: If certain JS files need to be restricted to select screens, then follow concept - // used in `All_in_One_SEO_Pack::admin_enqueue_scripts()` (v2.9.1); which uses the `$hook_suffix` - // and a switch-case. This also helps prevent unnessecarily processing localized data when it isn't needed. - parent::admin_enqueue_scripts( $hook_suffix ); - } - - /** - * Enqueue our file upload scripts and styles. - * @param $hook - */ - function og_admin_enqueue_scripts( $hook ) { - - if ( 'all-in-one-seo_page_aiosp_opengraph' != $hook && 'term.php' != $hook ) { - // Only enqueue if we're on the social module settings page. - return; - } - - wp_enqueue_script( 'media-upload' ); - wp_enqueue_script( 'thickbox' ); - wp_enqueue_style( 'thickbox' ); - wp_enqueue_media(); - } - - function save_tax_data( $term_id, $tt_id, $taxonomy ) { - static $update = false; - if ( $update ) { - return; - } - if ( $this->locations !== null ) { - foreach ( $this->locations as $k => $v ) { - if ( isset( $v['type'] ) && ( $v['type'] === 'metabox' ) ) { - $opts = $this->default_options( $k ); - $options = array(); - $update = false; - foreach ( $opts as $l => $o ) { - if ( isset( $_POST[ $l ] ) ) { - $options[ $l ] = stripslashes_deep( $_POST[ $l ] ); - $options[ $l ] = esc_attr( $options[ $l ] ); - $update = true; - } - } - if ( $update ) { - $prefix = $this->get_prefix( $k ); - $options = apply_filters( $prefix . 'filter_term_metabox_options', $options, $k, $term_id ); - update_term_meta( $term_id, '_' . $prefix . $k, $options ); - } - } - } - } - } - - /** - * Returns the placeholder filtered and ready for DOM display. - * filter:aioseop_opengraph_placeholder - * @since 2.4.14 - * - * @param mixed $placeholder Placeholder to be filtered. - * @param string $type Type of the value to be filtered. - * - * @return string - */ - public function filter_placeholder( $placeholder, $type = 'text' ) { - return strip_tags( trim( $placeholder ) ); - } - - /** - * Returns filtered default options. - * filter:{prefix}default_options - * @since 2.4.13 - * - * @param array $options Default options. - * @param string $location Location. - * - * @return array - */ - public function filter_default_options( $options, $location ) { - if ( $location === 'settings' ) { - $prefix = $this->get_prefix( $location ) . $location . '_'; - // Add image checker as default - $options[ $prefix . 'customimg_checker' ] = 0; - } - return $options; - } - } -} +name = __( 'Social Meta', 'all-in-one-seo-pack' ); // Human-readable name of the plugin + $this->prefix = 'aiosp_opengraph_'; // option prefix + $this->file = __FILE__; // the current file + $this->fb_object_types = array( + 'Activities' => array( + 'activity' => __( 'Activity', 'all-in-one-seo-pack' ), + 'sport' => __( 'Sport', 'all-in-one-seo-pack' ), + ), + 'Businesses' => array( + 'bar' => __( 'Bar', 'all-in-one-seo-pack' ), + 'company' => __( 'Company', 'all-in-one-seo-pack' ), + 'cafe' => __( 'Cafe', 'all-in-one-seo-pack' ), + 'hotel' => __( 'Hotel', 'all-in-one-seo-pack' ), + 'restaurant' => __( 'Restaurant', 'all-in-one-seo-pack' ), + ), + 'Groups' => array( + 'cause' => __( 'Cause', 'all-in-one-seo-pack' ), + 'sports_league' => __( 'Sports League', 'all-in-one-seo-pack' ), + 'sports_team' => __( 'Sports Team', 'all-in-one-seo-pack' ), + ), + 'Organizations' => array( + 'band' => __( 'Band', 'all-in-one-seo-pack' ), + 'government' => __( 'Government', 'all-in-one-seo-pack' ), + 'non_profit' => __( 'Non Profit', 'all-in-one-seo-pack' ), + 'school' => __( 'School', 'all-in-one-seo-pack' ), + 'university' => __( 'University', 'all-in-one-seo-pack' ), + ), + 'People' => array( + 'actor' => __( 'Actor', 'all-in-one-seo-pack' ), + 'athlete' => __( 'Athlete', 'all-in-one-seo-pack' ), + 'author' => __( 'Author', 'all-in-one-seo-pack' ), + 'director' => __( 'Director', 'all-in-one-seo-pack' ), + 'musician' => __( 'Musician', 'all-in-one-seo-pack' ), + 'politician' => __( 'Politician', 'all-in-one-seo-pack' ), + 'profile' => __( 'Profile', 'all-in-one-seo-pack' ), + 'public_figure' => __( 'Public Figure', 'all-in-one-seo-pack' ), + ), + 'Places' => array( + 'city' => __( 'City', 'all-in-one-seo-pack' ), + 'country' => __( 'Country', 'all-in-one-seo-pack' ), + 'landmark' => __( 'Landmark', 'all-in-one-seo-pack' ), + 'state_province' => __( 'State Province', 'all-in-one-seo-pack' ), + ), + 'Products and Entertainment' => array( + 'album' => __( 'Album', 'all-in-one-seo-pack' ), + 'book' => __( 'Book', 'all-in-one-seo-pack' ), + 'drink' => __( 'Drink', 'all-in-one-seo-pack' ), + 'food' => __( 'Food', 'all-in-one-seo-pack' ), + 'game' => __( 'Game', 'all-in-one-seo-pack' ), + 'movie' => __( 'Movie', 'all-in-one-seo-pack' ), + 'product' => __( 'Product', 'all-in-one-seo-pack' ), + 'song' => __( 'Song', 'all-in-one-seo-pack' ), + 'tv_show' => __( 'TV Show', 'all-in-one-seo-pack' ), + 'episode' => __( 'Episode', 'all-in-one-seo-pack' ), + ), + 'Websites' => array( + 'article' => __( 'Article', 'all-in-one-seo-pack' ), + 'website' => __( 'Website', 'all-in-one-seo-pack' ), + ), + ); + parent::__construct(); + + if ( is_admin() ) { + add_action( 'admin_init', array( $this, 'admin_init' ), 5 ); + } else { + add_action( 'wp', array( $this, 'type_setup' ) ); + } + + if ( ! is_admin() || defined( 'DOING_AJAX' ) || defined( 'AIOSEOP_UNIT_TESTING' ) ) { + $this->do_opengraph(); + } + // Set variables after WordPress load. + add_action( 'init', array( &$this, 'init' ), 999999 ); + add_filter( 'jetpack_enable_open_graph', '__return_false' ); // Avoid having duplicate meta tags + add_filter( $this->prefix . 'meta', array( $this, 'handle_meta_tag' ), 10, 5 ); + // Force refresh of Facebook cache. + add_action( 'post_updated', array( &$this, 'force_fb_refresh_update' ), 10, 3 ); + add_action( 'transition_post_status', array( &$this, 'force_fb_refresh_transition' ), 10, 3 ); + add_action( 'edited_term', array( &$this, 'save_tax_data' ), 10, 3 ); + // Adds special filters + add_filter( 'aioseop_opengraph_placeholder', array( &$this, 'filter_placeholder' ) ); + add_action( 'aiosp_activate_opengraph', array( $this, 'activate_module' ) ); + add_action( 'created_term', array( $this, 'created_term' ), 10, 3 ); + // Call to init to generate menus + $this->init(); + } + + /** + * Process meta tags for specific idiosyncrasies. + * + * @since 3.0 + * + * @param string $value The value that is proposed to be shown in the tag. + * @param string $network The social network. + * @param string $meta_tag The meta tag without the network name prefixed. + * @param string $network_meta_tag The meta tag with the network name prefixed. This is not always $network:$meta_tag. + * @param array $extra_params Extra parameters that might be required to process the meta tag. + * + * @return string The final value that will be shown. + */ + function handle_meta_tag( $value, $network, $meta_tag, $network_meta_tag, $extra_params ) { + switch ( $meta_tag ) { + case 'type': + // https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/1013 + if ( 'blog' === $value ) { + $value = 'website'; + } + break; + } + + /** + * Disables truncation of meta tags. Return true to shortcircuit and disable truncation. + * + * @since 3.0 + * + * @issue https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/808 + * @issue https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/2296 + * + * @param bool The value that is proposed to be shown in the tag. + * @param string $network The social network. + * @param string $meta_tag The meta tag without the network name prefixed. + * @param string $network_meta_tag The meta tag with the network name prefixed. This is not always $network:$meta_tag. + * @param array $extra_params Extra parameters that might be required to process the meta tag. + */ + if ( true === apply_filters( $this->prefix . 'disable_meta_tag_truncation', false, $network, $meta_tag, $network_meta_tag ) ) { + return $value; + } + + switch ( $network_meta_tag ) { + case 'og:description': + if ( isset( $extra_params['auto_generate_desc'] ) && $extra_params['auto_generate_desc'] ) { + // max 200, but respect full words. + if ( $this->strlen( $value ) > 200 ) { + $pos = $this->strpos( $value, ' ', 200 ); + $value = trim( $this->substr( $value, 0, $pos ) ); + } + } + break; + case 'twitter:description': + if ( isset( $extra_params['auto_generate_desc'] ) && $extra_params['auto_generate_desc'] ) { + // https://developer.twitter.com/en/docs/tweets/optimize-with-cards/overview/markup.html + $value = trim( $this->substr( $value, 0, 200 ) ); + } + break; + case 'twitter:title': + if ( isset( $extra_params['auto_generate_title'] ) && $extra_params['auto_generate_title'] ) { + // https://developer.twitter.com/en/docs/tweets/optimize-with-cards/overview/markup.html + $value = trim( $this->substr( $value, 0, 70 ) ); + } + break; + } + return $value; + } + + /** + * Sets the terms defaults after a new term is created. + * + * @param int $term_id Term ID. + * @param int $tt_id Term taxonomy ID. + * @param string $taxonomy Taxonomy slug. + */ + function created_term( $term_id, $tt_id, $taxonomy_name ) { + $k = 'settings'; + $prefix = $this->get_prefix( $k ); + $tax = get_taxonomy( $taxonomy_name ); + $this->set_object_type_for_taxonomy( $prefix, $k, $taxonomy_name, $tax, false, array( $term_id ) ); + } + + /** + * Sets the defaults for a taxonomy. + * + * @param string $prefix The prefix of this module. + * @param string $k The key against which the options will be determined/set. + * @param string $taxonomy_name The name of the taxonomy. + * @param Object $tax The taxonomy object. + * @param bool $bail_if_no_terms Bail if the taxonomy has no terms. + * @param array $terms The terms in the taxonomy. + */ + private function set_object_type_for_taxonomy( $prefix, $k, $taxonomy_name, $tax, $bail_if_no_terms = false, $terms = null ) { + $object_type = null; + if ( ! $terms ) { + $terms = get_terms( + $taxonomy_name, array( + 'meta_query' => array( + array( + 'key' => '_' . $prefix . $k, + 'compare' => 'NOT EXISTS', + ), + ), + 'number' => PHP_INT_MAX, + 'fields' => 'ids', + 'hide_empty' => false, + ) + ); + } + + if ( empty( $terms ) && $bail_if_no_terms ) { + return false; + } + + if ( true === $tax->_builtin ) { + $object_type = 'article'; + } else { + // custom taxonomy. Let's get a post against this to determine its post type. + $posts = get_posts( + array( + 'numberposts' => 1, + 'post_type' => 'any', + 'tax_query' => array( + array( + 'taxonomy' => $taxonomy_name, + 'field' => 'term_id', + 'terms' => $terms, + ), + ), + ) + ); + if ( $posts ) { + global $aioseop_options; + $post_type = $posts[0]->post_type; + if ( isset( $aioseop_options['modules'] ) && isset( $aioseop_options['modules'][ $this->prefix . 'options' ] ) ) { + $og_options = $aioseop_options['modules'][ $this->prefix . 'options' ]; + + // now let's see what default object type is set for this post type. + $object_type_set = $og_options[ $this->prefix . $post_type . '_fb_object_type' ]; + if ( ! empty( $object_type_set ) ) { + $object_type = $object_type_set; + } + } + } + } + + if ( $object_type ) { + $opts[ $prefix . $k . '_category' ] = $object_type; + foreach ( $terms as $term_id ) { + update_term_meta( $term_id, '_' . $prefix . $k, $opts ); + } + } + + return true; + } + + /** + * Called when this module is activated. + */ + public function activate_module() { + if ( $this->locations !== null ) { + foreach ( $this->locations as $k => $v ) { + if ( ! isset( $v['type'] ) || 'metabox' !== $v['type'] ) { + continue; + } + $this->set_virgin_tax_terms( $k ); + } + } + } + /** + * This iterates over all taxonomies that do not have a opengraph setting defined and sets the defaults. + * + * @param string $k The key against which the options will be determined/set. + */ + private function set_virgin_tax_terms( $k ) { + $prefix = $this->get_prefix( $k ); + $opts = $this->default_options( $k ); + $taxonomies = get_taxonomies( array( 'public' => true ), 'object' ); + if ( ! $taxonomies ) { + return; + } + foreach ( $taxonomies as $name => $tax ) { + $this->set_object_type_for_taxonomy( $prefix, $k, $name, $tax, true, null ); + + } + } + + /** + * Hook called after WordPress has been loaded. + * + * @since 2.4.14 + */ + public function init() { + $count_desc = __( ' characters. Open Graph allows up to a maximum of %1$s chars for the %2$s.', 'all-in-one-seo-pack' ); + // Create default options + $this->default_options = array( + 'scan_header' => array( + 'name' => __( 'Scan Header', 'all-in-one-seo-pack' ), + 'type' => 'custom', + 'save' => true, + ), + 'setmeta' => array( + 'name' => __( 'Use AIOSEO Title and Description', 'all-in-one-seo-pack' ), + 'type' => 'checkbox', + ), + 'key' => array( + 'name' => __( 'Facebook Admin ID', 'all-in-one-seo-pack' ), + 'default' => '', + 'type' => 'text', + ), + 'appid' => array( + 'name' => __( 'Facebook App ID', 'all-in-one-seo-pack' ), + 'default' => '', + 'type' => 'text', + ), + 'title_shortcodes' => array( + 'name' => __( 'Run Shortcodes In Title', 'all-in-one-seo-pack' ), + ), + 'description_shortcodes' => array( + 'name' => __( 'Run Shortcodes In Description', 'all-in-one-seo-pack' ), + ), + 'sitename' => array( + 'name' => __( 'Site Name', 'all-in-one-seo-pack' ), + 'default' => get_bloginfo( 'name' ), + 'type' => 'text', + ), + 'hometitle' => array( + 'name' => __( 'Home Title', 'all-in-one-seo-pack' ), + 'default' => '', + 'type' => 'textarea', + 'condshow' => array( + 'aiosp_opengraph_setmeta' => array( + 'lhs' => 'aiosp_opengraph_setmeta', + 'op' => '!=', + 'rhs' => 'on', + ), + ), + ), + 'description' => array( + 'name' => __( 'Home Description', 'all-in-one-seo-pack' ), + 'default' => '', + 'type' => 'textarea', + 'condshow' => array( + 'aiosp_opengraph_setmeta' => array( + 'lhs' => 'aiosp_opengraph_setmeta', + 'op' => '!=', + 'rhs' => 'on', + ), + ), + ), + 'homeimage' => array( + 'name' => __( 'Home Image', 'all-in-one-seo-pack' ), + 'type' => 'image', + ), + 'generate_descriptions' => array( + 'name' => __( 'Use Content For Autogenerated OG Descriptions', 'all-in-one-seo-pack' ), + 'default' => 0, + ), + 'defimg' => array( + 'name' => __( 'Select OG:Image Source', 'all-in-one-seo-pack' ), + 'type' => 'select', + 'initial_options' => array( + '' => __( 'Default Image' ), + 'featured' => __( 'Featured Image' ), + 'attach' => __( 'First Attached Image' ), + 'content' => __( 'First Image In Content' ), + 'custom' => __( 'Image From Custom Field' ), + 'author' => __( 'Post Author Image' ), + 'auto' => __( 'First Available Image' ), + ), + ), + 'fallback' => array( + 'name' => __( 'Use Default If No Image Found', 'all-in-one-seo-pack' ), + 'type' => 'checkbox', + ), + 'dimg' => array( + 'name' => __( 'Default OG:Image', 'all-in-one-seo-pack' ), + 'default' => AIOSEOP_PLUGIN_IMAGES_URL . 'default-user-image.png', + 'type' => 'image', + ), + 'dimgwidth' => array( + 'name' => __( 'Default Image Width', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + ), + 'dimgheight' => array( + 'name' => __( 'Default Image Height', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + ), + 'meta_key' => array( + 'name' => __( 'Use Custom Field For Image', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + ), + 'image' => array( + 'name' => __( 'Image', 'all-in-one-seo-pack' ), + 'type' => 'radio', + 'initial_options' => array( + 0 => '', + ), + ), + 'customimg' => array( + 'name' => __( 'Custom Image', 'all-in-one-seo-pack' ), + 'type' => 'image', + ), + 'imagewidth' => array( + 'name' => __( 'Specify Image Width', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + ), + 'imageheight' => array( + 'name' => __( 'Specify Image Height', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + ), + 'video' => array( + 'name' => __( 'Custom Video', 'all-in-one-seo-pack' ), + 'type' => 'text', + ), + 'videowidth' => array( + 'name' => __( 'Specify Video Width', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + 'condshow' => array( + 'aioseop_opengraph_settings_video' => array( + 'lhs' => 'aioseop_opengraph_settings_video', + 'op' => '!=', + 'rhs' => '', + ), + ), + ), + 'videoheight' => array( + 'name' => __( 'Specify Video Height', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + 'condshow' => array( + 'aioseop_opengraph_settings_video' => array( + 'lhs' => 'aioseop_opengraph_settings_video', + 'op' => '!=', + 'rhs' => '', + ), + ), + ), + 'defcard' => array( + 'name' => __( 'Default Twitter Card', 'all-in-one-seo-pack' ), + 'type' => 'select', + 'default' => 'summary', + 'initial_options' => array( + 'summary' => __( 'Summary', 'all-in-one-seo-pack' ), + 'summary_large_image' => __( 'Summary Large Image', 'all-in-one-seo-pack' ), + + /* + REMOVING THIS TWITTER CARD TYPE FROM SOCIAL META MODULE + 'photo' => __( 'Photo', 'all-in-one-seo-pack' ) + */ + ), + ), + 'setcard' => array( + 'name' => __( 'Twitter Card Type', 'all-in-one-seo-pack' ), + 'type' => 'select', + 'initial_options' => array( + 'summary_large_image' => __( 'Summary Large Image', 'all-in-one-seo-pack' ), + 'summary' => __( 'Summary', 'all-in-one-seo-pack' ), + + /* + REMOVING THIS TWITTER CARD TYPE FROM SOCIAL META MODULE + 'photo' => __( 'Photo', 'all-in-one-seo-pack' ) + */ + ), + ), + 'twitter_site' => array( + 'name' => __( 'Twitter Site', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + ), + 'twitter_creator' => array( + 'name' => __( 'Show Twitter Author', 'all-in-one-seo-pack' ), + ), + 'twitter_domain' => array( + 'name' => __( 'Twitter Domain', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + ), + 'customimg_twitter' => array( + 'name' => __( 'Custom Twitter Image', 'all-in-one-seo-pack' ), + 'type' => 'image', + ), + 'gen_tags' => array( + 'name' => __( 'Automatically Generate Article Tags', 'all-in-one-seo-pack' ), + ), + 'gen_keywords' => array( + 'name' => __( 'Use Keywords In Article Tags', 'all-in-one-seo-pack' ), + 'default' => 'on', + 'condshow' => array( 'aiosp_opengraph_gen_tags' => 'on' ), + ), + 'gen_categories' => array( + 'name' => __( 'Use Categories In Article Tags', 'all-in-one-seo-pack' ), + 'default' => 'on', + 'condshow' => array( 'aiosp_opengraph_gen_tags' => 'on' ), + ), + 'gen_post_tags' => array( + 'name' => __( 'Use Post Tags In Article Tags', 'all-in-one-seo-pack' ), + 'default' => 'on', + 'condshow' => array( 'aiosp_opengraph_gen_tags' => 'on' ), + ), + 'types' => array( + 'name' => __( 'Enable Facebook Meta for Post Types', 'all-in-one-seo-pack' ), + 'type' => 'multicheckbox', + 'default' => array( 'post' => 'post', 'page' => 'page' ), + 'initial_options' => $this->get_post_type_titles( array( '_builtin' => false ) ), + ), + 'title' => array( + 'name' => __( 'Title', 'all-in-one-seo-pack' ), + 'default' => '', + 'type' => 'text', + 'size' => 95, + 'count' => 1, + 'count_desc' => $count_desc, + ), + 'desc' => array( + 'name' => __( 'Description', 'all-in-one-seo-pack' ), + 'default' => '', + 'type' => 'textarea', + 'cols' => 250, + 'rows' => 4, + 'count' => 1, + 'count_desc' => $count_desc, + ), + 'category' => array( + 'name' => __( 'Facebook Object Type', 'all-in-one-seo-pack' ), + 'type' => 'select', + 'style' => '', + 'default' => '', + 'initial_options' => $this->fb_object_types, + ), + 'facebook_debug' => array( + 'name' => __( 'Facebook Debug', 'all-in-one-seo-pack' ), + 'type' => 'html', + 'save' => false, + 'default' => '' . __( 'Debug This Post', 'all-in-one-seo-pack' ) . '', + ), + 'section' => array( + 'name' => __( 'Article Section', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + 'condshow' => array( 'aioseop_opengraph_settings_category' => 'article' ), + ), + 'tag' => array( + 'name' => __( 'Article Tags', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + 'condshow' => array( 'aioseop_opengraph_settings_category' => 'article' ), + ), + 'facebook_publisher' => array( + 'name' => __( 'Show Facebook Publisher on Articles', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + ), + 'facebook_author' => array( + 'name' => __( 'Show Facebook Author on Articles', 'all-in-one-seo-pack' ), + ), + 'profile_links' => array( + 'name' => __( 'Social Profile Links', 'all-in-one-seo-pack' ), + 'type' => 'textarea', + 'cols' => 60, + 'rows' => 5, + ), + 'person_or_org' => array( + 'name' => __( 'Person or Organization?', 'all-in-one-seo-pack' ), + 'type' => 'radio', + 'initial_options' => array( + 'person' => __( 'Person', 'all-in-one-seo-pack' ), + 'org' => __( 'Organization', 'all-in-one-seo-pack' ), + ), + ), + 'social_name' => array( + 'name' => __( 'Associated Name', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + ), + ); + // load initial options / set defaults + $this->update_options(); + $display = array(); + if ( isset( $this->options['aiosp_opengraph_types'] ) && ! empty( $this->options['aiosp_opengraph_types'] ) ) { + $display = $this->options['aiosp_opengraph_types']; + } + $this->locations = array( + 'opengraph' => array( + 'name' => $this->name, + 'prefix' => 'aiosp_', + 'type' => 'settings', + 'options' => array( + 'scan_header', + 'setmeta', + 'key', + 'appid', + 'sitename', + 'title_shortcodes', + 'description_shortcodes', + 'hometitle', + 'description', + 'homeimage', + 'generate_descriptions', + 'defimg', + 'fallback', + 'dimg', + 'dimgwidth', + 'dimgheight', + 'meta_key', + 'defcard', + 'profile_links', + 'person_or_org', + 'social_name', + 'twitter_site', + 'twitter_creator', + 'twitter_domain', + 'gen_tags', + 'gen_keywords', + 'gen_categories', + 'gen_post_tags', + 'types', + 'facebook_publisher', + 'facebook_author', + ), + ), + 'settings' => array( + 'name' => __( 'Social Settings', 'all-in-one-seo-pack' ), + 'type' => 'metabox', + 'help_link' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/', + 'options' => array( + 'title', + 'desc', + 'image', + 'customimg', + 'imagewidth', + 'imageheight', + 'video', + 'videowidth', + 'videoheight', + 'category', + 'facebook_debug', + 'section', + 'tag', + 'setcard', + 'customimg_twitter', + ), + 'display' => apply_filters( 'aioseop_opengraph_display', $display ), + 'prefix' => 'aioseop_opengraph_', + ), + ); + $this->layout = array( + 'home' => array( + 'name' => __( 'Home Page Settings', 'all-in-one-seo-pack' ), + 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#use-aioseo-title-and-description', + 'options' => array( 'setmeta', 'sitename', 'hometitle', 'description', 'homeimage' ), + ), + 'image' => array( + 'name' => __( 'Image Settings', 'all-in-one-seo-pack' ), + 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#select-og-image-source', + 'options' => array( 'defimg', 'fallback', 'dimg', 'dimgwidth', 'dimgheight', 'meta_key' ), + ), + 'links' => array( + 'name' => __( 'Social Profile Links', 'all-in-one-seo-pack' ), + 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#social-profile-links', + 'options' => array( 'profile_links', 'person_or_org', 'social_name' ), + ), + 'facebook' => array( + 'name' => __( 'Facebook Settings', 'all-in-one-seo-pack' ), + 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#facebook-settings', + 'options' => array( + 'key', + 'appid', + 'types', + 'gen_tags', + 'gen_keywords', + 'gen_categories', + 'gen_post_tags', + 'facebook_publisher', + 'facebook_author', + ), + ), + 'twitter' => array( + 'name' => __( 'Twitter Settings', 'all-in-one-seo-pack' ), + 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#default-twitter-card', + 'options' => array( 'defcard', 'setcard', 'twitter_site', 'twitter_creator', 'twitter_domain' ), + ), + 'default' => array( + 'name' => __( 'Advanced Settings', 'all-in-one-seo-pack' ), + 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/', + 'options' => array(), // this is set below, to the remaining options -- pdb + ), + 'scan_meta' => array( + 'name' => __( 'Scan Social Meta', 'all-in-one-seo-pack' ), + 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#scan_meta', + 'options' => array( 'scan_header' ), + ), + ); + $other_options = array(); + foreach ( $this->layout as $k => $v ) { + $other_options = array_merge( $other_options, $v['options'] ); + } + + $this->layout['default']['options'] = array_diff( array_keys( $this->default_options ), $other_options ); + } + + /** + * Forces FaceBook OpenGraph to refresh its cache when a post is changed to + * + * @param $new_status + * @param $old_status + * @param $post + * + * @todo this and force_fb_refresh_update can probably have the remote POST extracted out. + * + * @see https://developers.facebook.com/docs/sharing/opengraph/using-objects#update + * @since 2.3.11 + */ + function force_fb_refresh_transition( $new_status, $old_status, $post ) { + if ( 'publish' !== $new_status ) { + return; + } + if ( 'future' !== $old_status ) { + return; + } + + $current_post_type = get_post_type(); + + // Only ping Facebook if Social SEO is enabled on this post type. + if ( $this->option_isset( 'types' ) && is_array( $this->options['aiosp_opengraph_types'] ) && in_array( $current_post_type, $this->options['aiosp_opengraph_types'] ) ) { + $post_url = aioseop_get_permalink( $post->ID ); + $endpoint = sprintf( + 'https://graph.facebook.com/?%s', http_build_query( + array( + 'id' => $post_url, + 'scrape' => true, + ) + ) + ); + wp_remote_post( $endpoint, array( 'blocking' => false ) ); + } + } + + /** + * Forces FaceBook OpenGraph refresh on update. + * + * @param $post_id + * @param $post_after + * + * @see https://developers.facebook.com/docs/sharing/opengraph/using-objects#update + * @since 2.3.11 + */ + function force_fb_refresh_update( $post_id, $post_after ) { + + $current_post_type = get_post_type(); + + // Only ping Facebook if Social SEO is enabled on this post type. + if ( 'publish' === $post_after->post_status && $this->option_isset( 'types' ) && is_array( $this->options['aiosp_opengraph_types'] ) && in_array( $current_post_type, $this->options['aiosp_opengraph_types'] ) ) { + $post_url = aioseop_get_permalink( $post_id ); + $endpoint = sprintf( + 'https://graph.facebook.com/?%s', http_build_query( + array( + 'id' => $post_url, + 'scrape' => true, + ) + ) + ); + wp_remote_post( $endpoint, array( 'blocking' => false ) ); + } + } + + function settings_page_init() { + add_filter( 'aiosp_output_option', array( $this, 'display_custom_options' ), 10, 2 ); + } + + function filter_options( $options, $location ) { + if ( $location == 'settings' ) { + $prefix = $this->get_prefix( $location ) . $location . '_'; + list( $legacy, $images ) = $this->get_all_images( $options ); + if ( isset( $options ) && isset( $options[ "{$prefix}image" ] ) ) { + $thumbnail = $options[ "{$prefix}image" ]; + if ( ctype_digit( (string) $thumbnail ) || ( $thumbnail == 'post' ) ) { + if ( $thumbnail == 'post' ) { + $thumbnail = $images['post1']; + } elseif ( ! empty( $legacy[ $thumbnail ] ) ) { + $thumbnail = $legacy[ $thumbnail ]; + } + } + $options[ "{$prefix}image" ] = $thumbnail; + } + if ( empty( $options[ $prefix . 'image' ] ) ) { + $img = array_keys( $images ); + if ( ! empty( $img ) && ! empty( $img[1] ) ) { + $options[ $prefix . 'image' ] = $img[1]; + } + } + } + + return $options; + } + + /** + * Applies filter to module settings. + * + * @since 2.3.11 + * @since 2.4.14 Added filter for description and title placeholders. + * @since 2.3.15 do_shortcode on description. + * + * @see [plugin]\admin\aioseop_module_class.php > display_options() + */ + function filter_settings( $settings, $location, $current ) { + global $aiosp, $post; + if ( $location == 'opengraph' || $location == 'settings' ) { + $prefix = $this->get_prefix( $location ) . $location . '_'; + if ( $location == 'opengraph' ) { + return $settings; + } + if ( $location == 'settings' ) { + list( $legacy, $settings[ $prefix . 'image' ]['initial_options'] ) = $this->get_all_images( $current ); + $opts = array( 'title', 'desc' ); + $current_post_type = get_post_type(); + if ( isset( $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ] ) ) { + $flat_type_list = array(); + foreach ( $this->fb_object_types as $k => $v ) { + if ( is_array( $v ) ) { + $flat_type_list = array_merge( $flat_type_list, $v ); + } else { + $flat_type_list[ $k ] = $v; + } + } + $default_fb_type = $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ]; + // https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/1013 + // if 'blog' is the selected type but because it is no longer a schema type, we use 'website' instead. + if ( 'blog' === $default_fb_type ) { + $default_fb_type = 'website'; + } + if ( isset( $flat_type_list[ $default_fb_type ] ) ) { + $default_fb_type = $flat_type_list[ $default_fb_type ]; + } + $settings[ $prefix . 'category' ]['initial_options'] = array_merge( + array( + $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ] => __( 'Default ', 'all-in-one-seo-pack' ) . ' - ' . $default_fb_type, + ), + $settings[ $prefix . 'category' ]['initial_options'] + ); + } + if ( isset( $this->options['aiosp_opengraph_defcard'] ) ) { + $settings[ $prefix . 'setcard' ]['default'] = $this->options['aiosp_opengraph_defcard']; + } + $info = $aiosp->get_page_snippet_info(); + $title = $info['title']; + $description = $info['description']; + + // Description options + if ( is_object( $post ) ) { + // Always show excerpt + $description = empty( $this->options['aiosp_opengraph_generate_descriptions'] ) + ? $aiosp->trim_excerpt_without_filters( + $aiosp->internationalize( preg_replace( '/\s+/', ' ', $post->post_excerpt ) ), + 1000 + ) + : $aiosp->trim_excerpt_without_filters( + $aiosp->internationalize( preg_replace( '/\s+/', ' ', $post->post_content ) ), + 1000 + ); + } + + // #1308 - we want to make sure we are ignoring php version only in the admin area while editing the post, so that it does not impact #932. + $screen = get_current_screen(); + $ignore_php_version = is_admin() && isset( $screen->id ) && 'post' == $screen->id; + + // Add filters + $description = apply_filters( 'aioseop_description', $description, false, $ignore_php_version ); + // Add placholders + $settings[ "{$prefix}title" ]['placeholder'] = apply_filters( 'aioseop_opengraph_placeholder', $title ); + $settings[ "{$prefix}desc" ]['placeholder'] = apply_filters( 'aioseop_opengraph_placeholder', $description ); + } + if ( isset( $current[ $prefix . 'setmeta' ] ) && $current[ $prefix . 'setmeta' ] ) { + foreach ( $opts as $opt ) { + if ( isset( $settings[ $prefix . $opt ] ) ) { + $settings[ $prefix . $opt ]['type'] = 'hidden'; + $settings[ $prefix . $opt ]['label'] = 'none'; + unset( $settings[ $prefix . $opt ]['count'] ); + } + } + } + } + + return $settings; + } + + /** + * Applies filter to module options. + * These will display in the "Social Settings" object tab. + * filter:{prefix}override_options + * + * @since 2.3.11 + * @since 2.4.14 Overrides empty og:type values. + * + * @see [plugin]\admin\aioseop_module_class.php > display_options() + * + * @global array $aioseop_options Plugin options. + * + * @param array $options Current options. + * @param string $location Location where filter is called. + * @param array $settings Settings. + * + * @return array + */ + function override_options( $options, $location, $settings ) { + global $aioseop_options; + // Prepare default and prefix + $prefix = $this->get_prefix( $location ) . $location . '_'; + $opts = array(); + + foreach ( $settings as $k => $v ) { + if ( $v['save'] ) { + $opts[ $k ] = $v['default']; + } + } + foreach ( $options as $k => $v ) { + switch ( $k ) { + case $prefix . 'category': + if ( empty( $v ) ) { + // Get post type + $type = isset( get_current_screen()->post_type ) + ? get_current_screen()->post_type + : null; + // Assign default from plugin options + if ( ! empty( $type ) + && isset( $aioseop_options['modules'] ) + && isset( $aioseop_options['modules']['aiosp_opengraph_options'] ) + && isset( $aioseop_options['modules']['aiosp_opengraph_options'][ 'aiosp_opengraph_' . $type . '_fb_object_type' ] ) + ) { + $options[ $prefix . 'category' ] = + $aioseop_options['modules']['aiosp_opengraph_options'][ 'aiosp_opengraph_' . $type . '_fb_object_type' ]; + } + } + break; + } + if ( $v === null ) { + unset( $options[ $k ] ); + } + } + $options = wp_parse_args( $options, $opts ); + + // https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/1013 + $post_types = $this->get_post_type_titles(); + foreach ( $post_types as $slug => $name ) { + $field = 'aiosp_opengraph_' . $slug . '_fb_object_type'; + if ( isset( $options[ $field ] ) && 'blog' === $options[ $field ] ) { + $options[ $field ] = 'website'; + } + } + + return $options; + } + + /** + * Applies filter to metabox settings before they are saved. + * Sets custom as default if a custom image is uploaded. + * filter:{prefix}filter_metabox_options + * filter:{prefix}filter_term_metabox_options + * + * @since 2.3.11 + * @since 2.4.14 Fixes for aioseop-pro #67 and other bugs found. + * + * @see [plugin]\admin\aioseop_module_class.php > save_post_data() + * @see [this file] > save_tax_data() + * + * @param array $options List of current options. + * @param string $location Location where filter is called. + * @param int $id Either post_id or term_id. + * + * @return array + */ + function filter_metabox_options( $options, $location, $post_id ) { + if ( $location == 'settings' ) { + $prefix = $this->get_prefix( $location ) . $location . '_'; + if ( isset( $options[ $prefix . 'customimg_checker' ] ) + && $options[ $prefix . 'customimg_checker' ] + ) { + $options[ $prefix . 'image' ] = $options[ $prefix . 'customimg' ]; + } + } + return $options; + } + + /** Custom settings **/ + function display_custom_options( $buf, $args ) { + if ( $args['name'] == 'aiosp_opengraph_scan_header' ) { + $buf .= '
    '; + $args['options']['type'] = 'submit'; + $args['attr'] = " class='button-primary' "; + $args['value'] = $args['options']['default'] = __( 'Scan Now', 'all-in-one-seo-pack' ); + $buf .= __( 'Scan your site for duplicate social meta tags.', 'all-in-one-seo-pack' ); + $buf .= '

    ' . $this->get_option_html( $args ); + $buf .= '
    '; + } + + return $buf; + } + + function add_attributes( $output ) { + // avoid having duplicate meta tags + $type = $this->type; + if ( empty( $type ) ) { + $type = 'website'; + } + $schema_types = array( + 'album' => 'MusicAlbum', + 'article' => 'Article', + 'bar' => 'BarOrPub', + 'blog' => 'Blog', + 'book' => 'Book', + 'cafe' => 'CafeOrCoffeeShop', + 'city' => 'City', + 'country' => 'Country', + 'episode' => 'Episode', + 'food' => 'FoodEvent', + 'game' => 'Game', + 'hotel' => 'Hotel', + 'landmark' => 'LandmarksOrHistoricalBuildings', + 'movie' => 'Movie', + 'product' => 'Product', + 'profile' => 'ProfilePage', + 'restaurant' => 'Restaurant', + 'school' => 'School', + 'sport' => 'SportsEvent', + 'website' => 'WebSite', + ); + + if ( ! empty( $schema_types[ $type ] ) ) { + $type = $schema_types[ $type ]; + } else { + $type = 'WebSite'; + } + + $attributes = apply_filters( + $this->prefix . 'attributes', array( + 'prefix="og: http://ogp.me/ns#"', + ) + ); + + foreach ( $attributes as $attr ) { + if ( strpos( $output, $attr ) === false ) { + $output .= "\n\t$attr "; + } + } + + return $output; + } + + /** + * Add our social meta. + * + * @since 1.0.0 + * @since 2.3.11.5 Support for multiple fb_admins. + * @since 2.3.13 Adds filter:aioseop_description on description. + * @since 2.4.14 Fixes for aioseop-pro #67. + * @since 2.3.15 Always do_shortcode on descriptions, removed for titles. + * + * @global object $post Current WP_Post object. + * @global object $aiosp All in one seo plugin object. + * @global array $aioseop_options All in one seo plugin options. + * @global object $wp_query WP_Query global instance. + */ + function add_meta() { + global $post, $aiosp, $aioseop_options, $wp_query; + $metabox = $this->get_current_options( array(), 'settings' ); + $key = $this->options['aiosp_opengraph_key']; + $key = $this->options['aiosp_opengraph_key']; + $dimg = $this->options['aiosp_opengraph_dimg']; + $current_post_type = get_post_type(); + $title = $description = $image = $video = ''; + $type = $this->type; + $sitename = $this->options['aiosp_opengraph_sitename']; + + // for some reason, options is not populated correctly during unit tests. + if ( defined( 'AIOSEOP_UNIT_TESTING' ) ) { + $this->options = $aioseop_options['modules'][ $this->prefix . 'options' ]; + } + + $appid = isset( $this->options['aiosp_opengraph_appid'] ) ? $this->options['aiosp_opengraph_appid'] : ''; + + if ( ! empty( $aioseop_options['aiosp_hide_paginated_descriptions'] ) ) { + $first_page = false; + if ( $aiosp->get_page_number() < 2 ) { + $first_page = true; + } + } else { + $first_page = true; + } + $url = $aiosp->aiosp_mrt_get_url( $wp_query ); + $url = apply_filters( 'aioseop_canonical_url', $url ); + + // this will collect the extra values that are required outside the below IF block. + $extra_params = array(); + + $setmeta = $this->options['aiosp_opengraph_setmeta']; + $social_links = ''; + if ( is_front_page() ) { + $title = $this->options['aiosp_opengraph_hometitle']; + if ( $first_page ) { + $description = $this->options['aiosp_opengraph_description']; + if ( empty( $description ) ) { + $description = get_bloginfo( 'description' ); + } + } + if ( ! empty( $this->options['aiosp_opengraph_homeimage'] ) ) { + $thumbnail = $this->options['aiosp_opengraph_homeimage']; + } else { + $thumbnail = $this->options['aiosp_opengraph_dimg']; + } + + /* If Use AIOSEO Title and Desc Selected */ + if ( $setmeta ) { + $title = $aiosp->wp_title(); + if ( $first_page ) { + $description = $aiosp->get_aioseop_description( $post ); + } + } + + /* Add some defaults */ + if ( empty( $title ) ) { + $title = get_bloginfo( 'name' ); + } + if ( empty( $sitename ) ) { + $sitename = get_bloginfo( 'name' ); + } + + if ( empty( $description ) && $first_page && ! empty( $post ) && ! post_password_required( $post ) ) { + + if ( ! empty( $post->post_content ) || ! empty( $post->post_excerpt ) ) { + $description = $aiosp->trim_excerpt_without_filters( $aiosp->internationalize( preg_replace( '/\s+/', ' ', $post->post_excerpt ) ), 1000 ); + + if ( ! empty( $this->options['aiosp_opengraph_generate_descriptions'] ) ) { + $description = $aiosp->trim_excerpt_without_filters( $aiosp->internationalize( preg_replace( '/\s+/', ' ', $post->post_content ) ), 1000 ); + } + } + } + + if ( empty( $description ) && $first_page ) { + $description = get_bloginfo( 'description' ); + } + if ( ! empty( $this->options['aiosp_opengraph_profile_links'] ) ) { + $social_links = $this->options['aiosp_opengraph_profile_links']; + if ( ! empty( $this->options['aiosp_opengraph_social_name'] ) ) { + $social_name = $this->options['aiosp_opengraph_social_name']; + } else { + $social_name = ''; + } + if ( $this->options['aiosp_opengraph_person_or_org'] == 'person' ) { + $social_type = 'Person'; + } else { + $social_type = 'Organization'; + } + } + } elseif ( is_singular() && $this->option_isset( 'types' ) + && is_array( $this->options['aiosp_opengraph_types'] ) + && in_array( $current_post_type, $this->options['aiosp_opengraph_types'] ) + ) { + + if ( $type == 'article' ) { + if ( ! empty( $metabox['aioseop_opengraph_settings_section'] ) ) { + $section = $metabox['aioseop_opengraph_settings_section']; + } + if ( ! empty( $metabox['aioseop_opengraph_settings_tag'] ) ) { + $tag = $metabox['aioseop_opengraph_settings_tag']; + } + if ( ! empty( $this->options['aiosp_opengraph_facebook_publisher'] ) ) { + $publisher = $this->options['aiosp_opengraph_facebook_publisher']; + } + } + + if ( ! empty( $this->options['aiosp_opengraph_twitter_domain'] ) ) { + $domain = $this->options['aiosp_opengraph_twitter_domain']; + } + + if ( $type == 'article' && ! empty( $post ) ) { + if ( isset( $post->post_author ) && ! empty( $this->options['aiosp_opengraph_facebook_author'] ) ) { + $author = get_the_author_meta( 'facebook', $post->post_author ); + } + + if ( isset( $post->post_date_gmt ) ) { + $published_time = date( 'Y-m-d\TH:i:s\Z', mysql2date( 'U', $post->post_date_gmt ) ); + } + + if ( isset( $post->post_modified_gmt ) ) { + $modified_time = date( 'Y-m-d\TH:i:s\Z', mysql2date( 'U', $post->post_modified_gmt ) ); + } + } + + $image = $metabox['aioseop_opengraph_settings_image']; + $video = $metabox['aioseop_opengraph_settings_video']; + $title = $metabox['aioseop_opengraph_settings_title']; + $description = $metabox['aioseop_opengraph_settings_desc']; + + // Let's make a note of manually provided descriptions/titles as they might need special handling. + // @issue https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/808 + // @issue https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/2296 + $title_from_main_settings = trim( strip_tags( get_post_meta( $post->ID, '_aioseop_title', true ) ) ); + $desc_from_main_settings = trim( strip_tags( get_post_meta( $post->ID, '_aioseop_description', true ) ) ); + if ( empty( $title ) && empty( $title_from_main_settings ) ) { + $extra_params['auto_generate_title'] = true; + } + if ( empty( $description ) && empty( $desc_from_main_settings ) ) { + $extra_params['auto_generate_desc'] = true; + } + + /* Add AIOSEO variables if Site Title and Desc from AIOSEOP not selected */ + global $aiosp; + if ( empty( $title ) ) { + $title = $aiosp->wp_title(); + } + if ( empty( $description ) ) { + $description = trim( strip_tags( get_post_meta( $post->ID, '_aioseop_description', true ) ) ); + } + + /* Add default title */ + if ( empty( $title ) ) { + $title = get_the_title(); + } + + // Add default description. + if ( empty( $description ) && ! post_password_required( $post ) ) { + + $description = $post->post_excerpt; + + if ( $this->options['aiosp_opengraph_generate_descriptions'] || empty( $description ) ) { + if ( ! AIOSEOPPRO || ( AIOSEOPPRO && apply_filters( $this->prefix . 'generate_descriptions_from_content', true, $post ) ) ) { + $description = $post->post_content; + } else { + $description = $post->post_excerpt; + } + } + } + if ( empty( $type ) ) { + $type = 'article'; + } + } elseif ( AIOSEOPPRO && ( is_category() || is_tag() || is_tax() ) ) { + if ( isset( $this->options['aioseop_opengraph_settings_category'] ) ) { + $type = $this->options['aioseop_opengraph_settings_category']; + } + if ( isset( $metabox['aioseop_opengraph_settings_category'] ) ) { + $type = $metabox['aioseop_opengraph_settings_category']; + } + if ( $type == 'article' ) { + if ( ! empty( $metabox['aioseop_opengraph_settings_section'] ) ) { + $section = $metabox['aioseop_opengraph_settings_section']; + } + if ( ! empty( $metabox['aioseop_opengraph_settings_tag'] ) ) { + $tag = $metabox['aioseop_opengraph_settings_tag']; + } + if ( ! empty( $this->options['aiosp_opengraph_facebook_publisher'] ) ) { + $publisher = $this->options['aiosp_opengraph_facebook_publisher']; + } + } + if ( ! empty( $this->options['aiosp_opengraph_twitter_domain'] ) ) { + $domain = $this->options['aiosp_opengraph_twitter_domain']; + } + if ( $type == 'article' && ! empty( $post ) ) { + if ( isset( $post->post_author ) && ! empty( $this->options['aiosp_opengraph_facebook_author'] ) ) { + $author = get_the_author_meta( 'facebook', $post->post_author ); + } + + if ( isset( $post->post_date_gmt ) ) { + $published_time = date( 'Y-m-d\TH:i:s\Z', mysql2date( 'U', $post->post_date_gmt ) ); + } + if ( isset( $post->post_modified_gmt ) ) { + $modified_time = date( 'Y-m-d\TH:i:s\Z', mysql2date( 'U', $post->post_modified_gmt ) ); + } + } + $image = $metabox['aioseop_opengraph_settings_image']; + $video = $metabox['aioseop_opengraph_settings_video']; + $title = $metabox['aioseop_opengraph_settings_title']; + $description = $metabox['aioseop_opengraph_settings_desc']; + /* Add AIOSEO variables if Site Title and Desc from AIOSEOP not selected */ + global $aiosp; + if ( empty( $title ) ) { + $title = $aiosp->wp_title(); + } + if ( empty( $description ) ) { + $term_id = isset( $_GET['tag_ID'] ) ? (int) $_GET['tag_ID'] : 0; + $term_id = $term_id ? $term_id : get_queried_object()->term_id; + $description = trim( strip_tags( get_term_meta( $term_id, '_aioseop_description', true ) ) ); + } + // Add default title + if ( empty( $title ) ) { + $title = get_the_title(); + } + // Add default description. + if ( empty( $description ) && ! post_password_required( $post ) ) { + $description = get_queried_object()->description; + } + if ( empty( $type ) ) { + // https://github.com/semperfiwebdesign/aioseop-pro/issues/321 + if ( AIOSEOPPRO && ( is_category() || is_tag() || is_tax() ) ) { + $og_options = $aioseop_options['modules'][ $this->prefix . 'options' ]; + $current_post_type = get_post_type(); + // check if the post type's object type is set. + if ( isset( $og_options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ] ) ) { + $type = $og_options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ]; + } elseif ( in_array( $current_post_type, array( 'post', 'page' ) ) ) { + $type = 'article'; + } + } else { + $type = 'website'; + } + } + } elseif ( is_home() && ! is_front_page() ) { + // This is the blog page but not the homepage. + global $aiosp; + $image = $metabox['aioseop_opengraph_settings_image']; + $video = $metabox['aioseop_opengraph_settings_video']; + $title = $metabox['aioseop_opengraph_settings_title']; + $description = $metabox['aioseop_opengraph_settings_desc']; + + if ( empty( $description ) ) { + // If there's not social description, fall back to the SEO description. + $description = trim( strip_tags( get_post_meta( get_option( 'page_for_posts' ), '_aioseop_description', true ) ) ); + } + if ( empty( $title ) ) { + $title = $aiosp->wp_title(); + } + } else { + return; + } + + if ( $type === 'article' && ! empty( $post ) && is_singular() ) { + if ( ! empty( $this->options['aiosp_opengraph_gen_tags'] ) ) { + if ( ! empty( $this->options['aiosp_opengraph_gen_keywords'] ) ) { + $keywords = $aiosp->get_main_keywords(); + $keywords = $this->apply_cf_fields( $keywords ); + $keywords = apply_filters( 'aioseop_keywords', $keywords ); + if ( ! empty( $keywords ) && ! empty( $tag ) ) { + $tag .= ',' . $keywords; + } elseif ( empty( $tag ) ) { + $tag = $keywords; + } + } + $tag = $aiosp->keyword_string_to_list( $tag ); + if ( ! empty( $this->options['aiosp_opengraph_gen_categories'] ) ) { + $tag = array_merge( $tag, $aiosp->get_all_categories( $post->ID ) ); + } + if ( ! empty( $this->options['aiosp_opengraph_gen_post_tags'] ) ) { + $tag = array_merge( $tag, $aiosp->get_all_tags( $post->ID ) ); + } + } + if ( ! empty( $tag ) ) { + $tag = $aiosp->clean_keyword_list( $tag ); + } + } + + if ( ! empty( $this->options['aiosp_opengraph_title_shortcodes'] ) ) { + $title = do_shortcode( $title ); + } + if ( ! empty( $description ) ) { + $description = $aiosp->internationalize( preg_replace( '/\s+/', ' ', $description ) ); + if ( ! empty( $this->options['aiosp_opengraph_description_shortcodes'] ) ) { + $description = do_shortcode( $description ); + } + $description = $aiosp->trim_excerpt_without_filters( $description, 1000 ); + } + + $title = $this->apply_cf_fields( $title ); + $description = $this->apply_cf_fields( $description ); + + /* Data Validation */ + $title = strip_tags( esc_attr( $title ) ); + $sitename = strip_tags( esc_attr( $sitename ) ); + $description = strip_tags( esc_attr( $description ) ); + + if ( empty( $thumbnail ) && ! empty( $image ) ) { + $thumbnail = $image; + } + + // Add user supplied default image. + if ( empty( $thumbnail ) ) { + if ( empty( $this->options['aiosp_opengraph_defimg'] ) ) { + $thumbnail = $this->options['aiosp_opengraph_dimg']; + } else { + $img_type = $this->options['aiosp_opengraph_defimg']; + if ( ! empty( $post ) ) { + // Customize the type of image per post/post_type. + $img_type = apply_filters( $this->prefix . 'default_image_type', $img_type, $post, $type ); + } + switch ( $img_type ) { + case 'featured': + $thumbnail = $this->get_the_image_by_post_thumbnail(); + break; + case 'attach': + $thumbnail = $this->get_the_image_by_attachment(); + break; + case 'content': + $thumbnail = $this->get_the_image_by_scan(); + break; + case 'custom': + $meta_key = $this->options['aiosp_opengraph_meta_key']; + if ( ! empty( $meta_key ) && ! empty( $post ) ) { + $meta_key = explode( ',', $meta_key ); + $thumbnail = $this->get_the_image_by_meta_key( + array( + 'post_id' => $post->ID, + 'meta_key' => $meta_key, + ) + ); + } + break; + case 'auto': + $thumbnail = $this->get_the_image(); + break; + case 'author': + $thumbnail = $this->get_the_image_by_author(); + break; + default: + $thumbnail = $this->options['aiosp_opengraph_dimg']; + } + } + } + + if ( empty( $thumbnail ) && ! empty( $this->options['aiosp_opengraph_fallback'] ) ) { + $thumbnail = $this->options['aiosp_opengraph_dimg']; + if ( ! empty( $post ) ) { + // Customize the default image per post/post_type. + $thumbnail = apply_filters( $this->prefix . 'default_image', $thumbnail, $post, $type ); + } + } + + if ( ! empty( $thumbnail ) ) { + $thumbnail = esc_url( $thumbnail ); + $thumbnail = set_url_scheme( $thumbnail ); + } + + $width = $height = ''; + if ( ! empty( $thumbnail ) ) { + if ( ! empty( $metabox['aioseop_opengraph_settings_imagewidth'] ) ) { + $width = $metabox['aioseop_opengraph_settings_imagewidth']; + } + if ( ! empty( $metabox['aioseop_opengraph_settings_imageheight'] ) ) { + $height = $metabox['aioseop_opengraph_settings_imageheight']; + } + if ( empty( $width ) && ! empty( $this->options['aiosp_opengraph_dimgwidth'] ) ) { + $width = $this->options['aiosp_opengraph_dimgwidth']; + } + if ( empty( $height ) && ! empty( $this->options['aiosp_opengraph_dimgheight'] ) ) { + $height = $this->options['aiosp_opengraph_dimgheight']; + } + } + + if ( ! empty( $video ) ) { + if ( ! empty( $metabox['aioseop_opengraph_settings_videowidth'] ) ) { + $videowidth = $metabox['aioseop_opengraph_settings_videowidth']; + } + if ( ! empty( $metabox['aioseop_opengraph_settings_videoheight'] ) ) { + $videoheight = $metabox['aioseop_opengraph_settings_videoheight']; + } + } + + $card = 'summary'; + if ( ! empty( $this->options['aiosp_opengraph_defcard'] ) ) { + $card = $this->options['aiosp_opengraph_defcard']; + } + + if ( ! empty( $metabox['aioseop_opengraph_settings_setcard'] ) ) { + $card = $metabox['aioseop_opengraph_settings_setcard']; + } + + // support for changing legacy twitter cardtype-photo to summary large image + if ( $card == 'photo' ) { + $card = 'summary_large_image'; + } + + $site = $domain = $creator = ''; + + if ( ! empty( $this->options['aiosp_opengraph_twitter_site'] ) ) { + $site = $this->options['aiosp_opengraph_twitter_site']; + $site = AIOSEOP_Opengraph_Public::prepare_twitter_username( $site ); + } + + if ( ! empty( $this->options['aiosp_opengraph_twitter_domain'] ) ) { + $domain = $this->options['aiosp_opengraph_twitter_domain']; + } + + if ( ! empty( $post ) && isset( $post->post_author ) && ! empty( $this->options['aiosp_opengraph_twitter_creator'] ) ) { + $creator = get_the_author_meta( 'twitter', $post->post_author ); + $creator = AIOSEOP_Opengraph_Public::prepare_twitter_username( $creator ); + } + + if ( ! empty( $thumbnail ) ) { + $twitter_thumbnail = $thumbnail; // Default Twitter image if custom isn't set. + } + + if ( isset( $metabox['aioseop_opengraph_settings_customimg_twitter'] ) && ! empty( $metabox['aioseop_opengraph_settings_customimg_twitter'] ) ) { + // Set Twitter image from custom. + $twitter_thumbnail = set_url_scheme( $metabox['aioseop_opengraph_settings_customimg_twitter'] ); + } + + // Apply last filters. + $description = apply_filters( 'aioseop_description', $description ); + + $meta = array( + 'facebook' => array( + 'title' => 'og:title', + 'type' => 'og:type', + 'url' => 'og:url', + 'thumbnail' => 'og:image', + 'width' => 'og:image:width', + 'height' => 'og:image:height', + 'video' => 'og:video', + 'videowidth' => 'og:video:width', + 'videoheight' => 'og:video:height', + 'sitename' => 'og:site_name', + 'key' => 'fb:admins', + 'appid' => 'fb:app_id', + 'description' => 'og:description', + 'section' => 'article:section', + 'tag' => 'article:tag', + 'publisher' => 'article:publisher', + 'author' => 'article:author', + 'published_time' => 'article:published_time', + 'modified_time' => 'article:modified_time', + ), + 'twitter' => array( + 'card' => 'twitter:card', + 'site' => 'twitter:site', + 'creator' => 'twitter:creator', + 'domain' => 'twitter:domain', + 'title' => 'twitter:title', + 'description' => 'twitter:description', + 'twitter_thumbnail' => 'twitter:image', + ), + ); + + // Only show if "use schema.org markup is checked". + if ( ! empty( $aioseop_options['aiosp_schema_markup'] ) ) { + $meta['google+'] = array( 'thumbnail' => 'image' ); + } + + // https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/1848 + if ( is_ssl() ) { + $meta['facebook'] += array( 'thumbnail_1' => 'og:image:secure_url' ); + $thumbnail_1 = $thumbnail; + } + + $tags = array( + 'facebook' => array( 'name' => 'property', 'value' => 'content' ), + 'twitter' => array( 'name' => 'name', 'value' => 'content' ), + 'google+' => array( 'name' => 'itemprop', 'value' => 'content' ), + ); + + foreach ( $meta as $t => $data ) { + foreach ( $data as $k => $v ) { + if ( empty( $$k ) ) { + $$k = ''; + } + $filtered_value = $$k; + + /** + * Process meta tags for their idiosyncracies. + * + * @since 3.0 + * + * @param string $filtered_value The value that is proposed to be shown in the tag. + * @param string $t The social network. + * @param string $k The meta tag without the network name prefixed. + * @param string $v The meta tag with the network name prefixed. This is not always $network:$meta_tag. + * @param array $extra_params Extra parameters that might be required to process the meta tag. + */ + $filtered_value = apply_filters( $this->prefix . 'meta', $filtered_value, $t, $k, $v, $extra_params ); + if ( ! empty( $filtered_value ) ) { + if ( ! is_array( $filtered_value ) ) { + $filtered_value = array( $filtered_value ); + } + + /** + * This is to accomodate multiple fb:admins on separate lines. + * @TODO Eventually we'll want to put this in its own function so things like images work too. + */ + if ( 'key' === $k ) { + $fbadmins = explode( ',', str_replace( ' ', '', $filtered_value[0] ) ); // Trim spaces then turn comma-separated values into an array. + foreach ( $fbadmins as $fbadmin ) { + echo '' . "\n"; + } + } else { + // For everything else. + foreach ( $filtered_value as $f ) { + // #1363: use esc_attr( $f ) instead of htmlspecialchars_decode( $f, ENT_QUOTES ) + echo '' . "\n"; + } + } + } + } + } + $social_link_schema = ''; + if ( ! empty( $social_links ) ) { + $home_url = esc_url( get_home_url() ); + $social_links = explode( "\n", $social_links ); + foreach ( $social_links as $k => $v ) { + $v = trim( $v ); + if ( empty( $v ) ) { + unset( $social_links[ $k ] ); + } else { + $v = esc_url( $v ); + $social_links[ $k ] = $v; + } + } + $social_links = join( '","', $social_links ); + $social_link_schema = << +{ "@context" : "http://schema.org", + "@type" : "{$social_type}", + "name" : "{$social_name}", + "url" : "{$home_url}", + "sameAs" : ["{$social_links}"] +} + + +END; + } + + // Only show if "use schema.org markup is checked". + if ( ! empty( $aioseop_options['aiosp_schema_markup'] ) ) { + echo apply_filters( 'aiosp_opengraph_social_link_schema', $social_link_schema ); + } + } + + /** + * Do / adds opengraph properties to meta. + * @since 2.3.11 + * + * @global array $aioseop_options AIOSEOP plugin options. + */ + public function do_opengraph() { + global $aioseop_options; + if ( ! empty( $aioseop_options ) + && ! empty( $aioseop_options['aiosp_schema_markup'] ) + ) { + add_filter( 'language_attributes', array( &$this, 'add_attributes' ) ); + } + if ( ! defined( 'DOING_AJAX' ) ) { + add_action( 'aioseop_modules_wp_head', array( &$this, 'add_meta' ), 5 ); + // Add social meta to AMP plugin. + if ( apply_filters( 'aioseop_enable_amp_social_meta', true ) === true ) { + add_action( 'amp_post_template_head', array( &$this, 'add_meta' ), 12 ); + } + } + } + + /** + * Set up types. + * + * @since ? + * @since 2.3.15 Change to website for homepage and blog post index page, default to object. + */ + function type_setup() { + $this->type = 'object'; // Default to type object if we don't have some other rule. + + if ( is_home() || is_front_page() ) { + $this->type = 'website'; // Home page and blog page should be website. + } elseif ( is_singular() && $this->option_isset( 'types' ) ) { + $metabox = $this->get_current_options( array(), 'settings' ); + $current_post_type = get_post_type(); + if ( ! empty( $metabox['aioseop_opengraph_settings_category'] ) ) { + $this->type = $metabox['aioseop_opengraph_settings_category']; + } elseif ( isset( $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ] ) ) { + $this->type = $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ]; + } + } + } + + /** + * Inits hooks and others for admin init. + * action:admin_init. + * + * @since 2.3.11 + * @since 2.4.14 Refactored function name, and new filter added for defaults and missing term metabox. + */ + function admin_init() { + add_filter( $this->prefix . 'display_settings', array( &$this, 'filter_settings' ), 10, 3 ); + add_filter( $this->prefix . 'override_options', array( &$this, 'override_options' ), 10, 3 ); + add_filter( + $this->get_prefix( 'settings' ) . 'default_options', array( + &$this, + 'filter_default_options', + ), 10, 2 + ); + add_filter( + $this->get_prefix( 'settings' ) . 'filter_metabox_options', array( + &$this, + 'filter_metabox_options', + ), 10, 3 + ); + add_filter( + $this->get_prefix( 'settings' ) . 'filter_term_metabox_options', array( + &$this, + 'filter_metabox_options', + ), 10, 3 + ); + $post_types = $this->get_post_type_titles(); + $rempost = array( + 'revision' => 1, + 'nav_menu_item' => 1, + 'custom_css' => 1, + 'customize_changeset' => 1, + ); + $post_types = array_diff_key( $post_types, $rempost ); + $this->default_options['types']['initial_options'] = $post_types; + foreach ( $post_types as $slug => $name ) { + $field = $slug . '_fb_object_type'; + $this->default_options[ $field ] = array( + 'name' => "$name " . __( 'Object Type', 'all-in-one-seo-pack' ) . "
    ($slug)", + 'type' => 'select', + 'style' => '', + 'initial_options' => $this->fb_object_types, + 'default' => 'article', + 'condshow' => array( 'aiosp_opengraph_types\[\]' => $slug ), + ); + $this->locations['opengraph']['options'][] = $field; + $this->layout['facebook']['options'][] = $field; + } + $this->setting_options(); + } + + function get_all_images( $options = null, $p = null ) { + static $img = array(); + if ( ! is_array( $options ) ) { + $options = array(); + } + if ( ! empty( $this->options['aiosp_opengraph_meta_key'] ) ) { + $options['meta_key'] = $this->options['aiosp_opengraph_meta_key']; + } + if ( empty( $img ) ) { + $size = apply_filters( 'post_thumbnail_size', 'large' ); + $default = $this->get_the_image_by_default(); + if ( ! empty( $default ) ) { + $default = set_url_scheme( $default ); + $img[ $default ] = 0; + } + $img = array_merge( $img, parent::get_all_images( $options, null ) ); + } + + if ( ! empty( $options ) && ! empty( $options['aioseop_opengraph_settings_customimg'] ) ) { + $img[ $options['aioseop_opengraph_settings_customimg'] ] = 'customimg'; + } + + if ( ! empty( $options ) && ! empty( $options['aioseop_opengraph_settings_customimg'] ) ) { + $img[ $options['aioseop_opengraph_settings_customimg'] ] = 'customimg'; + $img[ $options['aioseop_opengraph_settings_customimg_twitter'] ] = 'customimg_twitter'; + } + + if ( $author_img = $this->get_the_image_by_author( $p ) ) { + $image['author'] = $author_img; + } + $image = array_flip( $img ); + $images = array(); + if ( ! empty( $image ) ) { + foreach ( $image as $k => $v ) { + $images[ $v ] = ''; + } + } + + return array( $image, $images ); + } + + function get_the_image_by_author( $options = null, $p = null ) { + if ( $p === null ) { + global $post; + } else { + $post = $p; + } + if ( ! empty( $post ) && ! empty( $post->post_author ) ) { + $matches = array(); + $get_avatar = get_avatar( $post->post_author, 300 ); + if ( preg_match( "/src='(.*?)'/i", $get_avatar, $matches ) ) { + return $matches[1]; + } + } + + return false; + } + + function get_the_image( $options = null, $p = null ) { + $meta_key = $this->options['aiosp_opengraph_meta_key']; + + return parent::get_the_image( array( 'meta_key' => $meta_key ), $p ); + } + + function get_the_image_by_default( $args = array() ) { + return $this->options['aiosp_opengraph_dimg']; + } + + function settings_update() { + + } + + /** + * Admin Enqueue Scripts + * + * Add hook in \All_in_One_SEO_Pack_Module::enqueue_metabox_scripts - Bails adding hook if not on target valid screen. + * Add hook in \All_in_One_SEO_Pack_Module::add_page_hooks - Function itself is hooked based on the screen_id/page. + * + * @since 2.9.2 + * + * @see 'admin_enqueue_scripts' hook + * @link https://developer.wordpress.org/reference/hooks/admin_enqueue_scripts/ + * + * @param string $hook_suffix + */ + public function admin_enqueue_scripts( $hook_suffix ) { + wp_enqueue_script( + 'aioseop-opengraph-script', + AIOSEOP_PLUGIN_URL . 'js/modules/aioseop_opengraph.js', + array(), + AIOSEOP_VERSION + ); + + // Dev note: If certain JS files need to be restricted to select screens, then follow concept + // used in `All_in_One_SEO_Pack::admin_enqueue_scripts()` (v2.9.1); which uses the `$hook_suffix` + // and a switch-case. This also helps prevent unnessecarily processing localized data when it isn't needed. + parent::admin_enqueue_scripts( $hook_suffix ); + } + + /** + * Enqueue our file upload scripts and styles. + * @param $hook + */ + function og_admin_enqueue_scripts( $hook ) { + + if ( 'all-in-one-seo_page_aiosp_opengraph' != $hook && 'term.php' != $hook ) { + // Only enqueue if we're on the social module settings page. + return; + } + + wp_enqueue_script( 'media-upload' ); + wp_enqueue_script( 'thickbox' ); + wp_enqueue_style( 'thickbox' ); + wp_enqueue_media(); + } + + function save_tax_data( $term_id, $tt_id, $taxonomy ) { + static $update = false; + if ( $update ) { + return; + } + if ( $this->locations !== null ) { + foreach ( $this->locations as $k => $v ) { + if ( isset( $v['type'] ) && ( $v['type'] === 'metabox' ) ) { + $opts = $this->default_options( $k ); + $options = array(); + $update = false; + foreach ( $opts as $l => $o ) { + if ( isset( $_POST[ $l ] ) ) { + $options[ $l ] = stripslashes_deep( $_POST[ $l ] ); + $options[ $l ] = esc_attr( $options[ $l ] ); + $update = true; + } + } + if ( $update ) { + $prefix = $this->get_prefix( $k ); + $options = apply_filters( $prefix . 'filter_term_metabox_options', $options, $k, $term_id ); + update_term_meta( $term_id, '_' . $prefix . $k, $options ); + } + } + } + } + } + + /** + * Returns the placeholder filtered and ready for DOM display. + * filter:aioseop_opengraph_placeholder + * @since 2.4.14 + * + * @param mixed $placeholder Placeholder to be filtered. + * @param string $type Type of the value to be filtered. + * + * @return string + */ + public function filter_placeholder( $placeholder, $type = 'text' ) { + return strip_tags( trim( $placeholder ) ); + } + + /** + * Returns filtered default options. + * filter:{prefix}default_options + * @since 2.4.13 + * + * @param array $options Default options. + * @param string $location Location. + * + * @return array + */ + public function filter_default_options( $options, $location ) { + if ( $location === 'settings' ) { + $prefix = $this->get_prefix( $location ) . $location . '_'; + // Add image checker as default + $options[ $prefix . 'customimg_checker' ] = 0; + } + return $options; + } + } +} diff --git a/tests/modules/opengraph/test-opengraph.php b/tests/modules/opengraph/test-opengraph.php index 7f23c1f4a..9c0b65fee 100644 --- a/tests/modules/opengraph/test-opengraph.php +++ b/tests/modules/opengraph/test-opengraph.php @@ -12,6 +12,243 @@ */ class Test_Opengraph extends AIOSEOP_Test_Base { + public function setUp() { + $this->init( true ); + } + + /** + * Provides the title and content for the posts to be used for meta tag testing. + */ + public function metaTagContentProvider() { + return array( + array( 'seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo', 'seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo seo', 203 ), + ); + } + + /** + * Checks whether the meta tags are being truncated correctly. + * + * Function: Adds a post with a long content and title and checks whether the meta tags are being truncated correctly + * Expected: The meta tags are being truncated according to the limits imposed. + * Actual: Currently works as expected. + * Reproduce: Insert a post and check the length of the meta tags content. + * + * @dataProvider metaTagContentProvider + * + * @since 3.0 + */ + public function test_meta_tag_truncation_all( $title, $content, $og_desc_limit ) { + $tag_limits = array( + 'og:description' => $og_desc_limit, // limit to 200 but respect full words + 'twitter:description' => 200, // hard limit to 200 + 'twitter:title' => 70, // hard limit to 70 + ); + + $id = $this->factory->post->create( array( 'post_title' => $title, 'post_content' => $content ) ); + + wp_set_current_user( 1 ); + + $options = get_option( 'aioseop_options' ); + $options['aiosp_cpostactive'] = array( 'post' ); + update_option( 'aioseop_options', $options ); + + $custom_options = array(); + $custom_options['aiosp_opengraph_types'] = array( 'post' ); + $custom_options['aiosp_opengraph_generate_descriptions'] = 'on'; + $this->_setup_options( 'opengraph', $custom_options ); + + $meta = $this->parse_html( get_permalink( $id ), array( 'meta' ) ); + + // should have atleast one meta tag. + $this->assertGreaterThan( 1, count( $meta ) ); + + foreach ( $meta as $m ) { + $tag = isset( $m['property'] ) ? $m['property'] : $m['name']; + if ( empty( $tag ) ) { + continue; + } + if ( array_key_exists( $tag, $tag_limits ) ) { + $this->assertLessThanOrEqual( $tag_limits[ $tag ], strlen( $m['content'] ) ); + } + } + } + + /** + * Checks whether the meta tags are being truncated correctly ONLY IF they are not being explicitly provided (in the opengraph metabox title). + * + * Function: Adds a post with a long content and title and with seo title and checks whether ONLY the description meta tags are being truncated correctly + * Expected: The meta tags are being truncated according to the limits imposed. + * Actual: Currently works as expected. + * Reproduce: Insert a post and check the length of the meta tags content. + * + * @dataProvider metaTagContentProvider + * + * @since 3.0 + */ + public function test_meta_tag_truncation_with_manual_og_title( $title, $content, $og_desc_limit ) { + $tag_limits = array( + 'og:description' => $og_desc_limit, // limit to 200 but respect full words + 'twitter:description' => 200, // hard limit to 200 + 'twitter:title' => array( 70 ), // no limit + ); + + wp_set_current_user( 1 ); + + $options = get_option( 'aioseop_options' ); + $options['aiosp_cpostactive'] = array( 'post' ); + update_option( 'aioseop_options', $options ); + + $custom_options = array(); + $custom_options['aiosp_opengraph_types'] = array( 'post' ); + $custom_options['aiosp_opengraph_generate_descriptions'] = 'on'; + $this->_setup_options( 'opengraph', $custom_options ); + + $id = $this->factory->post->create( array( 'post_title' => $title, 'post_content' => $content ) ); + + $settings = get_post_meta( $id, '_aioseop_opengraph_settings', true ); + $settings['aioseop_opengraph_settings_title'] = $title; + update_post_meta( $id, '_aioseop_opengraph_settings', $settings ); + + $meta = $this->parse_html( get_permalink( $id ), array( 'meta' ) ); + + // should have atleast one meta tag. + $this->assertGreaterThan( 1, count( $meta ) ); + + foreach ( $meta as $m ) { + $tag = isset( $m['property'] ) ? $m['property'] : $m['name']; + if ( empty( $tag ) ) { + continue; + } + if ( array_key_exists( $tag, $tag_limits ) ) { + if ( is_array( $tag_limits[ $tag ] ) ) { + $this->assertGreaterThan( $tag_limits[ $tag ][0], strlen( $m['content'] ) ); + } else { + $this->assertLessThanOrEqual( $tag_limits[ $tag ], strlen( $m['content'] ) ); + } + } + } + } + + /** + * Checks whether the meta tags are being truncated correctly ONLY IF they are not being explicitly provided (in the main metabox title). + * + * Function: Adds a post with a long content and title and with seo title and checks whether ONLY the description meta tags are being truncated correctly + * Expected: The meta tags are being truncated according to the limits imposed. + * Actual: Currently works as expected. + * Reproduce: Insert a post and check the length of the meta tags content. + * + * @dataProvider metaTagContentProvider + * + * @since 3.0 + */ + public function test_meta_tag_truncation_with_manual_main_title( $title, $content, $og_desc_limit ) { + $tag_limits = array( + 'og:description' => $og_desc_limit, // limit to 200 but respect full words + 'twitter:description' => 200, // hard limit to 200 + 'twitter:title' => array( 70 ), // no limit + ); + + wp_set_current_user( 1 ); + + $options = get_option( 'aioseop_options' ); + $options['aiosp_cpostactive'] = array( 'post' ); + update_option( 'aioseop_options', $options ); + + $custom_options = array(); + $custom_options['aiosp_opengraph_types'] = array( 'post' ); + $custom_options['aiosp_opengraph_generate_descriptions'] = 'on'; + $this->_setup_options( 'opengraph', $custom_options ); + + $id = $this->factory->post->create( array( 'post_title' => $title, 'post_content' => $content ) ); + + update_post_meta( $id, '_aioseop_title', $title ); + + $meta = $this->parse_html( get_permalink( $id ), array( 'meta' ) ); + + // should have atleast one meta tag. + $this->assertGreaterThan( 1, count( $meta ) ); + + foreach ( $meta as $m ) { + $tag = isset( $m['property'] ) ? $m['property'] : $m['name']; + if ( empty( $tag ) ) { + continue; + } + if ( array_key_exists( $tag, $tag_limits ) ) { + if ( is_array( $tag_limits[ $tag ] ) ) { + $this->assertGreaterThan( $tag_limits[ $tag ][0], strlen( $m['content'] ) ); + } else { + $this->assertLessThanOrEqual( $tag_limits[ $tag ], strlen( $m['content'] ) ); + } + } + } + } + + /** + * Checks whether the meta tag filter to disable truncation is running correctly. + * + * Function: Adds a post with a long content and title and checks whether the meta tags are being truncated correctly except for the meta tag that's not being truncated. + * Expected: The meta tags are being truncated according to the limits imposed, except for the meta tag that's not being truncated. + * Actual: Currently works as expected. + * Reproduce: Insert a post and check the length of the meta tags content. + * + * @dataProvider metaTagContentProvider + * + * @since 3.0 + */ + public function test_meta_tag_truncation_filter( $title, $content, $og_desc_limit ) { + $tag_limits = array( + 'og:description' => $og_desc_limit, // limit to 200 but respect full words + 'twitter:description' => 200, // hard limit to 200 + 'twitter:title' => array( 70 ), // no limit + ); + + $id = $this->factory->post->create( array( 'post_title' => $title, 'post_content' => $content ) ); + + wp_set_current_user( 1 ); + + $options = get_option( 'aioseop_options' ); + $options['aiosp_cpostactive'] = array( 'post' ); + update_option( 'aioseop_options', $options ); + + $custom_options = array(); + $custom_options['aiosp_opengraph_types'] = array( 'post' ); + $custom_options['aiosp_opengraph_generate_descriptions'] = 'on'; + $this->_setup_options( 'opengraph', $custom_options ); + + add_filter( 'aiosp_opengraph_disable_meta_tag_truncation', array( $this, 'filter_disable_meta_tag_truncation' ), 10, 4 ); + + $meta = $this->parse_html( get_permalink( $id ), array( 'meta' ) ); + + // should have atleast one meta tag. + $this->assertGreaterThan( 1, count( $meta ) ); + + foreach ( $meta as $m ) { + $tag = isset( $m['property'] ) ? $m['property'] : $m['name']; + if ( empty( $tag ) ) { + continue; + } + if ( array_key_exists( $tag, $tag_limits ) ) { + if ( is_array( $tag_limits[ $tag ] ) ) { + $this->assertGreaterThan( $tag_limits[ $tag ][0], strlen( $m['content'] ) ); + } else { + $this->assertLessThanOrEqual( $tag_limits[ $tag ], strlen( $m['content'] ) ); + } + } + } + } + + /** + * Implements the filter to disable truncation of a particular meta tag. + */ + function filter_disable_meta_tag_truncation( $disable, $network, $meta_tag, $network_meta_tag ) { + switch ( $network_meta_tag ) { + case 'twitter:title': + $disable = true; + break; + } + return $disable; + } + /** * Checks the home page's meta tags. * From 95edc607b94012b1a6699af460d8b79cdcb1a88b Mon Sep 17 00:00:00 2001 From: Ashish Ravi Date: Sat, 13 Apr 2019 16:21:40 +0530 Subject: [PATCH 032/121] PHPCS checks for strict comparsion --- phpcs.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/phpcs.xml b/phpcs.xml index 1eacd9efe..6ad8162f6 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -48,6 +48,13 @@ + + + + + + + From 2cedcd764b29d213f4dbc67a90b37b4c56189fc3 Mon Sep 17 00:00:00 2001 From: EkoJR Date: Sat, 13 Apr 2019 14:58:22 -0700 Subject: [PATCH 033/121] Sync with Pro & Add Filter for extended help text (#2325) * Add Filter for extended help text * Remove old help text function for pro The plugin uses a filter instead for extending the help text. --- admin/class-aioseop-helper.php | 47 ++++++++++++---------------------- 1 file changed, 16 insertions(+), 31 deletions(-) diff --git a/admin/class-aioseop-helper.php b/admin/class-aioseop-helper.php index d349dfbf5..7d8503da9 100644 --- a/admin/class-aioseop-helper.php +++ b/admin/class-aioseop-helper.php @@ -46,7 +46,7 @@ public function __construct( $module = '' ) { * no class name in $module, then this Help Text will add all module help texts. * * @ignore - * @since 2.4.2 + * @since 3.0 * @access private * * @param string $module All_in_One_SEO_Pack module. @@ -79,31 +79,17 @@ private function _set_help_text( $module ) { case 'All_in_One_SEO_Pack_Bad_Robots': $this->help_text = $this->help_text_bad_robots(); break; - default: - $this->help_text = array_merge( - $this->help_text, - $this->help_text_general(), - $this->help_text_performance(), - $this->help_text_sitemap(), - $this->help_text_opengraph(), - $this->help_text_robots_generator(), - $this->help_text_file_editor(), - $this->help_text_importer_exporter(), - $this->help_text_bad_robots(), - $this->help_text_post_meta() - ); - break; - } - - if ( AIOSEOPPRO ) { - $help_text = aioseop_add_pro_help( $this->help_text ); - - // TODO - Get Prefix from PRO Version. - foreach ( $help_text as $key => $text ) { - $this->help_text[ $key ] = $text; - } } + /** + * Set Help Text + * + * @since 3.0 + * + * @param array $this->help_text Contains an array of help text for each setting. + * @param string $module Shows which class module is using the function. + */ + $this->help_text = apply_filters( 'aioseop_helper_set_help_text', $this->help_text, $module ); } /** @@ -492,8 +478,6 @@ private function help_text_general() { 'aiosp_dynamic_postspage_keywords' => __( 'Check this if you want your keywords on your Posts page (set in WordPress under Settings, Reading, Front Page Displays) and your archive pages to be dynamically generated from the keywords of the posts showing on that page. If unchecked, it will use the keywords set in the edit page screen for the posts page.', 'all-in-one-seo-pack' ), // Unknown Location. - 'aiosp_license_key' => __( 'This will be the license key received when the product was purchased. This is used for automatic upgrades.', 'all-in-one-seo-pack' ), - 'aiosp_taxactive' => __( 'Use these checkboxes to select which Taxonomies you want to use All in One SEO Pack with.', 'all-in-one-seo-pack' ), 'aiosp_google_connect' => __( 'Press the connect button to connect with Google Analytics; or if already connected, press the disconnect button to disable and remove any stored analytics credentials.', 'all-in-one-seo-pack' ), ); @@ -637,9 +621,7 @@ private function help_text_general() { 'aiosp_dynamic_postspage_keywords' => 'https://semperplugins.com/documentation/keyword-settings/#dynamically-generate-keywords-for-posts-page', // Unknown/Pro? - // 'aiosp_license_key' => '', - // 'aiosp_taxactive' => '', - // 'aiosp_google_connect' => '', + // 'aiosp_google_connect' => '', ); foreach ( $help_doc_link as $k1_slug => $v1_url ) { @@ -905,11 +887,14 @@ private function help_text_opengraph() { 'aioseop_opengraph_settings_customimg_twitter' => __( 'This option lets you upload an image to use as the Twitter image for this Page or Post.', 'all-in-one-seo-pack' ), ); - $args = array( + $args_1 = array( 'public' => true, ); + $args_2 = array( + 'public' => false, + ); - $post_types = get_post_types( $args, 'names' ); + $post_types = array_merge( get_post_types( $args_1, 'names' ), get_post_types( $args_2, 'names' ) ); foreach ( $post_types as $pt ) { $rtn_help_text[ 'aiosp_opengraph_' . $pt . '_fb_object_type' ] = __( 'Choose a default value that best describes the content of your post type.', 'all-in-one-seo-pack' ); $rtn_help_text[ 'aiosp_opengraph_' . $pt . '_fb_object_type' ] .= '

    ' . __( 'Click here for documentation on this setting.', 'all-in-one-seo-pack' ) . ''; From 2465fa95256a24c15eac68fb7197c5bc21195d36 Mon Sep 17 00:00:00 2001 From: contactashish13 Date: Wed, 24 Apr 2019 18:36:35 +0530 Subject: [PATCH 034/121] Video XML Sitemap - Remove taxonomy pages from video sitemap (#2334) * added info for testing * Video XML Sitemap - Remove taxonomy pages from video sitemap https://github.com/semperfiwebdesign/aioseop-pro/issues/246 * PR comments * code review comments * Dev-Fix typo & add initial since tag --- modules/aioseop_sitemap.php | 41 +++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/modules/aioseop_sitemap.php b/modules/aioseop_sitemap.php index 1ca87778a..c233b8d1f 100644 --- a/modules/aioseop_sitemap.php +++ b/modules/aioseop_sitemap.php @@ -1546,7 +1546,7 @@ public function get_sitemap_data( $sitemap_type, $page = 0 ) { $sitemap_data = $this->get_all_post_priority_data( $sitemap_type, 'publish', $page ); } elseif ( in_array( $sitemap_type, $taxonomies ) ) { // TODO Add `true` in 3rd argument with in_array(); which changes it to a strict comparison. - $sitemap_data = $this->get_term_priority_data( get_terms( $sitemap_type, $this->get_tax_args( $page ) ) ); + $sitemap_data = $this->get_term_priority_data( get_terms( $this->get_tax_args( $sitemap_type, $page ) ) ); } else { // TODO Add `true` in 3rd argument with in_array(); which changes it to a strict comparison. if ( is_array( $this->extra_sitemaps ) && in_array( $sitemap_type, $this->extra_sitemaps ) ) { @@ -1875,7 +1875,7 @@ public function get_sitemap_index_filenames() { $options[ "{$this->prefix}taxonomies" ] = array(); } $options[ "{$this->prefix}posttypes" ] = array_diff( $options[ "{$this->prefix}posttypes" ], array( 'all' ) ); - $options[ "{$this->prefix}taxonomies" ] = array_diff( $options[ "{$this->prefix}taxonomies" ], array( 'all' ) ); + $options[ "{$this->prefix}taxonomies" ] = $this->show_or_hide_taxonomy( array_diff( $options[ "{$this->prefix}taxonomies" ], array( 'all' ) ) ); $files[] = array( 'loc' => aioseop_home_url( '/' . $prefix . '_addl' . $suffix ) ); @@ -2212,7 +2212,7 @@ public function get_simple_sitemap() { if ( is_array( $home ) ) { array_unshift( $prio, $home ); } - $terms = get_terms( $options[ "{$this->prefix}taxonomies" ], $this->get_tax_args() ); + $terms = get_terms( $this->get_tax_args( $options[ "{$this->prefix}taxonomies" ] ) ); $prio2 = $this->get_term_priority_data( $terms ); $prio3 = $this->get_addl_pages_only(); $prio = array_merge( $child, $prio, $prio2, $prio3 ); @@ -2555,7 +2555,7 @@ public function build_sitemap( $urls, $sitemap_type, $comment = '' ) { */ public function get_term_priority_data( $terms ) { $prio = array(); - if ( is_array( $terms ) ) { + if ( is_array( $terms ) && ! empty( $terms ) ) { $def_prio = $this->get_default_priority( 'taxonomies' ); $def_freq = $this->get_default_frequency( 'taxonomies' ); foreach ( $terms as $term ) { @@ -3818,11 +3818,15 @@ public function parse_content_for_images( $content, &$images ) { /** * Return excluded categories for taxonomy queries. * - * @param int $page + * @since ? + * @since 3.0.0 Added $taxonomy parameter. + * + * @param array $taxonomy The array of taxonomy slugs. + * @param int $page The page number. * * @return array */ - public function get_tax_args( $page = 0 ) { + public function get_tax_args( $taxonomy, $page = 0 ) { $args = array(); if ( $this->option_isset( 'excl_categories' ) ) { $args['exclude'] = $this->options[ $this->prefix . 'excl_categories' ]; @@ -3831,6 +3835,7 @@ public function get_tax_args( $page = 0 ) { $args['number'] = $this->max_posts; $args['offset'] = $page * $this->max_posts; } + $args['taxonomy'] = $this->show_or_hide_taxonomy( $taxonomy ); $args = apply_filters( $this->prefix . 'tax_args', $args, $page, $this->options ); @@ -4033,6 +4038,26 @@ public function get_permalink( $post ) { return aioseop_get_permalink( $post ); } + /** + * Show or hide the taxonomy/taxonomies. + * + * @since 3.0.0 + * + * @param array $taxonomy The array of taxonomy slugs. + * + * @return array The array of taxonomy slugs that need to be shown. + */ + private function show_or_hide_taxonomy( $taxonomy ) { + /** + * Determines whether to show or hide the taxonomy/taxonomies. + * + * @since 3.0.0 + * + * @param array $taxonomy The array of taxonomy slugs. + */ + return apply_filters( "{$this->prefix}show_taxonomy", $taxonomy ); + } + /** * Return term counts using wp_count_terms(). * @@ -4048,13 +4073,13 @@ public function get_all_term_counts( $args ) { if ( is_array( $args['taxonomy'] ) ) { $args['taxonomy'] = array_shift( $args['taxonomy'] ); } - $term_counts = wp_count_terms( $args['taxonomy'], array( 'hide_empty' => true ) ); + $term_counts = wp_count_terms( $this->show_or_hide_taxonomy( $args['taxonomy'] ), array( 'hide_empty' => true ) ); } else { foreach ( $args['taxonomy'] as $taxonomy ) { if ( 'all' === $taxonomy ) { continue; } - $term_counts[ $taxonomy ] = wp_count_terms( $taxonomy, array( 'hide_empty' => true ) ); + $term_counts[ $taxonomy ] = wp_count_terms( $this->show_or_hide_taxonomy( $taxonomy ), array( 'hide_empty' => true ) ); } } } From 313d2115ee24b2c4ee2532107e263e8593118c8c Mon Sep 17 00:00:00 2001 From: Arnaud Broes Date: Thu, 25 Apr 2019 15:20:55 -0400 Subject: [PATCH 035/121] Open Upgrade links as new tabs #773 (#2347) * + Open Upgrade links in new tab #773 * + Grunt fixes #773 * = PR comments #773 * = Fix spacing #773 --- admin/display/general-metaboxes.php | 6 +++--- admin/display/menu.php | 19 +++++++++++++++++++ all_in_one_seo_pack.php | 2 +- js/aioseop-menu.js | 20 ++++++++++++++++++++ js/aioseop-menu.min.js | 1 + js/plugins-menu.js | 20 ++++++++++++++++++++ js/plugins-menu.min.js | 1 + 7 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 js/aioseop-menu.js create mode 100644 js/aioseop-menu.min.js create mode 100644 js/plugins-menu.js create mode 100644 js/plugins-menu.min.js diff --git a/admin/display/general-metaboxes.php b/admin/display/general-metaboxes.php index 77d6c272a..a32c21d0f 100644 --- a/admin/display/general-metaboxes.php +++ b/admin/display/general-metaboxes.php @@ -51,11 +51,11 @@ static function display_extra_metaboxes( $add, $meta ) { + case 'aioseop-donate': + ?>
    - +

    diff --git a/admin/display/menu.php b/admin/display/menu.php index 9857d8695..4a3e4a4be 100644 --- a/admin/display/menu.php +++ b/admin/display/menu.php @@ -23,6 +23,8 @@ function __construct() { } else { return; } + + add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) ); } function remove_menus() { @@ -44,6 +46,23 @@ function add_pro_submenu() { $url, ); } + + /* + * Opens Upgrade to Pro links in WP Admin as new tab. + * + * Enqueued here because All_in_One_SEO_Pack_Module::admin_enqueue_scripts does not work. + * + * @param string $hook + * + * @since 3.0 + */ + function admin_enqueue_scripts( $hook ) { + wp_enqueue_script( 'aioseop_menu_js', AIOSEOP_PLUGIN_URL . 'js/aioseop-menu.js', array( 'jquery' ), AIOSEOP_VERSION, true ); + + if ( 'plugins.php' === $hook ) { + wp_enqueue_script( 'aioseop_plugins_menu_js', AIOSEOP_PLUGIN_URL . 'js/plugins-menu.js', array( 'jquery' ), AIOSEOP_VERSION, true ); + } + } } new AIOSEOPAdminMenus(); diff --git a/all_in_one_seo_pack.php b/all_in_one_seo_pack.php index 91c362c1b..806a01043 100644 --- a/all_in_one_seo_pack.php +++ b/all_in_one_seo_pack.php @@ -305,7 +305,7 @@ function aiosp_plugin_row_meta( $actions, $plugin_file ) { ); - return aiosp_action_links( $actions, $plugin_file, $action_links, 'after' ); + return aiosp_action_links( $actions, $plugin_file, $action_links, 'after' ); } } diff --git a/js/aioseop-menu.js b/js/aioseop-menu.js new file mode 100644 index 000000000..ccc411861 --- /dev/null +++ b/js/aioseop-menu.js @@ -0,0 +1,20 @@ +/** + * AIOSEOP menu. + * + * Contains all functions that affect the AIOSEOP menu in the sidebar. + * + * @since 3.0 + * @package all-in-one-seo-pack + */ +(function($) { + + /** + * Opens Upgrade to Pro link in AIOSEOP menu as new tab. + */ + function upgrade_link_aioseop_menu_new_tab() { + $('#toplevel_page_all-in-one-seo-pack-aioseop_class ul li').last().find('a').attr('target','_blank'); + } + + upgrade_link_aioseop_menu_new_tab(); + +}(jQuery)); diff --git a/js/aioseop-menu.min.js b/js/aioseop-menu.min.js new file mode 100644 index 000000000..f671ffcb9 --- /dev/null +++ b/js/aioseop-menu.min.js @@ -0,0 +1 @@ +jQuery("#toplevel_page_all-in-one-seo-pack-aioseop_class ul li").last().find("a").attr("target","_blank"); \ No newline at end of file diff --git a/js/plugins-menu.js b/js/plugins-menu.js new file mode 100644 index 000000000..752d7bfea --- /dev/null +++ b/js/plugins-menu.js @@ -0,0 +1,20 @@ +/** + * Plugins menu. + * + * Contains all functions that affect the Plugins menu. + * + * @since 3.0 + * @package all-in-one-seo-pack + */ +(function($) { + + /** + * Opens Upgrade to Pro link in Plugins menu as new tab. + */ + function upgrade_link_plugins_menu_new_tab() { + $('.proupgrade').find('a').attr('target','_blank'); + } + + upgrade_link_plugins_menu_new_tab(); + +}(jQuery)); diff --git a/js/plugins-menu.min.js b/js/plugins-menu.min.js new file mode 100644 index 000000000..a8cab5f0e --- /dev/null +++ b/js/plugins-menu.min.js @@ -0,0 +1 @@ +jQuery(".proupgrade").find("a").attr("target","_blank"); \ No newline at end of file From f2b6eca55f491b14ddcc8abe987a0e50c362c026 Mon Sep 17 00:00:00 2001 From: Arnaud Broes Date: Thu, 25 Apr 2019 17:44:27 -0400 Subject: [PATCH 036/121] = Change absolute URI to relative URI #2282 (#2350) --- admin/display/menu.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admin/display/menu.php b/admin/display/menu.php index 4a3e4a4be..180e051c5 100644 --- a/admin/display/menu.php +++ b/admin/display/menu.php @@ -40,7 +40,7 @@ function add_pro_submenu() { global $submenu; $url = 'https://semperplugins.com/all-in-one-seo-pack-pro-version/?loc=aio_menu'; $upgrade_text = __( 'Upgrade to Pro', 'all-in-one-seo-pack' ); - $submenu['all-in-one-seo-pack/aioseop_class.php'][] = array( + $submenu[ AIOSEOP_PLUGIN_DIRNAME . '/aioseop_class.php' ][] = array( "$upgrade_text", 'manage_options', $url, From 6e5f09e83ef394ae71a7c5cd3d63f92784daabdf Mon Sep 17 00:00:00 2001 From: Arnaud Broes Date: Fri, 26 Apr 2019 12:25:18 -0400 Subject: [PATCH 037/121] Add Pro to sitemap source code (#2358) * = Add Pro to sitemap source code as appropriate #1972 * changing Semper Plugins back to Semper Fi Web Design --- modules/aioseop_sitemap.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/aioseop_sitemap.php b/modules/aioseop_sitemap.php index c233b8d1f..f4b192e2d 100644 --- a/modules/aioseop_sitemap.php +++ b/modules/aioseop_sitemap.php @@ -166,7 +166,7 @@ public function __construct() { } parent::__construct(); // TODO This could be move up to the class field default/initial values. - $this->comment_string = 'Sitemap %s generated by All in One SEO Pack %s by Michael Torbert of Semper Fi Web Design on %s'; + $this->comment_string = 'Sitemap %s generated by ' . AIOSEOP_PLUGIN_NAME . ' %s by Michael Torbert of Semper Fi Web Design on %s'; $this->default_options = array( 'rss_sitemap' => array( 'name' => __( 'Create RSS Sitemap', 'all-in-one-seo-pack' ) ), From e8274606819d21edd3451358d2bb35e3bbde3da5 Mon Sep 17 00:00:00 2001 From: Arnaud Broes Date: Fri, 26 Apr 2019 15:38:30 -0400 Subject: [PATCH 038/121] = Remove redundant global $aioseop_plugin_name #2353 (#2354) --- all_in_one_seo_pack.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/all_in_one_seo_pack.php b/all_in_one_seo_pack.php index 806a01043..7a155928a 100644 --- a/all_in_one_seo_pack.php +++ b/all_in_one_seo_pack.php @@ -38,11 +38,12 @@ if ( ! defined( 'AIOSEOPPRO' ) ) { define( 'AIOSEOPPRO', false ); } +if ( ! defined( 'AIOSEOP_PLUGIN_NAME' ) ) { + define( 'AIOSEOP_PLUGIN_NAME', 'All in One SEO Pack' ); +} if ( ! defined( 'AIOSEOP_VERSION' ) ) { define( 'AIOSEOP_VERSION', '3.0-dev' ); } -global $aioseop_plugin_name; -$aioseop_plugin_name = 'All in One SEO Pack'; /* * DO NOT EDIT BELOW THIS LINE. @@ -74,10 +75,6 @@ function aiosp_add_cap() { } add_action( 'plugins_loaded', 'aiosp_add_cap' ); -if ( ! defined( 'AIOSEOP_PLUGIN_NAME' ) ) { - define( 'AIOSEOP_PLUGIN_NAME', $aioseop_plugin_name ); -} - if ( ! defined( 'AIOSEOP_PLUGIN_DIR' ) ) { define( 'AIOSEOP_PLUGIN_DIR', plugin_dir_path( __FILE__ ) ); } elseif ( AIOSEOP_PLUGIN_DIR !== plugin_dir_path( __FILE__ ) ) { From 88b4e59d9375a06f4b62efa760be52e556f03bb8 Mon Sep 17 00:00:00 2001 From: Arnaud Broes Date: Fri, 26 Apr 2019 15:39:25 -0400 Subject: [PATCH 039/121] Use double quotes for pagination links (#2352) * = Use double quotes for pagination links #2088 * = Escape double quotes instead of using concatenation #2088 --- aioseop_class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aioseop_class.php b/aioseop_class.php index 505beffe3..322b6c0a3 100644 --- a/aioseop_class.php +++ b/aioseop_class.php @@ -3737,10 +3737,10 @@ function wp_head() { $prev = apply_filters( 'aioseop_prev_link', $prev_next['prev'] ); $next = apply_filters( 'aioseop_next_link', $prev_next['next'] ); if ( ! empty( $prev ) ) { - $meta_string .= "\n"; + $meta_string .= '\n"; } if ( ! empty( $next ) ) { - $meta_string .= "\n"; + $meta_string .= '\n"; } if ( $meta_string != null ) { echo "$meta_string\n"; From fc3883fc76a89cb7bcea72393aa282ac98d8fa34 Mon Sep 17 00:00:00 2001 From: Arnaud Broes Date: Mon, 29 Apr 2019 10:19:25 -0400 Subject: [PATCH 040/121] + Change social meta home title field to text input #1336 (#2366) --- modules/aioseop_opengraph.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/aioseop_opengraph.php b/modules/aioseop_opengraph.php index 470934f7b..72c132f8a 100644 --- a/modules/aioseop_opengraph.php +++ b/modules/aioseop_opengraph.php @@ -334,7 +334,7 @@ public function init() { 'hometitle' => array( 'name' => __( 'Home Title', 'all-in-one-seo-pack' ), 'default' => '', - 'type' => 'textarea', + 'type' => 'text', 'condshow' => array( 'aiosp_opengraph_setmeta' => array( 'lhs' => 'aiosp_opengraph_setmeta', From 0822de4f952e593e93bd7b245a28437d1fda1845 Mon Sep 17 00:00:00 2001 From: Arnaud Broes Date: Mon, 29 Apr 2019 10:23:06 -0400 Subject: [PATCH 041/121] + Use AIOSEOP_PLUGIN_NAME in sitemap instead of string #2357 (#2365) --- inc/sitemap-xsl.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/inc/sitemap-xsl.php b/inc/sitemap-xsl.php index a8e7538a9..123ee9d54 100644 --- a/inc/sitemap-xsl.php +++ b/inc/sitemap-xsl.php @@ -89,12 +89,12 @@

    XML Sitemap

    -

    Generated by All in One SEO, this is an XML Sitemap, meant to be consumed by search engines like Google or Bing.
    +

    Generated by , this is an XML Sitemap, meant to be consumed by search engines like Google or Bing.
    You can find more information about XML sitemaps at sitemaps.org.

    - This sitemap contains URLs - This sitemap index contains sitemaps + This sitemap contains URLs. + This sitemap index contains sitemaps.

    From 1d22eeef0598eb9ca88b1250a68ff56a2d7ff073 Mon Sep 17 00:00:00 2001 From: Arnaud Broes Date: Mon, 29 Apr 2019 10:30:37 -0400 Subject: [PATCH 042/121] Add Yandex and Baidu Webmaster Tools verification (#2362) * + Add option for Yandex Webmaster Tools verification #875 * + Add option for Baidu Webmaster Tools verification #875 --- admin/class-aioseop-helper.php | 4 ++++ aioseop_class.php | 14 +++++++++++++- inc/compatability/compat-init.php | 8 ++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/admin/class-aioseop-helper.php b/admin/class-aioseop-helper.php index 7d8503da9..5be2812f6 100644 --- a/admin/class-aioseop-helper.php +++ b/admin/class-aioseop-helper.php @@ -421,6 +421,8 @@ private function help_text_general() { 'aiosp_google_verify' => __( 'Enter your verification code here to verify your site with Google Search Console.', 'all-in-one-seo-pack' ), 'aiosp_bing_verify' => __( 'Enter your verification code here to verify your site with Bing Webmaster Tools.', 'all-in-one-seo-pack' ), 'aiosp_pinterest_verify' => __( 'Enter your verification code here to verify your site with Pinterest.', 'all-in-one-seo-pack' ), + 'aiosp_yandex_verify' => __( 'Enter your verification code here to verify your site with Yandex Webmaster Tools.', 'all-in-one-seo-pack' ), + 'aiosp_baidu_verify' => __( 'Enter your verification code here to verify your site with Baidu Webmaster Tools.', 'all-in-one-seo-pack' ), // Google Settings. 'aiosp_google_publisher' => __( 'Enter your Google+ Profile URL here to add the rel=“author” tag to your site for Google authorship. It is recommended that the URL you enter here should be your personal Google+ profile. Use the Advanced Authorship Options below if you want greater control over the use of authorship.', 'all-in-one-seo-pack' ), @@ -563,6 +565,8 @@ private function help_text_general() { 'aiosp_google_verify' => 'https://semperplugins.com/documentation/google-search-console-verification/', 'aiosp_bing_verify' => 'https://semperplugins.com/documentation/bing-webmaster-verification/', 'aiosp_pinterest_verify' => 'https://semperplugins.com/documentation/pinterest-site-verification/', + 'aiosp_yandex_verify' => 'https://semperplugins.com/documentation/yandex-webmaster-verification/', + 'aiosp_baidu_verify' => 'https://semperplugins.com/documentation/baidu-webmaster-verification/', // Google Settings. 'aiosp_google_publisher' => 'https://semperplugins.com/documentation/google-settings/#google-plus-default-profile', diff --git a/aioseop_class.php b/aioseop_class.php index 322b6c0a3..22c9a8448 100644 --- a/aioseop_class.php +++ b/aioseop_class.php @@ -283,6 +283,16 @@ function __construct() { 'default' => '', 'type' => 'text', ), + 'yandex_verify' => array( + 'name' => __( 'Yandex Webmaster Tools:', 'all-in-one-seo-pack' ), + 'default' => '', + 'type' => 'text', + ), + 'baidu_verify' => array( + 'name' => __( 'Baidu Webmaster Tools:', 'all-in-one-seo-pack' ), + 'default' => '', + 'type' => 'text', + ), 'google_publisher' => array( 'name' => __( 'Google Plus Default Profile:', 'all-in-one-seo-pack' ), 'default' => '', @@ -733,7 +743,7 @@ function __construct() { 'webmaster' => array( 'name' => __( 'Webmaster Verification', 'all-in-one-seo-pack' ), 'help_link' => 'https://semperplugins.com/sections/webmaster-verification/', - 'options' => array( 'google_verify', 'bing_verify', 'pinterest_verify' ), + 'options' => array( 'google_verify', 'bing_verify', 'pinterest_verify', 'yandex_verify', 'baidu_verify' ), ), 'google' => array( 'name' => __( 'Google Settings', 'all-in-one-seo-pack' ), @@ -3675,6 +3685,8 @@ function wp_head() { '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" ] ) ) { diff --git a/inc/compatability/compat-init.php b/inc/compatability/compat-init.php index 2b91de506..d9e675550 100644 --- a/inc/compatability/compat-init.php +++ b/inc/compatability/compat-init.php @@ -108,6 +108,14 @@ function filter_jetpack_site_verification_output( $ver_tag ) { return ''; } + if ( isset( $aioseop_options['aiosp_yandex_verify'] ) && ! empty( $aioseop_options['aiosp_yandex_verify'] ) && strpos( $ver_tag, 'yandex-verification' ) ) { + return ''; + } + + if ( isset( $aioseop_options['aiosp_baidu_verify'] ) && ! empty( $aioseop_options['aiosp_baidu_verify'] ) && strpos( $ver_tag, 'baidu-site-verification' ) ) { + return ''; + } + return $ver_tag; } From 5c17b112322342226f8d33e672e6051253ffe0ad Mon Sep 17 00:00:00 2001 From: wpsmort Date: Mon, 29 Apr 2019 11:51:00 -0400 Subject: [PATCH 043/121] #1790 Change height for text fields to min-height (#2367) --- css/modules/aioseop_module.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/css/modules/aioseop_module.css b/css/modules/aioseop_module.css index 8e196ac6b..5a5ae9d7e 100644 --- a/css/modules/aioseop_module.css +++ b/css/modules/aioseop_module.css @@ -161,7 +161,7 @@ div.aioseop_tip_icon:before { .aioseop input[type="text"], .aioseop input[type="url"] { color: #515151; - height: 35px; + min-height: 35px; padding: 10px 0 10px 10px; font-size: 14px; width: 95%; @@ -1513,4 +1513,4 @@ textarea.robots-text { div#aiosp_sitemap_status_metabox .toggle-indicator { display:none; -} \ No newline at end of file +} From c3aa5c933f10d7c972725ae51db05aa5f432a410 Mon Sep 17 00:00:00 2001 From: Arnaud Broes Date: Wed, 1 May 2019 17:10:14 -0400 Subject: [PATCH 044/121] Add separate mailing list for Pro users (#2369) * + Add separate mailing list for Pro users * = Change if control structure to braces * = Change if control structure back to alternative syntax --- admin/display/general-metaboxes.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/admin/display/general-metaboxes.php b/admin/display/general-metaboxes.php index a32c21d0f..3ddc8b653 100644 --- a/admin/display/general-metaboxes.php +++ b/admin/display/general-metaboxes.php @@ -111,8 +111,12 @@ static function display_extra_metaboxes( $add, $meta ) { ?>
    + action="https://semperplugins.us1.list-manage.com/subscribe/post?u=794674d3d54fdd912f961ef14&id=b786958a9a" + + action="https://semperplugins.us1.list-manage.com/subscribe/post?u=794674d3d54fdd912f961ef14&id=af0a96d3d9" + + method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank">

    From 38a23046b204b1e6c13f7e0c77b6043cd0f6ef6f Mon Sep 17 00:00:00 2001 From: Michael Torbert Date: Fri, 3 May 2019 12:09:32 -0400 Subject: [PATCH 045/121] support for WordPress 5.2 --- readme.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.txt b/readme.txt index 6cdfb1a0c..846825a64 100644 --- a/readme.txt +++ b/readme.txt @@ -2,7 +2,7 @@ Contributors: hallsofmontezuma, semperplugins, wpsmort, arnaudbroes Tags: SEO, Google Search Console, XML Sitemap, meta description, meta title, noindex Requires at least: 4.7 -Tested up to: 5.1 +Tested up to: 5.2 Stable tag: 3.0-dev License: GPLv2 or later Requires PHP: 5.2.4 From 04899b3f30e65956b35aac93b16a5c58893ff51d Mon Sep 17 00:00:00 2001 From: EkoJR Date: Sat, 4 May 2019 12:07:29 -0700 Subject: [PATCH 046/121] Change Sitemap to exclude NOINDEX post types & posts (#2317) * Change Sitemap to exclude NOINDEX post types & posts * Dev-Remove todo comment * Dev-Change to exclude noindex post types with Sitemap Indexes disabled * Dev-Add PHP Documentation * Dev-Fix issue with post types with Sitemap Indexes enabled * Dev-Change to simplify code * Dev-Add comment * Add Index posts on NoIndex post type * Dev-Change boolean check to int check * Dev-Add comments * Dev-Add comments * Change sitemap exclude posts per page to use max_posts value * Fix 404 error on Post Type's Sitemap when no posts queried --- modules/aioseop_sitemap.php | 186 ++++++++++++++++++++++++++++++++---- 1 file changed, 168 insertions(+), 18 deletions(-) diff --git a/modules/aioseop_sitemap.php b/modules/aioseop_sitemap.php index f4b192e2d..d83569bbc 100644 --- a/modules/aioseop_sitemap.php +++ b/modules/aioseop_sitemap.php @@ -1856,10 +1856,12 @@ public function get_default_frequency( $item, $nodefaults = false, $type = '' ) * * @since 2.3.6 * @since 2.3.12.3 Refactored to use aioseop_home_url() for compatibility purposes. + * @since 3.0 Changed to exclude noindex post types. #1382 * * @return array */ public function get_sitemap_index_filenames() { + global $aioseop_options; $files = array(); $options = $this->options; $prefix = $this->get_filename(); @@ -1879,17 +1881,56 @@ public function get_sitemap_index_filenames() { $files[] = array( 'loc' => aioseop_home_url( '/' . $prefix . '_addl' . $suffix ) ); - if ( ! empty( $options[ "{$this->prefix}posttypes" ] ) ) { + // Get post types selected, and NoIndex post types & Index posts. + $post_types = $options[ "{$this->prefix}posttypes" ]; + if ( is_array( $aioseop_options['aiosp_cpostnoindex'] ) ) { + foreach ( $post_types as $index => $post_type ) { + if ( in_array( $post_type, $aioseop_options['aiosp_cpostnoindex'], true ) ) { + $args = array( + 'post_type' => $post_type, + 'meta_query' => array( + 'relation' => 'OR', + array( + 'key' => '_aioseop_noindex', + 'value' => 'off', + 'compare' => '=', + ), + ), + 'fields' => 'ids', + 'posts_per_page' => 1, + ); + $q = new WP_Query( $args ); + if ( 0 === $q->post_count ) { + unset( $post_types[ $index ] ); + } + } + } + } + + if ( ! empty( $post_types ) ) { $prio = $this->get_default_priority( 'post' ); $freq = $this->get_default_frequency( 'post' ); + // Get post counts from posts type. Exclude if NoIndex is on. $post_counts = $this->get_all_post_counts( array( - 'post_type' => $options[ "{$this->prefix}posttypes" ], + 'post_type' => $post_types, 'post_status' => 'publish', + 'meta_query' => array( + 'relation' => 'OR', + array( + 'key' => '_aioseop_noindex', + 'value' => 'on', + 'compare' => '!=', + ), + array( + 'key' => '_aioseop_noindex', + 'compare' => 'NOT EXISTS', + ), + ), ) ); - foreach ( $options[ "{$this->prefix}posttypes" ] as $sm ) { + foreach ( $post_types as $sm ) { if ( 0 === intval( $post_counts[ $sm ] ) ) { continue; } @@ -4181,11 +4222,16 @@ public function get_total_post_count( $args ) { /** * Return post data using get_posts(). * - * @param $args + * @since ? + * @since 3.0 Changed to exclude noindex post types & posts. #1382 + * + * @global array $aioseop_options * + * @param array $args Query Arguments. * @return array|mixed */ public function get_all_post_type_data( $args ) { + global $aioseop_options; $defaults = array( 'numberposts' => $this->max_posts, 'offset' => 0, @@ -4195,10 +4241,7 @@ public function get_all_post_type_data( $args ) { 'include' => array(), 'exclude' => array(), 'post_type' => 'any', - 'meta_key' => '', - 'meta_value' => '', - 'meta_compare' => '', - 'meta_query' => '', + 'meta_query' => array(), 'cache_results' => false, 'no_found_rows' => true, ); @@ -4233,24 +4276,107 @@ public function get_all_post_type_data( $args ) { } } } - - $ex_args = $args; - $ex_args['meta_key'] = '_aioseop_sitemap_exclude'; - $ex_args['meta_value'] = 'on'; - $ex_args['meta_compare'] = '='; - $ex_args['fields'] = 'ids'; - $ex_args['posts_per_page'] = - 1; - $q = new WP_Query( $ex_args ); if ( ! is_array( $args['exclude'] ) ) { $args['exclude'] = explode( ',', $args['exclude'] ); } - if ( ! empty( $q->posts ) ) { - $args['exclude'] = array_merge( $args['exclude'], $q->posts ); + + // Exclude (method) query args. + $ex_args = $args; + $ex_args['meta_query'] = array( + 'relation' => 'OR', + + array( + 'key' => '_aioseop_sitemap_exclude', + 'value' => 'on', + 'compare' => '=', + ), + array( + 'key' => '_aioseop_noindex', + 'value' => 'on', + 'compare' => '=', + ), + ); + $ex_args['fields'] = 'ids'; + $ex_args['posts_per_page'] = $this->max_posts; + + // Exclude (method) query. + $q_exclude = new WP_Query( $ex_args ); + if ( ! empty( $q_exclude->posts ) ) { + $args['exclude'] = array_merge( $args['exclude'], $q_exclude->posts ); } $this->excludes = array_merge( $args['exclude'], $exclude_slugs ); // Add excluded slugs and IDs to class var. + // Avoid if possible. + // Include (method) query args for including posts that may have been excluded; + // for example, exclude post type, but include certain posts. + // NOTE: Do NOT use this for basic including. It's best to avoid an additional query. + $args_include = array( + 'post_type' => array(), + 'meta_query' => array( + 'relation' => 'OR', + array( + 'key' => '_aioseop_noindex', + 'value' => 'off', + 'compare' => '=', + ), + + ), + 'posts_per_page' => $this->max_posts, + ); + + // Exclude from main query, and check if a Query Include is needed. + // Check for NoIndex Post Types, BUT also check for Index on NoIdex Post Type. + if ( is_array( $aioseop_options['aiosp_cpostnoindex'] ) ) { + // Check if wp_query_args post_type is an array or string. + if ( is_array( $args['post_type'] ) ) { + foreach ( $args['post_type'] as $index => $post_type ) { + if ( in_array( $post_type, $aioseop_options['aiosp_cpostnoindex'], true ) ) { + $args_include['post_type'][] = $post_type; + unset( $args['post_type'][ $index ] ); + } + } + } else { + if ( in_array( $args['post_type'], $aioseop_options['aiosp_cpostnoindex'], true ) ) { + $args_include['post_type'][] = $args['post_type']; + + $q_include = new WP_Query( $args_include ); + // Return posts on single post type query, since no additional query is needed. + return $q_include->posts; + } + } + } + + // Avoid if possible. + // Include (method) query. + // NOTE: Do NOT use this for basic including. It's best to avoid an additional query. + $posts_include = array(); + if ( ! empty( $args_include['post_type'] ) ) { + $q_include = new WP_Query( $args_include ); + // When posts exists from the include method, add to $posts_include to add to final query. + if ( ! empty( $q_include->posts ) ) { + $posts_include = $q_include->posts; + } + } + // TODO: consider using WP_Query instead of get_posts to improve efficiency. + /** + * {$module_prefix}post_query + * + * Arguments to use on get_posts(). + * + * @since ? + * + * @param array $args { + * Arguments/params for get_posts. + * @see get_posts() + * @link https://developer.wordpress.org/reference/functions/get_posts/ + * } + * + */ $posts = get_posts( apply_filters( $this->prefix . 'post_query', $args ) ); + + // TODO Possibly change to exclude with post__not_in. + // Hardcoded exclude concept. if ( ! empty( $exclude_slugs ) ) { foreach ( $posts as $k => $v ) { // TODO Add `true` in 3rd argument with in_array(); which changes it to a strict comparison. @@ -4259,6 +4385,30 @@ public function get_all_post_type_data( $args ) { } } } + // Hardcoded include concept. + foreach ( $posts_include as $k1_post_id => $v1_post ) { + $posts[ $k1_post_id ] = $v1_post; + } + + /** + * {$module_prefix}post_filter + * + * Posts from finalized query for sitemap data. + * + * @since ? + * + * @param array $posts { + * @type WP_Post ${$post_id} { + * @see WP_Post object for more information. + * @link https://codex.wordpress.org/Class_Reference/WP_Post + * } + * } + * @param array $args { + * Arguments/params for get_posts. + * @see get_posts() + * @link https://developer.wordpress.org/reference/functions/get_posts/ + * } + */ $posts = apply_filters( $this->prefix . 'post_filter', $posts, $args ); return $posts; From 8fa6b878d2e9add3dbc8a105b0a9096dce4d742c Mon Sep 17 00:00:00 2001 From: Arnaud Broes Date: Mon, 6 May 2019 11:53:39 -0400 Subject: [PATCH 047/121] Add %site_title% and %site_description% macros (#2360) * + Add %site_title% and %site_description% macros #1271 * = Use strpos() parent class method and Yoda conditions #1271 * = Remove "%blog_xxxx% is deprecated" #1271 * + Add unit test #1271 * = Undo package.json changes #1271 --- admin/class-aioseop-helper.php | 48 ++-- aioseop_class.php | 232 ++++++++++++------- inc/aioseop_functions.php | 4 +- tests/modules/general/test-meta.php | 2 +- tests/modules/general/test-rewrite-title.php | 105 +++++++++ 5 files changed, 277 insertions(+), 114 deletions(-) create mode 100644 tests/modules/general/test-rewrite-title.php diff --git a/admin/class-aioseop-helper.php b/admin/class-aioseop-helper.php index 5be2812f6..c785bf4d6 100644 --- a/admin/class-aioseop-helper.php +++ b/admin/class-aioseop-helper.php @@ -136,10 +136,10 @@ private function help_text_general() { __( 'The following macros are supported:', 'all-in-one-seo-pack' ) . '

      ' . '
    • ' . - __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ) . + __( '%site_title% - Your site title', 'all-in-one-seo-pack' ) . '
    • ' . '
    • ' . - __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ) . + __( '%site_description% - Your site description', 'all-in-one-seo-pack' ) . '
    • ' . '
    • ' . __( '%page_title% - The original title of the page', 'all-in-one-seo-pack' ) . @@ -168,10 +168,10 @@ private function help_text_general() { __( 'The following macros are supported:', 'all-in-one-seo-pack' ) . '
        ' . '
      • ' . - __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ) . + __( '%site_title% - Your site title', 'all-in-one-seo-pack' ) . '
      • ' . '
      • ' . - __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ) . + __( '%site_description% - Your site description', 'all-in-one-seo-pack' ) . '
      • ' . '
      • ' . __( '%page_title% - The original title of the page', 'all-in-one-seo-pack' ) . @@ -209,10 +209,10 @@ private function help_text_general() { __( 'The following macros are supported:', 'all-in-one-seo-pack' ) . '
          ' . '
        • ' . - __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ) . + __( '%site_title% - Your site title', 'all-in-one-seo-pack' ) . '
        • ' . '
        • ' . - __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ) . + __( '%site_description% - Your site description', 'all-in-one-seo-pack' ) . '
        • ' . '
        • ' . __( '%post_title% - The original title of the post', 'all-in-one-seo-pack' ) . @@ -256,10 +256,10 @@ private function help_text_general() { __( 'The following macros are supported:', 'all-in-one-seo-pack' ) . '
            ' . '
          • ' . - __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ) . + __( '%site_title% - Your site title', 'all-in-one-seo-pack' ) . '
          • ' . '
          • ' . - __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ) . + __( '%site_description% - Your site description', 'all-in-one-seo-pack' ) . '
          • ' . '
          • ' . __( '%category_title% - The original title of the category', 'all-in-one-seo-pack' ) . @@ -273,10 +273,10 @@ private function help_text_general() { __( 'The following macros are supported:', 'all-in-one-seo-pack' ) . '
              ' . '
            • ' . - __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ) . + __( '%site_title% - Your site title', 'all-in-one-seo-pack' ) . '
            • ' . '
            • ' . - __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ) . + __( '%site_description% - Your site description', 'all-in-one-seo-pack' ) . '
            • ' . '
            • ' . __( '%archive_title - The original archive title given by wordpress', 'all-in-one-seo-pack' ) . @@ -287,10 +287,10 @@ private function help_text_general() { __( 'The following macros are supported:', 'all-in-one-seo-pack' ) . '
                ' . '
              • ' . - __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ) . + __( '%site_title% - Your site title', 'all-in-one-seo-pack' ) . '
              • ' . '
              • ' . - __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ) . + __( '%site_description% - Your site description', 'all-in-one-seo-pack' ) . '
              • ' . '
              • ' . __( '%date% - The original archive title given by wordpress, e.g. "2007" or "2007 August"', 'all-in-one-seo-pack' ) . @@ -310,10 +310,10 @@ private function help_text_general() { __( 'The following macros are supported:', 'all-in-one-seo-pack' ) . '
                  ' . '
                • ' . - __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ) . + __( '%site_title% - Your site title', 'all-in-one-seo-pack' ) . '
                • ' . '
                • ' . - __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ) . + __( '%site_description% - Your site description', 'all-in-one-seo-pack' ) . '
                • ' . '
                • ' . __( '%author% - The original archive title given by wordpress, e.g. "Steve" or "John Smith"', 'all-in-one-seo-pack' ) . @@ -324,10 +324,10 @@ private function help_text_general() { __( 'The following macros are supported:', 'all-in-one-seo-pack' ) . '
                    ' . '
                  • ' . - __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ) . + __( '%site_title% - Your site title', 'all-in-one-seo-pack' ) . '
                  • ' . '
                  • ' . - __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ) . + __( '%site_description% - Your site description', 'all-in-one-seo-pack' ) . '
                  • ' . '
                  • ' . __( '%tag% - The name of the tag', 'all-in-one-seo-pack' ) . @@ -338,10 +338,10 @@ private function help_text_general() { __( 'The following macros are supported:', 'all-in-one-seo-pack' ) . '
                      ' . '
                    • ' . - __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ) . + __( '%site_title% - Your site title', 'all-in-one-seo-pack' ) . '
                    • ' . '
                    • ' . - __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ) . + __( '%site_description% - Your site description', 'all-in-one-seo-pack' ) . '
                    • ' . '
                    • ' . __( '%search% - What was searched for', 'all-in-one-seo-pack' ) . @@ -351,10 +351,10 @@ private function help_text_general() { __( 'This controls the format of Meta Descriptions.The following macros are supported:', 'all-in-one-seo-pack' ) . '
                        ' . '
                      • ' . - __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ) . + __( '%site_title% - Your site title', 'all-in-one-seo-pack' ) . '
                      • ' . '
                      • ' . - __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ) . + __( '%site_description% - Your site description', 'all-in-one-seo-pack' ) . '
                      • ' . '
                      • ' . __( '%description% - This outputs the description you write for each page/post or the autogenerated description, if you have that option enabled. Auto-generated descriptions are generated from the Post Excerpt, or the first 160 characters of the post content if there is no Post Excerpt.', 'all-in-one-seo-pack' ) . @@ -386,10 +386,10 @@ private function help_text_general() { __( 'The following macros are supported:', 'all-in-one-seo-pack' ) . '
                          ' . '
                        • ' . - __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ) . + __( '%site_title% - Your site title', 'all-in-one-seo-pack' ) . '
                        • ' . '
                        • ' . - __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ) . + __( '%site_description% - Your site description', 'all-in-one-seo-pack' ) . '
                        • ' . '
                        • ' . __( '%request_url% - The original URL path, like "/url-that-does-not-exist/"', 'all-in-one-seo-pack' ) . @@ -491,8 +491,8 @@ private function help_text_general() { $help_text_fields = array(); array_push( $help_text_fields, - __( '%blog_title% - Your blog title', 'all-in-one-seo-pack' ), - __( '%blog_description% - Your blog description', 'all-in-one-seo-pack' ), + __( '%site_title% - Your site title', 'all-in-one-seo-pack' ), + __( '%site_description% - Your site description', 'all-in-one-seo-pack' ), __( '%post_title% - The original title of the page', 'all-in-one-seo-pack' ) ); $pt_obj_taxes = get_object_taxonomies( $v1_pt, 'objects' ); diff --git a/aioseop_class.php b/aioseop_class.php index 22c9a8448..0261439db 100644 --- a/aioseop_class.php +++ b/aioseop_class.php @@ -180,49 +180,49 @@ function __construct() { 'page_title_format' => array( 'name' => __( 'Page Title Format:', 'all-in-one-seo-pack' ), 'type' => 'text', - 'default' => '%page_title% | %blog_title%', + 'default' => '%page_title% | %site_title%', 'condshow' => array( 'aiosp_rewrite_titles' => 1 ), ), 'post_title_format' => array( 'name' => __( 'Post Title Format:', 'all-in-one-seo-pack' ), 'type' => 'text', - 'default' => '%post_title% | %blog_title%', + 'default' => '%post_title% | %site_title%', 'condshow' => array( 'aiosp_rewrite_titles' => 1 ), ), 'category_title_format' => array( 'name' => __( 'Category Title Format:', 'all-in-one-seo-pack' ), 'type' => 'text', - 'default' => '%category_title% | %blog_title%', + 'default' => '%category_title% | %site_title%', 'condshow' => array( 'aiosp_rewrite_titles' => 1 ), ), 'archive_title_format' => array( 'name' => __( 'Archive Title Format:', 'all-in-one-seo-pack' ), 'type' => 'text', - 'default' => '%archive_title% | %blog_title%', + 'default' => '%archive_title% | %site_title%', 'condshow' => array( 'aiosp_rewrite_titles' => 1 ), ), 'date_title_format' => array( 'name' => __( 'Date Archive Title Format:', 'all-in-one-seo-pack' ), 'type' => 'text', - 'default' => '%date% | %blog_title%', + 'default' => '%date% | %site_title%', 'condshow' => array( 'aiosp_rewrite_titles' => 1 ), ), 'author_title_format' => array( 'name' => __( 'Author Archive Title Format:', 'all-in-one-seo-pack' ), 'type' => 'text', - 'default' => '%author% | %blog_title%', + 'default' => '%author% | %site_title%', 'condshow' => array( 'aiosp_rewrite_titles' => 1 ), ), 'tag_title_format' => array( 'name' => __( 'Tag Title Format:', 'all-in-one-seo-pack' ), 'type' => 'text', - 'default' => '%tag% | %blog_title%', + 'default' => '%tag% | %site_title%', 'condshow' => array( 'aiosp_rewrite_titles' => 1 ), ), 'search_title_format' => array( 'name' => __( 'Search Title Format:', 'all-in-one-seo-pack' ), 'type' => 'text', - 'default' => '%search% | %blog_title%', + 'default' => '%search% | %site_title%', 'condshow' => array( 'aiosp_rewrite_titles' => 1 ), ), 'description_format' => array( @@ -929,28 +929,32 @@ public function get_title_format( $args ) { $w = $info['w']; $p = $info['p']; - if ( strpos( $title_format, '%blog_title%' ) !== false ) { + if ( false !== strpos( $title_format, '%site_title%', 0 ) ) { + $title_format = str_replace( '%site_title%', get_bloginfo( 'name' ), $title_format ); + } + // %blog_title% is deprecated. + if ( false !== strpos( $title_format, '%blog_title%', 0 ) ) { $title_format = str_replace( '%blog_title%', get_bloginfo( 'name' ), $title_format ); } $title_format = $this->apply_cf_fields( $title_format ); $replace_title = '' . esc_attr( wp_strip_all_tags( html_entity_decode( $title ) ) ) . ''; - if ( strpos( $title_format, '%post_title%' ) !== false ) { + if ( false !== strpos( $title_format, '%post_title%', 0 ) ) { $title_format = str_replace( '%post_title%', $replace_title, $title_format ); } - if ( strpos( $title_format, '%page_title%' ) !== false ) { + if ( false !== strpos( $title_format, '%page_title%', 0 ) ) { $title_format = str_replace( '%page_title%', $replace_title, $title_format ); } - if ( strpos( $title_format, '%current_date%' ) !== false ) { + if ( false !== strpos( $title_format, '%current_date%', 0 ) ) { $title_format = str_replace( '%current_date%', aioseop_formatted_date(), $title_format ); } - if ( strpos( $title_format, '%post_date%' ) !== false ) { + if ( false !== strpos( $title_format, '%post_date%', 0 ) ) { $title_format = str_replace( '%post_date%', aioseop_formatted_date( get_the_time( 'U' ) ), $title_format ); } - if ( strpos( $title_format, '%post_year%' ) !== false ) { + if ( false !== strpos( $title_format, '%post_year%', 0 ) ) { $title_format = str_replace( '%post_year%', get_the_date( 'Y' ), $title_format ); } - if ( strpos( $title_format, '%post_month%' ) !== false ) { + if ( false !== strpos( $title_format, '%post_month%', 0 ) ) { $title_format = str_replace( '%post_month%', get_the_date( 'F' ), $title_format ); } if ( $w->is_category || $w->is_tag || $w->is_tax ) { @@ -966,28 +970,28 @@ public function get_title_format( $args ) { } } } - if ( strpos( $title_format, '%category_title%' ) !== false ) { + if ( false !== strpos( $title_format, '%category_title%', 0 ) ) { $title_format = str_replace( '%category_title%', $replace_title, $title_format ); } - if ( strpos( $title_format, '%taxonomy_title%' ) !== false ) { + if ( false !== strpos( $title_format, '%taxonomy_title%', 0 ) ) { $title_format = str_replace( '%taxonomy_title%', $replace_title, $title_format ); } } else { - if ( strpos( $title_format, '%category%' ) !== false ) { + if ( false !== strpos( $title_format, '%category%', 0 ) ) { $title_format = str_replace( '%category%', $category, $title_format ); } - if ( strpos( $title_format, '%category_title%' ) !== false ) { + if ( false !== strpos( $title_format, '%category_title%', 0 ) ) { $title_format = str_replace( '%category_title%', $category, $title_format ); } - if ( strpos( $title_format, '%taxonomy_title%' ) !== false ) { + if ( false !== strpos( $title_format, '%taxonomy_title%', 0 ) ) { $title_format = str_replace( '%taxonomy_title%', $category, $title_format ); } if ( AIOSEOPPRO ) { - if ( strpos( $title_format, '%tax_' ) && ! empty( $p ) ) { + if ( strpos( $title_format, '%tax_', 0 ) && ! empty( $p ) ) { $taxes = get_object_taxonomies( $p, 'objects' ); if ( ! empty( $taxes ) ) { foreach ( $taxes as $t ) { - if ( strpos( $title_format, "%tax_{$t->name}%" ) ) { + if ( strpos( $title_format, "%tax_{$t->name}%", 0 ) ) { $terms = $this->get_all_terms( $p->ID, $t->name ); $term = ''; if ( count( $terms ) > 0 ) { @@ -1000,7 +1004,7 @@ public function get_title_format( $args ) { } } } - if ( strpos( $title_format, '%taxonomy_description%' ) !== false ) { + if ( false !== strpos( $title_format, '%taxonomy_description%', 0 ) ) { $title_format = str_replace( '%taxonomy_description%', $description, $title_format ); } @@ -1472,11 +1476,17 @@ function get_aioseop_title( $post, $use_original_title_format = true ) { } elseif ( is_search() && isset( $s ) && ! empty( $s ) ) { $search = esc_attr( stripslashes( $s ) ); $title_format = $aioseop_options['aiosp_search_title_format']; - $title = str_replace( '%blog_title%', $this->internationalize( get_bloginfo( 'name' ) ), $title_format ); - if ( strpos( $title, '%blog_description%' ) !== false ) { + $title = str_replace( '%site_title%', $this->internationalize( get_bloginfo( 'name' ) ), $title_format ); + if ( false !== strpos( $title, '%blog_title%', 0 ) ) { + $title = str_replace( '%blog_title%', $this->internationalize( get_bloginfo( 'name' ) ), $title ); + } + if ( false !== strpos( $title, '%site_description%', 0 ) ) { + $title = str_replace( '%site_description%', $this->internationalize( get_bloginfo( 'description' ) ), $title ); + } + if ( false !== strpos( $title, '%blog_description%', 0 ) ) { $title = str_replace( '%blog_description%', $this->internationalize( get_bloginfo( 'description' ) ), $title ); } - if ( strpos( $title, '%search%' ) !== false ) { + if ( false !== strpos( $title, '%search%', 0 ) ) { $title = str_replace( '%search%', $search, $title ); } $title = $this->paged_title( $title ); @@ -1514,17 +1524,23 @@ function get_aioseop_title( $post, $use_original_title_format = true ) { } if ( $tag ) { $title_format = $aioseop_options['aiosp_tag_title_format']; - $title = str_replace( '%blog_title%', $this->internationalize( get_bloginfo( 'name' ) ), $title_format ); - if ( strpos( $title, '%blog_description%' ) !== false ) { + $title = str_replace( '%site_title%', $this->internationalize( get_bloginfo( 'name' ) ), $title_format ); + if ( false !== strpos( $title, '%blog_title%', 0 ) ) { + $title = str_replace( '%blog_title%', $this->internationalize( get_bloginfo( 'name' ) ), $title ); + } + if ( false !== strpos( $title, '%site_description%', 0 ) ) { + $title = str_replace( '%site_description%', $this->internationalize( get_bloginfo( 'description' ) ), $title ); + } + if ( false !== strpos( $title, '%blog_description%', 0 ) ) { $title = str_replace( '%blog_description%', $this->internationalize( get_bloginfo( 'description' ) ), $title ); } - if ( strpos( $title, '%tag%' ) !== false ) { + if ( false !== strpos( $title, '%tag%', 0 ) ) { $title = str_replace( '%tag%', $tag, $title ); } - if ( strpos( $title, '%tag_description%' ) !== false ) { + if ( false !== strpos( $title, '%tag_description%', 0 ) ) { $title = str_replace( '%tag_description%', $tag_description, $title ); } - if ( strpos( $title, '%taxonomy_description%' ) !== false ) { + if ( false !== strpos( $title, '%taxonomy_description%', 0 ) ) { $title = str_replace( '%taxonomy_description%', $tag_description, $title ); } $title = trim( wp_strip_all_tags( $title ) ); @@ -1539,11 +1555,17 @@ function get_aioseop_title( $post, $use_original_title_format = true ) { $tag = $STagging->search_tag; if ( $tag ) { $title_format = $aioseop_options['aiosp_tag_title_format']; - $title = str_replace( '%blog_title%', $this->internationalize( get_bloginfo( 'name' ) ), $title_format ); - if ( strpos( $title, '%blog_description%' ) !== false ) { + $title = str_replace( '%site_title%', $this->internationalize( get_bloginfo( 'name' ) ), $title_format ); + if ( false !== strpos( $title, '%blog_title%', 0 ) ) { + $title = str_replace( '%blog_title%', $this->internationalize( get_bloginfo( 'name' ) ), $title ); + } + if ( false !== strpos( $title, '%site_description%', 0 ) ) { + $title = str_replace( '%site_description%', $this->internationalize( get_bloginfo( 'description' ) ), $title ); + } + if ( false !== strpos( $title, '%blog_description%', 0 ) ) { $title = str_replace( '%blog_description%', $this->internationalize( get_bloginfo( 'description' ) ), $title ); } - if ( strpos( $title, '%tag%' ) !== false ) { + if ( false !== strpos( $title, '%tag%', 0 ) ) { $title = str_replace( '%tag%', $tag, $title ); } $title = $this->paged_title( $title ); @@ -1573,10 +1595,10 @@ function get_aioseop_title( $post, $use_original_title_format = true ) { } $month = date( 'F', mktime( 0, 0, 0, (int) $monthnum, 1, (int) $year ) ); $new_title = str_replace( '%monthnum%', $monthnum, $new_title ); - if ( strpos( $new_title, '%month%' ) !== false ) { + if ( false !== strpos( $new_title, '%month%', 0 ) ) { $new_title = str_replace( '%month%', $month, $new_title ); } - if ( strpos( $new_title, '%year%' ) !== false ) { + if ( false !== strpos( $new_title, '%year%', 0 ) ) { $new_title = str_replace( '%year%', get_query_var( 'year' ), $new_title ); } } elseif ( is_post_type_archive() ) { @@ -1587,8 +1609,14 @@ function get_aioseop_title( $post, $use_original_title_format = true ) { } else { return false; } - $new_title = str_replace( '%blog_title%', $this->internationalize( get_bloginfo( 'name' ) ), $new_title ); - if ( strpos( $new_title, '%blog_description%' ) !== false ) { + $new_title = str_replace( '%site_title%', $this->internationalize( get_bloginfo( 'name' ) ), $new_title ); + if ( false !== strpos( $new_title, '%blog_title%', 0 ) ) { + $new_title = str_replace( '%blog_title%', $this->internationalize( get_bloginfo( 'name' ) ), $new_title ); + } + if ( false !== strpos( $new_title, '%site_description%', 0 ) ) { + $new_title = str_replace( '%site_description%', $this->internationalize( get_bloginfo( 'description' ) ), $new_title ); + } + if ( false !== strpos( $new_title, '%blog_description%', 0 ) ) { $new_title = str_replace( '%blog_description%', $this->internationalize( get_bloginfo( 'description' ) ), $new_title ); } $title = trim( $new_title ); @@ -1597,17 +1625,23 @@ function get_aioseop_title( $post, $use_original_title_format = true ) { return $title; } elseif ( is_404() ) { $title_format = $aioseop_options['aiosp_404_title_format']; - $new_title = str_replace( '%blog_title%', $this->internationalize( get_bloginfo( 'name' ) ), $title_format ); - if ( strpos( $new_title, '%blog_description%' ) !== false ) { + $new_title = str_replace( '%site_title%', $this->internationalize( get_bloginfo( 'name' ) ), $title_format ); + if ( false !== strpos( $new_title, '%blog_title%', 0 ) ) { + $new_title = str_replace( '%blog_title%', $this->internationalize( get_bloginfo( 'name' ) ), $new_title ); + } + if ( false !== strpos( $new_title, '%site_description%', 0 ) ) { + $new_title = str_replace( '%site_description%', $this->internationalize( get_bloginfo( 'description' ) ), $new_title ); + } + if ( false !== strpos( $new_title, '%blog_description%', 0 ) ) { $new_title = str_replace( '%blog_description%', $this->internationalize( get_bloginfo( 'description' ) ), $new_title ); } - if ( strpos( $new_title, '%request_url%' ) !== false ) { + if ( false !== strpos( $new_title, '%request_url%', 0 ) ) { $new_title = str_replace( '%request_url%', $_SERVER['REQUEST_URI'], $new_title ); } - if ( strpos( $new_title, '%request_words%' ) !== false ) { + if ( false !== strpos( $new_title, '%request_words%', 0 ) ) { $new_title = str_replace( '%request_words%', $this->request_as_words( $_SERVER['REQUEST_URI'] ), $new_title ); } - if ( strpos( $new_title, '%404_title%' ) !== false ) { + if ( false !== strpos( $new_title, '%404_title%', 0 ) ) { $new_title = str_replace( '%404_title%', $this->internationalize( $this->get_original_title( '', false ) ), $new_title ); } @@ -1694,14 +1728,20 @@ function get_original_title( $sep = '|', $echo = false, $seplocation = '' ) { $title = $this->internationalize( post_type_archive_title( '', false ) ); } elseif ( is_404() ) { $title_format = $aioseop_options['aiosp_404_title_format']; - $new_title = str_replace( '%blog_title%', $this->internationalize( get_bloginfo( 'name' ) ), $title_format ); - if ( strpos( $new_title, '%blog_description%' ) !== false ) { + $new_title = str_replace( '%site_title%', $this->internationalize( get_bloginfo( 'name' ) ), $title_format ); + if ( false !== strpos( $new_title, '%blog_title%', 0 ) ) { + $new_title = str_replace( '%blog_title%', $this->internationalize( get_bloginfo( 'name' ) ), $new_title ); + } + if ( false !== strpos( $new_title, '%site_description%', 0 ) ) { + $new_title = str_replace( '%site_description%', $this->internationalize( get_bloginfo( 'description' ) ), $new_title ); + } + if ( false !== strpos( $new_title, '%blog_description%', 0 ) ) { $new_title = str_replace( '%blog_description%', $this->internationalize( get_bloginfo( 'description' ) ), $new_title ); } - if ( strpos( $new_title, '%request_url%' ) !== false ) { + if ( false !== strpos( $new_title, '%request_url%', 0 ) ) { $new_title = str_replace( '%request_url%', $_SERVER['REQUEST_URI'], $new_title ); } - if ( strpos( $new_title, '%request_words%' ) !== false ) { + if ( false !== strpos( $new_title, '%request_words%', 0 ) ) { $new_title = str_replace( '%request_words%', $this->request_as_words( $_SERVER['REQUEST_URI'] ), $new_title ); } $title = $new_title; @@ -1770,25 +1810,31 @@ function title_placeholder_helper( $title, $post, $type = 'post', $title_format } else { $authordata = new WP_User(); } - $new_title = str_replace( '%blog_title%', $this->internationalize( get_bloginfo( 'name' ) ), $title_format ); - if ( strpos( $new_title, '%blog_description%' ) !== false ) { + $new_title = str_replace( '%site_title%', $this->internationalize( get_bloginfo( 'name' ) ), $title_format ); + if ( false !== strpos( $new_title, '%blog_title%', 0 ) ) { + $new_title = str_replace( '%blog_title%', $this->internationalize( get_bloginfo( 'name' ) ), $new_title ); + } + if ( false !== strpos( $new_title, '%site_description%', 0 ) ) { + $new_title = str_replace( '%site_description%', $this->internationalize( get_bloginfo( 'description' ) ), $new_title ); + } + if ( false !== strpos( $new_title, '%blog_description%', 0 ) ) { $new_title = str_replace( '%blog_description%', $this->internationalize( get_bloginfo( 'description' ) ), $new_title ); } - if ( strpos( $new_title, "%{$type}_title%" ) !== false ) { + if ( false !== strpos( $new_title, "%{$type}_title%", 0 ) ) { $new_title = str_replace( "%{$type}_title%", $title, $new_title ); } if ( $type == 'post' ) { - if ( strpos( $new_title, '%category%' ) !== false ) { + if ( false !== strpos( $new_title, '%category%', 0 ) ) { $new_title = str_replace( '%category%', $category, $new_title ); } - if ( strpos( $new_title, '%category_title%' ) !== false ) { + if ( false !== strpos( $new_title, '%category_title%', 0 ) ) { $new_title = str_replace( '%category_title%', $category, $new_title ); } - if ( strpos( $new_title, '%tax_' ) && ! empty( $post ) ) { + if ( false !== strpos( $new_title, '%tax_', 0 ) && ! empty( $post ) ) { $taxes = get_object_taxonomies( $post, 'objects' ); if ( ! empty( $taxes ) ) { foreach ( $taxes as $t ) { - if ( strpos( $new_title, "%tax_{$t->name}%" ) ) { + if ( false !== strpos( $new_title, "%tax_{$t->name}%", 0 ) ) { $terms = $this->get_all_terms( $post->ID, $t->name ); $term = ''; if ( count( $terms ) > 0 ) { @@ -1800,29 +1846,29 @@ function title_placeholder_helper( $title, $post, $type = 'post', $title_format } } } - if ( strpos( $new_title, "%{$type}_author_login%" ) !== false ) { + if ( false !== strpos( $new_title, "%{$type}_author_login%", 0 ) ) { $new_title = str_replace( "%{$type}_author_login%", $authordata->user_login, $new_title ); } - if ( strpos( $new_title, "%{$type}_author_nicename%" ) !== false ) { + if ( false !== strpos( $new_title, "%{$type}_author_nicename%", 0 ) ) { $new_title = str_replace( "%{$type}_author_nicename%", $authordata->user_nicename, $new_title ); } - if ( strpos( $new_title, "%{$type}_author_firstname%" ) !== false ) { + if ( false !== strpos( $new_title, "%{$type}_author_firstname%", 0 ) ) { $new_title = str_replace( "%{$type}_author_firstname%", $this->ucwords( $authordata->first_name ), $new_title ); } - if ( strpos( $new_title, "%{$type}_author_lastname%" ) !== false ) { + if ( false !== strpos( $new_title, "%{$type}_author_lastname%", 0 ) ) { $new_title = str_replace( "%{$type}_author_lastname%", $this->ucwords( $authordata->last_name ), $new_title ); } - if ( strpos( $new_title, '%current_date%' ) !== false ) { + if ( false !== strpos( $new_title, '%current_date%', 0 ) ) { $new_title = str_replace( '%current_date%', aioseop_formatted_date(), $new_title ); } - if ( strpos( $new_title, '%post_date%' ) !== false ) { + if ( false !== strpos( $new_title, '%post_date%', 0 ) ) { $new_title = str_replace( '%post_date%', aioseop_formatted_date( get_the_date( 'U' ) ), $new_title ); } - if ( strpos( $new_title, '%post_year%' ) !== false ) { + if ( false !== strpos( $new_title, '%post_year%', 0 ) ) { $new_title = str_replace( '%post_year%', get_the_date( 'Y' ), $new_title ); } - if ( strpos( $new_title, '%post_month%' ) !== false ) { + if ( false !== strpos( $new_title, '%post_month%', 0 ) ) { $new_title = str_replace( '%post_month%', get_the_date( 'F' ), $new_title ); } @@ -1917,7 +1963,7 @@ function get_post_title_format( $title_type = 'post', $p = null ) { if ( ( $title_type != 'post' ) && ( $title_type != 'archive' ) ) { return false; } - $title_format = "%{$title_type}_title% | %blog_title%"; + $title_format = "%{$title_type}_title% | %site_title%"; if ( isset( $aioseop_options[ "aiosp_{$title_type}_title_format" ] ) ) { $title_format = $aioseop_options[ "aiosp_{$title_type}_title_format" ]; } @@ -2084,19 +2130,25 @@ function apply_tax_title_format( $category_name, $category_description, $tax = ' } $title_format = $this->get_tax_title_format( $tax ); $title = str_replace( '%taxonomy_title%', $category_name, $title_format ); - if ( strpos( $title, '%taxonomy_description%' ) !== false ) { + if ( false !== strpos( $title, '%taxonomy_description%', 0 ) ) { $title = str_replace( '%taxonomy_description%', $category_description, $title ); } - if ( strpos( $title, '%category_title%' ) !== false ) { + if ( false !== strpos( $title, '%category_title%', 0 ) ) { $title = str_replace( '%category_title%', $category_name, $title ); } - if ( strpos( $title, '%category_description%' ) !== false ) { + if ( false !== strpos( $title, '%category_description%', 0 ) ) { $title = str_replace( '%category_description%', $category_description, $title ); } - if ( strpos( $title, '%blog_title%' ) !== false ) { + if ( false !== strpos( $title, '%site_title%', 0 ) ) { + $title = str_replace( '%site_title%', $this->internationalize( get_bloginfo( 'name' ) ), $title ); + } + if ( false !== strpos( $title, '%blog_title%', 0 ) ) { $title = str_replace( '%blog_title%', $this->internationalize( get_bloginfo( 'name' ) ), $title ); } - if ( strpos( $title, '%blog_description%' ) !== false ) { + if ( false !== strpos( $title, '%site_description%', 0 ) ) { + $title = str_replace( '%site_description%', $this->internationalize( get_bloginfo( 'description' ) ), $title ); + } + if ( false !== strpos( $title, '%blog_description%', 0 ) ) { $title = str_replace( '%blog_description%', $this->internationalize( get_bloginfo( 'description' ) ), $title ); } $title = wp_strip_all_tags( $title ); @@ -2112,7 +2164,7 @@ function apply_tax_title_format( $category_name, $category_description, $tax = ' function get_tax_title_format( $tax = '' ) { global $aioseop_options; if ( AIOSEOPPRO ) { - $title_format = '%taxonomy_title% | %blog_title%'; + $title_format = '%taxonomy_title% | %site_title%'; if ( is_category() ) { $title_format = $aioseop_options['aiosp_category_title_format']; } else { @@ -2125,10 +2177,10 @@ function get_tax_title_format( $tax = '' ) { } } if ( empty( $title_format ) ) { - $title_format = '%category_title% | %blog_title%'; + $title_format = '%category_title% | %site_title%'; } } else { - $title_format = '%category_title% | %blog_title%'; + $title_format = '%category_title% | %site_title%'; if ( ! empty( $aioseop_options['aiosp_category_title_format'] ) ) { $title_format = $aioseop_options['aiosp_category_title_format']; } @@ -2147,7 +2199,7 @@ function get_tax_title_format( $tax = '' ) { */ function apply_archive_title_format( $title, $category = '' ) { $title_format = $this->get_archive_title_format(); - $r_title = array( '%blog_title%', '%blog_description%', '%archive_title%' ); + $r_title = array( '%site_title%', '%site_description%', '%archive_title%' ); $d_title = array( $this->internationalize( get_bloginfo( 'name' ) ), $this->internationalize( get_bloginfo( 'description' ) ), @@ -2249,7 +2301,7 @@ function show_page_description() { */ function get_page_number() { global $post; - if ( is_singular() && false === strpos( $post->post_content, '' ) ) { + if ( is_singular() && false === strpos( $post->post_content, '', 0 ) ) { return null; } $page = get_query_var( 'page' ); @@ -2913,7 +2965,7 @@ function add_page_hooks() { $this->default_options[ $field ] = array( 'name' => "$name " . __( 'Title Format:', 'all-in-one-seo-pack' ) . "
                          ($p)", 'type' => 'text', - 'default' => '%post_title% | %blog_title%', + 'default' => '%post_title% | %site_title%', 'condshow' => array( 'aiosp_rewrite_titles' => 1, 'aiosp_cpostactive\[\]' => $p, @@ -2945,7 +2997,7 @@ function add_page_hooks() { $this->default_options[ $field ] = array( 'name' => "$name " . __( 'Taxonomy Title Format:', 'all-in-one-seo-pack' ), 'type' => 'text', - 'default' => '%taxonomy_title% | %blog_title%', + 'default' => '%taxonomy_title% | %site_title%', 'condshow' => array( 'aiosp_rewrite_titles' => 1, 'aiosp_taxactive\[\]' => $p, @@ -3376,8 +3428,8 @@ function replace_title( $content, $title ) { $title = trim( strip_tags( $title ) ); $title_tag_start = 'strpos( $content, $title_tag_start ); - $end = $this->strpos( $content, $title_tag_end ); + $start = $this->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; @@ -3866,28 +3918,34 @@ function apply_description_format( $description, $post = null ) { $description_format = '%description%'; } $description = str_replace( '%description%', apply_filters( 'aioseop_description_override', $description ), $description_format ); - if ( strpos( $description, '%blog_title%' ) !== false ) { + 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 ( strpos( $description, '%blog_description%' ) !== false ) { + 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 ( strpos( $description, '%wp_title%' ) !== false ) { + if ( false !== strpos( $description, '%wp_title%', 0 ) ) { $description = str_replace( '%wp_title%', $this->get_original_title(), $description ); } - if ( strpos( $description, '%post_title%' ) !== false ) { + if ( false !== strpos( $description, '%post_title%', 0 ) ) { $description = str_replace( '%post_title%', $this->get_aioseop_title( $post, false ), $description ); } - if ( strpos( $description, '%current_date%' ) !== false ) { + if ( false !== strpos( $description, '%current_date%', 0 ) ) { $description = str_replace( '%current_date%', date_i18n( get_option( 'date_format' ) ), $description ); } - if ( strpos( $description, '%post_date%' ) !== false ) { + if ( false !== strpos( $description, '%post_date%', 0 ) ) { $description = str_replace( '%post_date%', get_the_date(), $description ); } - if ( strpos( $description, '%post_year%' ) !== false ) { + if ( false !== strpos( $description, '%post_year%', 0 ) ) { $description = str_replace( '%post_year%', get_the_date( 'Y' ), $description ); } - if ( strpos( $description, '%post_month%' ) !== false ) { + if ( false !== strpos( $description, '%post_month%', 0 ) ) { $description = str_replace( '%post_month%', get_the_date( 'F' ), $description ); } @@ -4157,7 +4215,7 @@ function get_prev_next_links( $post = null ) { $more = 1; } $content = $post->post_content; - if ( false !== strpos( $content, '' ) ) { + if ( false !== strpos( $content, '', 0 ) ) { if ( $page > 1 ) { $more = 1; } @@ -4165,7 +4223,7 @@ function get_prev_next_links( $post = null ) { $content = str_replace( "\n", '', $content ); $content = str_replace( "\n", '', $content ); // Ignore nextpage at the beginning of the content. - if ( 0 === strpos( $content, '' ) ) { + if ( 0 === strpos( $content, '', 0 ) ) { $content = substr( $content, 15 ); } $pages = explode( '', $content ); diff --git a/inc/aioseop_functions.php b/inc/aioseop_functions.php index b8aa34dd2..6147476d9 100644 --- a/inc/aioseop_functions.php +++ b/inc/aioseop_functions.php @@ -74,8 +74,8 @@ function aioseop_update_settings_check() { unset( $aioseop_options['aiosp_archive_title_format'] ); $update_options = true; } - if ( ! empty( $aioseop_options['aiosp_archive_title_format'] ) && ( $aioseop_options['aiosp_archive_title_format'] === '%date% | %blog_title%' ) ) { - $aioseop_options['aiosp_archive_title_format'] = '%archive_title% | %blog_title%'; + if ( ! empty( $aioseop_options['aiosp_archive_title_format'] ) && ( $aioseop_options['aiosp_archive_title_format'] === '%date% | %site_title%' ) ) { + $aioseop_options['aiosp_archive_title_format'] = '%archive_title% | %site_title%'; $update_options = true; } if ( $update_options ) { diff --git a/tests/modules/general/test-meta.php b/tests/modules/general/test-meta.php index cc4c46a0d..ccafd3ca2 100644 --- a/tests/modules/general/test-meta.php +++ b/tests/modules/general/test-meta.php @@ -169,7 +169,7 @@ public function postContentProvider() { public function metaDescProvider() { return array( array( 'heyhey', 'heyhey', '%post_title%' ), - array( 'heyhey', 'heyhey' . get_option( 'blogname' ), '%post_title%%blog_title%' ), + array( 'heyhey', 'heyhey' . get_option( 'blogname' ), '%post_title%%site_title%' ), ); } diff --git a/tests/modules/general/test-rewrite-title.php b/tests/modules/general/test-rewrite-title.php new file mode 100644 index 000000000..5eeb90100 --- /dev/null +++ b/tests/modules/general/test-rewrite-title.php @@ -0,0 +1,105 @@ + 'post', 'post_title' => 'Example Title' ); + $id = $this->factory->post->create( $args ); + break; + case 'category': + $args = array( 'taxonomy' => 'category' ); + $id = $this->factory->term->create( $args ); + break; + } + + $link = get_permalink( $id ); + $title = $this->parse_html( $link, array ('title') ); + + $this->assertEquals( 1, count( $title ) ); + $this->assertContains( $blog_name, $title[0]['#text'] ); + + return $title; + } + + /** + * %xxx_title% macro comparison test. + * + * Tests whether the rewrite feature returns the same result for both site title macros. + * + * @group title_macros + * + * @since 3.0 + */ + public function test_compare_title_macros() { + $site_title = $this->test_title_format_macros( '%site_title%' ); + $blog_title = $this->test_title_format_macros( '%blog_title%' ); + + $this->assertSame( $site_title, $blog_title ); + } + + /** + * Title format macro provider. + * + * Provides combinations to test_title_format_macros(). + * + * @group title_macros + * + * @since 3.0 + */ + public function macroProvider() { + return [ + '%site_title% & post' => ['%site_title', 'post' ], + '%site_title% & category' => ['%site_title', 'category' ], + '%blog_title% & post' => ['%blog_title', 'post' ], + '%blog_title% & category' => ['%blog_title', 'category' ], + ]; + } +} \ No newline at end of file From 2991e0c0eb1475634d2afe2f3dd1c556e7f882d1 Mon Sep 17 00:00:00 2001 From: Arnaud Broes Date: Tue, 7 May 2019 16:50:43 -0400 Subject: [PATCH 048/121] Fix PHPCS missing line at end of test-rewrite-titles.php #2392 (#2393) --- tests/modules/general/test-rewrite-title.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/modules/general/test-rewrite-title.php b/tests/modules/general/test-rewrite-title.php index 5eeb90100..e51799bce 100644 --- a/tests/modules/general/test-rewrite-title.php +++ b/tests/modules/general/test-rewrite-title.php @@ -102,4 +102,4 @@ public function macroProvider() { '%blog_title% & category' => ['%blog_title', 'category' ], ]; } -} \ No newline at end of file +} From d94d15fbc04f6f84f679159bb8f0eba36ad36549 Mon Sep 17 00:00:00 2001 From: Arnaud Broes Date: Wed, 8 May 2019 11:09:33 -0400 Subject: [PATCH 049/121] + Add %current_year% macro #1754 (#2388) --- admin/class-aioseop-helper.php | 16 ++++++++++++++++ aioseop_class.php | 14 ++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/admin/class-aioseop-helper.php b/admin/class-aioseop-helper.php index c785bf4d6..8c477487d 100644 --- a/admin/class-aioseop-helper.php +++ b/admin/class-aioseop-helper.php @@ -159,6 +159,9 @@ private function help_text_general() { '
                        • ' . __( '%current_date% - The current date (localized)', 'all-in-one-seo-pack' ) . '
                        • ' . + '
                        • ' . + __( '%current_year% - The current year', 'all-in-one-seo-pack' ) . + '
                        • ' . '
                        • ' . __( '%cf_fieldname% - Custom field name', 'all-in-one-seo-pack' ) . '
                        • ' . @@ -191,6 +194,9 @@ private function help_text_general() { '
                        • ' . __( '%current_date% - The current date (localized)', 'all-in-one-seo-pack' ) . '
                        • ' . + '
                        • ' . + __( '%current_year% - The current year', 'all-in-one-seo-pack' ) . + '
                        • ' . '
                        • ' . __( '%post_date% - The date the page was published (localized)', 'all-in-one-seo-pack' ) . '
                        • ' . @@ -238,6 +244,9 @@ private function help_text_general() { '
                        • ' . __( '%current_date% - The current date (localized)', 'all-in-one-seo-pack' ) . '
                        • ' . + '
                        • ' . + __( '%current_year% - The current year', 'all-in-one-seo-pack' ) . + '
                        • ' . '
                        • ' . __( '%post_date% - The date the post was published (localized)', 'all-in-one-seo-pack' ) . '
                        • ' . @@ -267,6 +276,9 @@ private function help_text_general() { '
                        • ' . __( '%category_description% - The description of the category', 'all-in-one-seo-pack' ) . '
                        • ' . + '
                        • ' . + __( '%current_year% - The current year', 'all-in-one-seo-pack' ) . + '
                        • ' . '
                        ', 'aiosp_archive_title_format' => __( 'This controls the format of the title tag for Custom Post Archives.', 'all-in-one-seo-pack' ) . '
                        ' . @@ -368,6 +380,9 @@ private function help_text_general() { '
                      • ' . __( '%current_date% - The current date (localized)', 'all-in-one-seo-pack' ) . '
                      • ' . + '
                      • ' . + __( '%current_year% - The current year', 'all-in-one-seo-pack' ) . + '
                      • ' . '
                      • ' . __( '%post_date% - The date the page/post was published (localized)', 'all-in-one-seo-pack' ) . '
                      • ' . @@ -509,6 +524,7 @@ private function help_text_general() { __( '%post_author_firstname% - This page\'s author\' first name (capitalized)', 'all-in-one-seo-pack' ), __( '%post_author_lastname% - This page\'s author\' last name (capitalized)', 'all-in-one-seo-pack' ), __( '%current_date% - The current date (localized)', 'all-in-one-seo-pack' ), + __( '%current_year% - The current year', 'all-in-one-seo-pack' ), __( '%post_date% - The date the page was published (localized)', 'all-in-one-seo-pack' ), __( '%post_year% - The year the page was published (localized)', 'all-in-one-seo-pack' ), __( '%post_month% - The month the page was published (localized)', 'all-in-one-seo-pack' ) diff --git a/aioseop_class.php b/aioseop_class.php index 0261439db..eb8b8cf2b 100644 --- a/aioseop_class.php +++ b/aioseop_class.php @@ -947,7 +947,9 @@ public function get_title_format( $args ) { if ( false !== strpos( $title_format, '%current_date%', 0 ) ) { $title_format = str_replace( '%current_date%', aioseop_formatted_date(), $title_format ); } - + if ( false !== strpos( $title_format, '%current_year%', 0 ) ) { + $title_format = str_replace( '%current_year%', date( 'Y' ), $title_format ); + } if ( false !== strpos( $title_format, '%post_date%', 0 ) ) { $title_format = str_replace( '%post_date%', aioseop_formatted_date( get_the_time( 'U' ) ), $title_format ); } @@ -1858,10 +1860,12 @@ function title_placeholder_helper( $title, $post, $type = 'post', $title_format if ( false !== strpos( $new_title, "%{$type}_author_lastname%", 0 ) ) { $new_title = str_replace( "%{$type}_author_lastname%", $this->ucwords( $authordata->last_name ), $new_title ); } - if ( false !== strpos( $new_title, '%current_date%', 0 ) ) { $new_title = str_replace( '%current_date%', aioseop_formatted_date(), $new_title ); } + if ( false !== strpos( $new_title, '%current_year%', 0 ) ) { + $new_title = str_replace( '%current_year%', date( 'Y' ), $new_title ); + } if ( false !== strpos( $new_title, '%post_date%', 0 ) ) { $new_title = str_replace( '%post_date%', aioseop_formatted_date( get_the_date( 'U' ) ), $new_title ); } @@ -2151,6 +2155,9 @@ function apply_tax_title_format( $category_name, $category_description, $tax = ' if ( false !== strpos( $title, '%blog_description%', 0 ) ) { $title = str_replace( '%blog_description%', $this->internationalize( get_bloginfo( 'description' ) ), $title ); } + if ( false !== strpos( $title, '%current_year%', 0 ) ) { + $title = str_replace( '%current_year%', date( 'Y' ), $title ); + } $title = wp_strip_all_tags( $title ); return $this->paged_title( $title ); @@ -3939,6 +3946,9 @@ function apply_description_format( $description, $post = null ) { 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 ); } From 923c488b60339be714c9a54b4677b901908f7bbc Mon Sep 17 00:00:00 2001 From: Arnaud Broes Date: Wed, 8 May 2019 14:42:35 -0400 Subject: [PATCH 050/121] Remove spaces from translatable strings (#2397) * Remove spaces from translatable strings #825 * Refactor code #825 * Remove redundant comments and add translator description #825 --- admin/display/general-metaboxes.php | 3 ++- modules/aioseop_sitemap.php | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/admin/display/general-metaboxes.php b/admin/display/general-metaboxes.php index 3ddc8b653..a7b9d0942 100644 --- a/admin/display/general-metaboxes.php +++ b/admin/display/general-metaboxes.php @@ -43,7 +43,8 @@ static function display_extra_metaboxes( $add, $meta ) {

                        diff --git a/modules/aioseop_sitemap.php b/modules/aioseop_sitemap.php index d83569bbc..95a9fb697 100644 --- a/modules/aioseop_sitemap.php +++ b/modules/aioseop_sitemap.php @@ -649,8 +649,8 @@ public function add_post_types() { $this->default_options['taxonomies']['default'] = array_keys( $this->default_options['taxonomies']['initial_options'] ); $this->default_options['excl_categories']['initial_options'] = $this->get_category_titles(); - $post_name = __( ' Post Type', 'all-in-one-seo-pack' ); - $tax_name = __( ' Taxonomy', 'all-in-one-seo-pack' ); + $post_name = ' ' . __( 'Post Type', 'all-in-one-seo-pack' ); + $tax_name = ' ' . __( 'Taxonomy', 'all-in-one-seo-pack' ); foreach ( $post_type_titles as $k => $v ) { $key = 'prio_post_' . $k; @@ -830,7 +830,7 @@ public function filter_display_options( $options ) { /* translators: Link to documentation. */ $options[ $this->prefix . 'link' ] = sprintf( __( 'Click here to %s.', 'all-in-one-seo-pack' ), '' . __( 'view your XML sitemap', 'all-in-one-seo-pack' ) . '' ); - $options[ $this->prefix . 'link' ] .= __( ' Your sitemap has been created with content and images.', 'all-in-one-seo-pack' ); + $options[ $this->prefix . 'link' ] .= ' ' . __( 'Your sitemap has been created with content and images.', 'all-in-one-seo-pack' ); if ( $options[ "{$this->prefix}rss_sitemap" ] ) { $url_rss = aioseop_home_url( '/' . $this->get_filename() . '.rss' ); From e4c368030d8354d51245abbc2b7f4533413d1af4 Mon Sep 17 00:00:00 2001 From: Arnaud Broes Date: Wed, 8 May 2019 17:11:01 -0400 Subject: [PATCH 051/121] Make remaining strings translatable (#2391) * Make remaining strings translatable #2241 * Undo extra line in test-rewrite-title.php #2241 * Fix missing string and space #2241 * Add domain to translatable strings #2241 * Refactor code #2241 --- admin/display/dashboard_widget.php | 2 +- admin/display/general-metaboxes.php | 2 +- aioseop_class.php | 11 +++++------ inc/sitemap-xsl.php | 10 +++++----- modules/aioseop_performance.php | 4 ++-- 5 files changed, 14 insertions(+), 15 deletions(-) diff --git a/admin/display/dashboard_widget.php b/admin/display/dashboard_widget.php index 859b677b1..ca991666b 100644 --- a/admin/display/dashboard_widget.php +++ b/admin/display/dashboard_widget.php @@ -71,7 +71,7 @@ function display_rss_dashboard_widget() { $rss = fetch_feed( 'https://www.semperplugins.com/feed/' ); if ( is_wp_error( $rss ) ) { - echo '{Temporarily unable to load feed.}'; + echo __( '{Temporarily unable to load feed.}', 'all-in-one-seo-pack' ); return; } diff --git a/admin/display/general-metaboxes.php b/admin/display/general-metaboxes.php index a7b9d0942..7e9bc4e1d 100644 --- a/admin/display/general-metaboxes.php +++ b/admin/display/general-metaboxes.php @@ -188,7 +188,7 @@ static function pro_meta_content() { echo '
                      '; - echo 'Click here to file a feature request/bug report.'; + echo sprintf( __( '%1$sClick here%2$s to file a feature request/bug report.', 'all-in-one-seo-pack' ), '', '' ); } diff --git a/aioseop_class.php b/aioseop_class.php index eb8b8cf2b..4ccd34a9b 100644 --- a/aioseop_class.php +++ b/aioseop_class.php @@ -240,7 +240,7 @@ function __construct() { 'paged_format' => array( 'name' => __( 'Paged Format:', 'all-in-one-seo-pack' ), 'type' => 'text', - 'default' => ' - Part %page%', + 'default' => sprintf( ' - %s %%page%%', __( 'Part', 'all-in-one-seo-pack' ) ), 'condshow' => array( 'aiosp_rewrite_titles' => 1 ), ), 'cpostactive' => array( @@ -3668,11 +3668,10 @@ function wp_head() { $description = ''; // Logging - rewrite handler check for output buffering. $this->check_rewrite_handler(); - if ( AIOSEOPPRO ) { - echo "\n\n"; + + /* 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; @@ -3857,11 +3828,7 @@ function wp_head() { } } do_action( 'aioseop_modules_wp_head' ); - if ( AIOSEOPPRO ) { - echo "\n"; - } else { - echo "\n"; - } + echo sprintf( "\n", AIOSEOP_PLUGIN_NAME ); if ( ! empty( $old_wp_query ) ) { // Change the query back after we've finished. diff --git a/inc/aioseop_functions.php b/inc/aioseop_functions.php index cb6fb9e50..5e86947ef 100644 --- a/inc/aioseop_functions.php +++ b/inc/aioseop_functions.php @@ -583,8 +583,9 @@ function aioseop_ajax_scan_header() { } else { $meta = "" . $meta . '
                      Meta For SiteKind of MetaElement NameElement Value
                      '; $meta .= "

                      " . __( 'What Does This Mean?', 'all-in-one-seo-pack' ) . "

                      " - . '

                      ' . __( 'All in One SEO Pack has detected that a plugin(s) or theme is also outputting social meta tags on your site. You can view this social meta in the source code of your site (check your browser help for instructions on how to view source code).', 'all-in-one-seo-pack' ) - . '

                      ' . __( 'You may prefer to use the social meta tags that are being output by the other plugin(s) or theme. If so, then you should deactivate this Social Meta feature in All in One SEO Pack Feature Manager.', 'all-in-one-seo-pack' ) + /* translators: %s is a placeholder, which means that it should not be translated. It will be replaced with the name of the plugin, All in One SEO Pack. */ + . '

                      ' . sprintf( __( '%s has detected that a plugin(s) or theme is also outputting social meta tags on your site. You can view this social meta in the source code of your site (check your browser help for instructions on how to view source code).', 'all-in-one-seo-pack' ), AIOSEOP_PLUGIN_NAME ) + . '

                      ' . __( 'You may prefer to use the social meta tags that are being output by the other plugin(s) or theme. If so, then you should deactivate this Social Meta feature in the Feature Manager.', 'all-in-one-seo-pack' ) . '

                      ' . __( 'You should avoid duplicate social meta tags. You can use these free tools from Facebook and Twitter to validate your social meta and check for errors:', 'all-in-one-seo-pack' ) . '

                      '; foreach ( @@ -844,7 +845,7 @@ function aioseop_add_contactmethods( $contactmethods ) { if ( ( $m !== false ) && is_object( $m ) ) { if ( $m->option_isset( 'twitter_creator' ) || $m->option_isset( 'facebook_author' ) ) { - $contactmethods['aioseop_edit_profile_header'] = 'All in One SEO Pack'; + $contactmethods['aioseop_edit_profile_header'] = AIOSEOP_PLUGIN_NAME; } if ( $m->option_isset( 'twitter_creator' ) ) { diff --git a/inc/commonstrings.php b/inc/commonstrings.php index 2b39d7667..9d411e64c 100644 --- a/inc/commonstrings.php +++ b/inc/commonstrings.php @@ -33,12 +33,16 @@ private function __construct() { __( 'Manage Licenses', 'all-in-one-seo-pack' ); // These are Pro option strings. + /* translators: %s is a placeholder, which means that it should not be translated. It will be replaced with the name of the plugin, All in One SEO Pack. */ + sprintf( __( 'Use these checkboxes to select which Taxonomies you want to use %s with.', 'all-in-one-seo-pack' ), AIOSEOP_PLUGIN_NAME ); __( 'Show SEO News', 'all-in-one-seo-pack' ); __( 'Display Menu In Admin Bar:', 'all-in-one-seo-pack' ); __( 'Display Menu At The Top:', 'all-in-one-seo-pack' ); __( 'This displays an SEO News widget on the dashboard.', 'all-in-one-seo-pack' ); - __( 'Check this to add All in One SEO Pack to the Admin Bar for easy access to your SEO settings.', 'all-in-one-seo-pack' ); - __( 'Check this to move the All in One SEO Pack menu item to the top of your WordPress Dashboard menu.', 'all-in-one-seo-pack' ); + /* translators: %s is a placeholder, which means that it should not be translated. It will be replaced with the name of the plugin, All in One SEO Pack. */ + sprintf( __( 'Check this to add %s to the Admin Bar for easy access to your SEO settings.', 'all-in-one-seo-pack' ), AIOSEOP_PLUGIN_NAME ); + /* translators: %s is a placeholder, which means that it should not be translated. It will be replaced with the name of the plugin, All in One SEO Pack. */ + sprintf( __( 'Check this to move the %s menu item to the top of your WordPress Dashboard menu.', 'all-in-one-seo-pack' ), AIOSEOP_PLUGIN_NAME ); __( '%s is almost ready.', 'all-in-one-seo-pack' ); __( 'You must enter a valid License Key for it to work.', 'all-in-one-seo-pack' ); __( "There is a new version of %1\$s available. Go to the plugins page for details.", 'all-in-one-seo-pack' ); diff --git a/modules/aioseop_feature_manager.php b/modules/aioseop_feature_manager.php index 8f7d7b513..fad1ad29e 100644 --- a/modules/aioseop_feature_manager.php +++ b/modules/aioseop_feature_manager.php @@ -54,7 +54,8 @@ function __construct( $mod ) { /* translators: the Importer & Exporter module allows users to import/export their All in One SEO Pack settings for backup purposes or when migrating their site. */ 'name' => __( 'Importer & Exporter', 'all-in-one-seo-pack' ), - 'description' => __( 'Exports and imports your All in One SEO Pack plugin settings.', 'all-in-one-seo-pack' ), + /* translators: %s is a placeholder, which means that it should not be translated. It will be replaced with the name of the plugin, All in One SEO Pack. */ + 'description' => sprintf( __( 'Exports and imports your %s plugin settings.', 'all-in-one-seo-pack' ), AIOSEOP_PLUGIN_NAME ), ), 'bad_robots' => array( /* translators: the Bad Bot Blocker module allows users to block requests from user agents that are known to misbehave. */ diff --git a/modules/aioseop_importer_exporter.php b/modules/aioseop_importer_exporter.php index 534218ec6..168dd520b 100644 --- a/modules/aioseop_importer_exporter.php +++ b/modules/aioseop_importer_exporter.php @@ -496,9 +496,13 @@ function do_importer_exporter() { case 'Export': // Creates Files Contents $settings_file = 'settings_aioseop.ini'; - $buf = '; ' . __( - 'Settings export file for All in One SEO Pack', ' + /* translators: %s is a placeholder, which means that it should not be translated. It will be replaced with the name of the plugin, All in One SEO Pack. */ + $buf = '; ' . sprintf( + __( + 'Settings export file for %s', ' all-in-one-seo-pack' + ), + AIOSEOP_PLUGIN_NAME ) . "\n"; // Adds all settings to settings file diff --git a/modules/aioseop_performance.php b/modules/aioseop_performance.php index 699d695bf..1715b93a2 100644 --- a/modules/aioseop_performance.php +++ b/modules/aioseop_performance.php @@ -265,7 +265,8 @@ function get_serverinfo() { $debug_info[ __( 'Inactive Plugins', 'all-in-one-seo-pack' ) ] = null; $debug_info = array_merge( $debug_info, (array) $inactive_plugins ); - $mail_text = __( 'All in One SEO Pack Pro Debug Info', 'all-in-one-seo-pack' ) . "\r\n------------------\r\n\r\n"; + /* translators: %s is a placeholder, which means that it should not be translated. It will be replaced with the name of the premium version of the plugin, All in One SEO Pack Pro. */ + $mail_text = sprintf( __( '%s Debug Info', 'all-in-one-seo-pack' ), 'All in One SEO Pack Pro' ) . "\r\n------------------\r\n\r\n"; $page_text = ''; if ( ! empty( $debug_info ) ) { foreach ( $debug_info as $name => $value ) { @@ -301,8 +302,11 @@ function get_serverinfo() { if ( $file_handle = @fopen( $file_path, 'w' ) ) { // @codingStandardsIgnoreEnd global $aiosp; - $buf = '; ' . __( - 'Settings export file for All in One SEO Pack', 'all-in-one-seo-pack' + /* translators: %s is a placeholder, which means that it should not be translated. It will be replaced with the name of the plugin, All in One SEO Pack. */ + $buf = '; ' . sprintf( + __( + 'Settings export file for %s', 'all-in-one-seo-pack' + ), AIOSEOP_PLUGIN_NAME ) . "\n"; // Adds all settings and posts data to settings file diff --git a/modules/aioseop_sitemap.php b/modules/aioseop_sitemap.php index b13922212..b98b023a0 100644 --- a/modules/aioseop_sitemap.php +++ b/modules/aioseop_sitemap.php @@ -1324,9 +1324,11 @@ public function get_problem_files( $files, &$msg ) { $matches ) ) { if ( ! empty( $this->options[ "{$this->prefix}rewrite" ] ) ) { + /* translators: %1$s, %2$s, etc. are placeholders and should not be translated. %1$s expands to the name of a sitemap file, %2$s to the name of the plugin, All in One SEO Pack, %3$s is replaced with the plugin version number and %4$s with a date. */ $msg .= '

                      ' . sprintf( - __( "Warning: a static sitemap '%1\$s' generated by All in One SEO Pack %2\$s on %3\$s already exists that may conflict with dynamic sitemap generation.", 'all-in-one-seo-pack' ), + __( "Warning: a static sitemap '%1\$s' generated by %2\$s %3\$s on %4\$s already exists that may conflict with dynamic sitemap generation.", 'all-in-one-seo-pack' ), $f, + AIOSEOP_PLUGIN_NAME, $matches[2], $matches[3] ) . "

                      \n"; From e630cdd30cab1179ee7ab03ef316335d6d95c058 Mon Sep 17 00:00:00 2001 From: Michael Torbert Date: Wed, 29 May 2019 08:35:04 -0400 Subject: [PATCH 107/121] replace sitemap url in robotstxt option with filter hook (#2520) * replace sitemap url in robotstxt option with filter hook #535 * Correct phpDoc syntax #535 --- modules/aioseop_sitemap.php | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/modules/aioseop_sitemap.php b/modules/aioseop_sitemap.php index b98b023a0..28e8acb9c 100644 --- a/modules/aioseop_sitemap.php +++ b/modules/aioseop_sitemap.php @@ -207,10 +207,6 @@ public function __construct() { 'archive' => array( 'name' => __( 'Include Date Archive Pages', 'all-in-one-seo-pack' ) ), 'author' => array( 'name' => __( 'Include Author Pages', 'all-in-one-seo-pack' ) ), 'images' => array( 'name' => __( 'Exclude Images', 'all-in-one-seo-pack' ) ), - 'robots' => array( - 'name' => __( 'Link From Virtual Robots.txt', 'all-in-one-seo-pack' ), - 'default' => 'On', - ), 'rewrite' => array( 'name' => __( 'Dynamically Generate Sitemap', 'all-in-one-seo-pack' ), 'default' => 'On', @@ -623,7 +619,16 @@ public function load_sitemap_options() { $this->setup_rewrites(); } - if ( $this->option_isset( 'robots' ) ) { + /** + * Filters whether to display the URL to the XML Sitemap on our virtual robots.txt file. + * + * Defaults to true. Return __return_false in order to not display the URL. + * + * @since 3.0 + * + * @param boolean Defaults to true. + */ + if ( apply_filters( 'aioseop_robotstxt_sitemap_url', true ) ) { add_action( 'do_robots', array( $this, 'do_robots' ), 100 ); } From f883c6d0fea92bf635f8eab77bbd3d3dc52558ca Mon Sep 17 00:00:00 2001 From: Arnaud Broes Date: Wed, 29 May 2019 15:45:40 +0200 Subject: [PATCH 108/121] Fix meta box help icon alignment (#2484) * Fix meta box help icon alignment #1956 * Fix alignment for RTL languages #1956 --- css/modules/aioseop_module-rtl.css | 1 - css/modules/aioseop_module.css | 2951 ++++++++++++++-------------- 2 files changed, 1475 insertions(+), 1477 deletions(-) diff --git a/css/modules/aioseop_module-rtl.css b/css/modules/aioseop_module-rtl.css index 941da6523..8c0bc0d97 100644 --- a/css/modules/aioseop_module-rtl.css +++ b/css/modules/aioseop_module-rtl.css @@ -35,7 +35,6 @@ float: left; padding-left: 0; margin-right: 0; - margin-left: 64px } .aioseop_label { diff --git a/css/modules/aioseop_module.css b/css/modules/aioseop_module.css index d03aa6cec..a4757a29c 100644 --- a/css/modules/aioseop_module.css +++ b/css/modules/aioseop_module.css @@ -1,1476 +1,1475 @@ -/** - * Controls all the styling of the plugin. - * - * @author Michael Torbert. - * @author Semper Fi Web Design. - * @copyright http://semperplugins.com - * @package All-in-One-SEO-Pack. - */ - -.form-table.aioseop { - clear: none; -} - -.form-table.aioseop td { - vertical-align: top; - padding: 16px 0 10px 0; - line-height: 20px; - font-size: 12px; -} - -.form-table.aioseop th { - width: 200px; - padding: 10px 0 12px 9px; -} - -.aioseop_help_text_link, -.aioseop_help_text_link:active { - text-align: left; - float: left; - max-width: 30px; - min-width: 20px; - padding-top: 2px; - outline: none; - color: #888; - font-family: sans-serif; - line-height: 1.4em; -} - -.aioseop_help_text_link span { - font-size: 14px; -} - -.aioseop_help_text_link:before { - content: "\f223"; - font-size: 27px; - font-family: dashicons; - vertical-align: middle; -} - -#aioseop-support .aioseop_metabox_text, -#aioseop-support a { - font-size: 14px; - color: #000; - text-decoration: none; -} - -.aioseop_meta_box_help > label { - position: absolute; - margin-left: 8px; -} - -.aioseop_help_text_link img { - width: 40px; - float: left; -} - -.aioseop_meta_box_help, -.aioseop_meta_box_help:active { - float: right; - text-align: right; - min-width: 56px; - max-width: 90px; - text-decoration: none; - height: 15px; - padding-top: 1px; - position: relative; -} - -.aioseop_meta_box_help span { - vertical-align: middle; -} - -.aioseop_tabs .aioseop_meta_box_help, -.aioseop_tabs .aioseop_meta_box_help:active { - margin-top: 4px; - margin-right: 45px; -} - -.aioseop_label { - color: #5F5F5F; - font-weight: bold; - line-height: 19px; - display: inline-block; - float: left; - text-align: left; - font-family: 'Open Sans', sans-serif; - padding: 2px 0; - width: 81%; - min-width: 120px; - max-width: 250px; - cursor: default; -} - -.aioseop_option_div { - max-height: 360px; - min-height: 37px; - width: 95%; - overflow-y: auto; -} - -.aioseop_overflowed { - border: 1px solid #e1e1e1; -} - -.aioseop input[type="text"], .aioseop input[type="url"] { - color: #515151; - min-height: 35px; - padding: 10px 0 10px 10px; - font-size: 14px; - width: 95%; - max-width: 600px; -} - -.aioseop textarea { - color: #515151; - padding: 10px 0 0 10px; - margin: 0; - font-size: 14px; - line-height: 25px; - width: 95%; - max-width: 600px; - min-height: 36px; -} - -.aioseop_help_text_div { - text-align: left; - width: 100%; - margin: 0; -} - -.aioseop_help_text { - font-size: 12px; - float: left; - clear: left; - color: #797979; - line-height: 15px; - font-style: italic; -} - -.aioseop_head_tagline { - color: #5F5F5F; - font-size: 13px; -} - -.aioseop_head_nav { - float: left; - font-size: 18px; - margin: 0 0 16px 0; - font-family: "HelveticaNeue-Light", - "Helvetica Neue Light", - "Helvetica Neue", - sans-serif; - border-bottom: 1px solid #CCC; - width: 100%; -} - -.aioseop_head_nav_tab { - padding: 10px 15px 10px 15px; - margin: 0 0 0 15px; - border-radius: 4px 4px 0 0; - border: 1px solid #CCC; - border-bottom: 0 white; - float: left; - opacity: 0.5; - color: black; - text-shadow: white 0 1px 0; - text-decoration: none; -} - -.aioseop_head_nav_tab.aioseop_head_nav_active { - opacity: 1; - margin-bottom: -1px; - border-width: 1px; -} - -.aioseop_head_nav_tab:first-child { - margin-left: 0; -} - -.aioseop_head_nav_tab:hover { - opacity: 1; -} - -.aioseop_header { - float: left; - clear: left; -} - -.aioseop_advert { - padding: 10px; - margin-bottom: 30px; - border: 1px solid #DDD; - height: 200px; - width: 423px; -} - -.aioseop_nopad { - padding-left: 0; - padding-top: 0; -} - -.aioseop_nopad_all { - padding: 0; - height: 220px; - width: 445px; - margin-bottom: 20px; - border: none; -} - -.aioseop_adverts { - float: right; -} - -.wincherad { - width: 100%; - height: 100%; - background-size: 100%; - background-repeat: no-repeat; - margin-bottom: 0; - border: none; -} - -#wincher21 { - background-image: url(../../modules/images/banner21.jpg); -} - -#wincher22 { - background-image: url(../../modules/images/banner22.jpg); -} - -.aioseop_content { - min-width: 760px; - clear: left; -} - -.aioseop_options_wrapper .hndle { - font-size: 15px; - font-family: Georgia, - "Times New Roman", - "Bitstream Charter", - Times, - serif; - font-weight: normal; - min-height: 18px; - padding: 7px 10px; - margin: 0; - line-height: 1; -} - -.aioseop_options_wrapper .submit input.button-primary { - margin-bottom: 5px; -} - -#aiosp_feature_manager_metabox.postbox { - margin-top: 20px; - float: left; -} - -.aioseop_advert p { - margin: 25px 0 25px 0; -} - -.aioseop_options_wrapper .postarea { - border-color: #DFDFDF; - -moz-box-shadow: inset 0 1px 0 #fff; - -webkit-box-shadow: inset 0 1px 0 #fff; - box-shadow: inset 0 1px 0 #fff; - -moz-border-radius: 3px; - -webkit-border-radius: 3px; - border-radius: 3px; -} - -.aioseop_advert h3 { - padding: 0; - margin-top: 6px; -} - -.aioseop_metabox_text p { - margin: 0 0 0 0; - width: 101%; -} - -.aioseop_sidebar { - width: 457px; - margin-left: 10px; -} - -.aioseop_metabox_text { - margin-bottom: 0; -} - -.aioseop_metabox_wrapper { - padding: 0; -} - -.aioseop_metabox_text *:last-child { - margin: 0; -} - -.aioseop_metabox_feature { - margin-top: 20px; -} - -.aioseop_translations { - margin-top: 15px; -} - -.aioseop_option_label { - float: left; - margin: 0; - padding-top: 3px; - padding-bottom: 3px; - width: 37%; - min-width: 150px; - max-width: 360px; - min-height: 30px; -} - -.aioseop_metabox_text h2 { - font-size: 14px; - padding: 0; - font-weight: bold; - line-height: 29px; -} - -#aioseop-about { - width: 443px; - margin-bottom: 20px; -} - -#aioseop-about .aioseop_metabox_text #mc-embedded-subscribe-form h2 { - font-size: 13px; -} - -.aioseop_sidebar #mc-embedded-subscribe-form { - margin: 0 0 10px 0; - background: white; - padding: 10px 10px; - border: 1px solid #DDD; -} - -#aioseop-about .aioseop_metabox_text ul { - list-style-type: disc; - padding-left: 15px; -} - -.aioseop input[readonly] { - background-color: #EEE; - margin: 5px 0 5px 0 !important; -} - -.aioseop_settings_left { - float: left; - padding: 0; - margin: 0; - width: 100%; -} - -body.all-in-one-seo_page_all-in-one-seo-pack-aioseop_feature_manager .aioseop_settings_left { - margin-top: 20px; -} - -body.all-in-one-seo_page_all-in-one-seo-pack-pro-aioseop_feature_manager .aioseop_settings_left { - margin-top: 20px; -} - -#aioseop_top_button { - margin-top: 5px; - height: 30px; -} - -#aioseop-list #mce-EMAIL { - margin-top: 5px; - width: 250px; -} - -.aioseop_top { - margin: 10px 10px 0 0; - /* margin: 10px 477px 0px 0px; */ -} - -.aioseop_top #aioseop-list { - margin-bottom: 0; -} - -.aioseop_top #aioseop-list.postbox.closed { - overflow: hidden; -} - -.aioseop_right_sidebar { - float: right; - margin-top: 35px; -} - -#aiosp_settings_form .button-primary.hidden { - display: none; -} - -form#edittag div#aiosp_titleatr_wrapper, -form#edittag div#aiosp_menulabel_wrapper, -form#edittag div#aiosp_sitemap_exclude_wrapper { - display: none; -} - -.All_in_One_SEO_Pack_Feature_Manager > #aiosp_settings_form > #aioseop_top_button { - height: 5px; - position: absolute; - top: 0; - width: 97%; -} - -.All_in_One_SEO_Pack_Feature_Manager > #aiosp_settings_form > .aioseop_settings_left { - margin-top: 10px; -} - -.All_in_One_SEO_Pack_Feature_Manager > .aioseop_right_sidebar.aioseop_options_wrapper { - margin-top: 10px; -} - -div#aiosp_feature_manager_metabox .inside { - padding: 8px; -} - -div.aioseop_feature { - position: relative; - display: inline-block; - float: left; - vertical-align: top; - width: 240px; - height: 288px; - margin: 8px; - border: 1px solid #DEDEDE; - -moz-border-radius: 3px; - -webkit-border-radius: 3px; - border-radius: 3px; - background: white; - padding: 10px 0 0; - -webkit-box-shadow: inset 0 1px 0 #fff, - inset 0 0 20px rgba(0, 0, 0, 0.05), - 0 1px 2px rgba(0, 0, 0, 0.1); - -moz-box-shadow: inset 0 1px 0 #fff, - inset 0 0 20px rgba(0, 0, 0, 0.05), - 0 1px 2px rgba(0, 0, 0, 0.1); - box-shadow: inset 0 1px 0 #fff, - inset 0 0 20px rgba(0, 0, 0, 0.05), - 0 1px 2px rgba(0, 0, 0, 0.1); - -webkit-transition-duration: .4s; - -moz-transition-duration: .4s; -} - -.aioseop_feature .flag { - float: right; - margin-right: -7px; - background: none repeat scroll 0 0 #D23D46; - color: #FFFFFF; - padding: 5px 12px 6px 5px; - position: relative; -} - -.aioseop_feature .flag:before { - border-color: #D23D46 #D23D46 #D23D46 transparent; - border-style: solid; - border-width: 14px 4px 15px 10px; - content: ""; - left: -14px; - position: absolute; - top: 0; -} - -.aioseop_feature .flag:after { - border-color: #892026 transparent transparent; - border-style: solid; - border-width: 6px 6px 6px 0; - bottom: -12px; - content: ""; - position: absolute; - right: 0; -} - -.aioseop_feature .flag.pro { - display: none; -} - -#aioseop_coming_soon .free.flag, -.all-in-one-seo_page_all-in-one-seo-pack-pro-modules-aioseop_feature_manager .aioseop_feature .free.flag { - display: none; -} - -#aioseop_coming_soon .flag.pro { - display: block; - margin-top: -30px; -} - -.all-in-one-seo_page_all-in-one-seo-pack-pro-modules-aioseop_feature_manager #aioseop_coming_soon .flag.pro { - display: none; -} - -.aioseop_feature h3 { - font-size: 17px; - margin: 0; - padding: 0 10px 5px 10px; - font-weight: normal; - font-style: normal; - font-family: "Helvetica Neue", - Helvetica, - Arial, - "Lucida Grande", - Verdana, - "Bitstream Vera Sans", - sans-serif; -} - -.aioseop_feature p { - line-height: 150%; - font-size: 12px; - font-family: Georgia, - "Times New Roman", - "Bitstream Charter", - Times, serif; - margin-bottom: 20px; - color: #666; - padding: 0 10px; -} - -.aioseop_feature p.aioseop_desc { - min-height: 80px; -} - -.aioseop_feature .feature_button { - float: right; - margin-bottom: 10px; - margin-right: 10px; - min-width: 80px; - text-align: center; -} - -.aioseop_feature .feature_button:before { - content: "Activate"; -} - -.aioseop_feature .active.feature_button:before { - content: "Deactivate"; -} - -div.aioseop_feature .aioseop_featured_image { - min-height: 100px; - background-repeat: no-repeat; - display: block; - margin: 0 auto; - width: 133px; -} - -div.aioseop_feature .aioseop_featured_image { - background-image: url(../../modules/images/Default-BW-Standard.png); -} - -div.aioseop_feature .aioseop_featured_image.active { - background-image: url(../../modules/images/Default-Color-Standard.png); -} - -div.aioseop_feature#aioseop_sitemap .aioseop_featured_image { - background-image: url(../../modules/images/XMLSitemaps-BW-Standard.png); -} - -div.aioseop_feature#aioseop_sitemap .aioseop_featured_image.active { - background-image: url(../../modules/images/XMLSitemaps-Color-Standard.png); -} - -div.aioseop_feature#aioseop_video_sitemap .aioseop_featured_image { - background-image: url(../../modules/images/VideoSitemap-BW-Standard.png); -} - -div.aioseop_feature#aioseop_video_sitemap .aioseop_featured_image.active { - background-image: url(../../modules/images/VideoSitemap-Color-Standard.png); -} - -div.aioseop_feature#aioseop_opengraph .aioseop_featured_image { - background-image: url(../../modules/images/SocialMeta-BW-Standard.png); -} - -div.aioseop_feature#aioseop_opengraph .aioseop_featured_image.active { - background-image: url(../../modules/images/SocialMeta-Color-Standard.png); -} - -div.aioseop_feature#aioseop_robots .aioseop_featured_image, div.aioseop_feature#aioseop_bad_robots .aioseop_featured_image { - background-image: url(../../modules/images/Robots-BW-Standard.png); -} - -div.aioseop_feature#aioseop_robots .aioseop_featured_image.active, div.aioseop_feature#aioseop_bad_robots .aioseop_featured_image.active { - background-image: url(../../modules/images/Robots-Color-Standard.png); -} - -div.aioseop_feature#aioseop_file_editor .aioseop_featured_image { - background-image: url(../../modules/images/FileEditor-BW-Standard.png); -} - -div.aioseop_feature#aioseop_file_editor .aioseop_featured_image.active { - background-image: url(../../modules/images/FileEditor-Color-Standard.png); -} - -div.aioseop_feature#aioseop_importer_exporter .aioseop_featured_image { - background-image: url(../../modules/images/ImporterExporter-BW-Standard.png); -} - -div.aioseop_feature#aioseop_importer_exporter .aioseop_featured_image.active { - background-image: url(../../modules/images/ImporterExporter-Color-Standard.png); -} - -div.aioseop_feature#aioseop_performance .aioseop_featured_image { - background-image: url(../../modules/images/Performance-BW-Standard.png); -} - -div.aioseop_feature#aioseop_performance .aioseop_featured_image.active { - background-image: url(../../modules/images/Performance-Color-Standard.png); -} - -div.aioseop_feature#aioseop_coming_soon .aioseop_featured_image { - background-image: url(../../modules/images/Default-Color-Standard.png); -} - -div.aioseop_feature#aioseop_coming_soon2 .aioseop_featured_image { - background-image: url(../../modules/images/Default-Color-Standard.png); -} - -.All_in_One_SEO_Pack_Sitemap > form > .wrap > .form-table, -.All_in_One_SEO_Pack_Video_Sitemap > form > .wrap > .form-table { - max-width: 500px; - clear: none; -} - -.aioseop_follow_button { - min-height: 50px; - background-repeat: no-repeat; - display: inline-block; - width: 100px; - background-size: auto 50px !important; - margin-right: 0; -} - -.aioseop_facebook_follow { - background-image: url(../../modules/images/facebook-follow-standard.png); -} - -.aioseop_twitter_follow { - background-image: url(../../modules/images/twitter-follow-standard.png); -} - -@media only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and ( min--moz-device-pixel-ratio: 1.5), only screen and ( -o-min-device-pixel-ratio: 3/2), only screen and ( min-device-pixel-ratio: 1.5), only screen and ( min-resolution: 1.5dppx) { - div.aioseop_feature .aioseop_featured_image { - background-size: auto 100px !important; - } - - div.aioseop_feature .aioseop_featured_image.active { - background-image: url(../../modules/images/Default-Color-Retina.png); - } - - div.aioseop_feature .aioseop_featured_image { - background-image: url(../../modules/images/Default-BW-Retina.png); - } - - div.aioseop_feature#aioseop_sitemap .aioseop_featured_image { - background-image: url(../../modules/images/XMLSitemaps-BW-Retina.png); - } - - div.aioseop_feature#aioseop_sitemap .aioseop_featured_image.active { - background-image: url(../../modules/images/XMLSitemaps-Color-Retina.png); - } - - div.aioseop_feature#aioseop_video_sitemap .aioseop_featured_image { - background-image: url(../../modules/images/VideoSitemap-BW-Retina.png); - } - - div.aioseop_feature#aioseop_video_sitemap .aioseop_featured_image.active { - background-image: url(../../modules/images/VideoSitemap-Color-Retina.png); - } - - div.aioseop_feature#aioseop_opengraph .aioseop_featured_image { - background-image: url(../../modules/images/SocialMeta-BW-Retina.png); - } - - div.aioseop_feature#aioseop_opengraph .aioseop_featured_image.active { - background-image: url(../../modules/images/SocialMeta-Color-Retina.png); - } - - div.aioseop_feature#aioseop_robots .aioseop_featured_image, div.aioseop_feature#aioseop_bad_robots .aioseop_featured_image { - background-image: url(../../modules/images/Robots-BW-Retina.png); - } - - div.aioseop_feature#aioseop_robots .aioseop_featured_image.active, div.aioseop_feature#aioseop_bad_robots .aioseop_featured_image.active { - background-image: url(../../modules/images/Robots-Color-Retina.png); - } - - div.aioseop_feature#aioseop_file_editor .aioseop_featured_image { - background-image: url(../../modules/images/FileEditor-BW-Retina.png); - } - - div.aioseop_feature#aioseop_file_editor .aioseop_featured_image.active { - background-image: url(../../modules/images/FileEditor-Color-Retina.png); - } - - div.aioseop_feature#aioseop_importer_exporter .aioseop_featured_image { - background-image: url(../../modules/images/ImporterExporter-BW-Retina.png); - } - - div.aioseop_feature#aioseop_importer_exporter .aioseop_featured_image.active { - background-image: url(../../modules/images/ImporterExporter-Color-Retina.png); - } - - div.aioseop_feature#aioseop_performance .aioseop_featured_image { - background-image: url(../../modules/images/Performance-BW-Retina.png); - } - - div.aioseop_feature#aioseop_performance .aioseop_featured_image.active { - background-image: url(../../modules/images/Performance-Color-Retina.png); - } - - div.aioseop_feature#aioseop_coming_soon .aioseop_featured_image { - background-image: url(../../modules/images/Default-BW-Retina.png); - } - - div.aioseop_feature#aioseop_coming_soon2 .aioseop_featured_image { - background-image: url(../../modules/images/Default-BW-Retina.png); - } - - .aioseop_facebook_follow { - background-image: url(../../modules/images/facebook-follow-retina.png); - } - - .aioseop_twitter_follow { - background-image: url(../../modules/images/twitter-follow-retina.png); - } -} - -.aioseop_options { - width: 100%; - margin: 18px 0 10px 0; -} - -.aioseop_wrapper { - width: 100%; - padding-left: 5px; -} - -.aioseop_input { - clear: left; - width: 98%; - padding: 5px 1%; - display: inline-block; -} - -.aioseop_option_input { - float: left; - width: 61%; - margin: 0; - padding-left: 1px; - min-width: 160px; - /* max-width: 900px; */ -} - -/*** Sitemap Additional Pages section ***/ -#aiosp_sitemap_addl_pages_metabox .aioseop_options, -#aiosp_video_sitemap_addl_pages_metabox .aioseop_options { - width: 97%; - margin: 5px; -} - -#aiosp_sitemap_addl_pages_metabox .aioseop_wrapper#aiosp_sitemap_addl_instructions_wrapper, -#aiosp_video_sitemap_addl_pages_metabox .aioseop_wrapper#aiosp_video_sitemap_addl_instructions_wrapper { - display: block; - width: 100%; - float: none; - margin: 0; -} - -#aiosp_sitemap_addl_pages_metabox .aioseop_wrapper#aiosp_sitemap_addl_instructions_wrapper .aioseop_input, -#aiosp_video_sitemap_addl_pages_metabox .aioseop_wrapper#aiosp_video_sitemap_addl_instructions_wrapper .aioseop_input { - display: block; - width: 100%; -} - -#aiosp_sitemap_addl_pages_metabox .aioseop_wrapper, -#aiosp_video_sitemap_addl_pages_metabox .aioseop_wrapper { - padding: 0; -} - -#aiosp_sitemap_addl_pages_metabox .aioseop_wrapper .aioseop_input, -#aiosp_video_sitemap_addl_pages_metabox .aioseop_wrapper .aioseop_input { - display: inline-block; - vertical-align: middle; - width: 25%; - min-width: 120px; - height: 70px; -} - -#aiosp_sitemap_addl_pages_metabox .aioseop_wrapper .aioseop_top_label, -#aiosp_video_sitemap_addl_pages_metabox .aioseop_wrapper .aioseop_top_label { - width: 70%; - margin: 0; -} - -#aiosp_sitemap_addl_pages_metabox .aioseop_wrapper .aioseop_option_label, -#aiosp_video_sitemap_addl_pages_metabox .aioseop_wrapper .aioseop_option_label { - height: 30px !important; -} - -#aiosp_sitemap_addl_pages_metabox .aioseop_wrapper#aiosp_sitemap_addl_mod_wrapper input.aiseop-date, -#aiosp_video_sitemap_addl_pages_metabox .aioseop_wrapper#aiosp_video_sitemap_addl_mod_wrapper input.aiseop-date { - height: 36px; -} - -#aiosp_sitemap_addl_pages_metabox .aioseop_options .aioseop_submit_type, -#aiosp_video_sitemap_addl_pages_metabox .aioseop_options .aioseop_submit_type { - margin: 0; -} - -#aiosp_sitemap_addl_pages_metabox .aioseop_options .aioseop_submit_type input.button-primary, -#aiosp_video_sitemap_addl_pages_metabox .aioseop_options .aioseop_submit_type input.button-primary { - margin-left: 0 !important; -} - -#aiosp_sitemap_addl_pages_metabox .aioseop_help_text_div, -#aiosp_video_sitemap_addl_pages_metabox .aioseop_help_text_div { - position: absolute; - width: auto; - margin: 5px 0 10px 0; -} - -#aiosp_sitemap_addl_pages_metabox table.aioseop_table, -#aiosp_video_sitemap_addl_pages_metabox table.aioseop_table { - width: 96%; - border: 1px solid #CCC; - margin: 5px 5px 10px; -} - -/*** Sitemap Exclude Items section ***/ -.selectize-control.aioseop-exclude-terms { - position: static; - width: 95%; - max-width: 600px; -} - -table.aioseop_table tr:nth-child(odd) { - background-color: #EEE; -} - -.All_in_One_SEO_Pack_Opengraph table.aioseop_table tr:nth-child(odd) { - background-color: rgba(238, 238, 238, 0.5); -} - -table.aioseop_table td { - width: 23%; -} - -.All_in_One_SEO_Pack_Opengraph table.aioseop_table { - width: 80%; - max-width: 800px; - display: block; - border-top: 1px solid #dfdfdf; - border-left: 1px solid #dfdfdf; -} - -.All_in_One_SEO_Pack_Opengraph table.aioseop_table th { - width: 18%; - border-right: 1px solid #dfdfdf; - border-bottom: 1px solid #dfdfdf; -} - -.All_in_One_SEO_Pack_Opengraph div.aioseop_meta_info { - margin-top: 10px; - border: 1px solid #dfdfdf; - width: 80%; - max-width: 800px; -} - -.All_in_One_SEO_Pack_Opengraph table.aioseop_table tr.aioseop_table_header th { - background: #f1f1f1; - background-image: -webkit-gradient(linear, left bottom, left top, from(#ececec), to(#f9f9f9)); - background-image: -webkit-linear-gradient(bottom, #ececec, #f9f9f9); - background-image: -moz-linear-gradient(bottom, #ececec, #f9f9f9); - background-image: -o-linear-gradient(bottom, #ececec, #f9f9f9); - background-image: linear-gradient(to top, #ececec, #f9f9f9); - padding: 5px; - border-bottom-color: #dfdfdf; - text-shadow: #fff 0 1px 0; - -webkit-box-shadow: 0 1px 0 #fff; - -moz-box-shadow: 0 1px 0 #fff; - box-shadow: 0 1px 0 #fff; -} - -.All_in_One_SEO_Pack_Opengraph table.aioseop_table td { - border-right: 1px solid #dfdfdf; - border-bottom: 1px solid #dfdfdf; -} - -#aioseop_opengraph_settings_facebook_debug_result li.aioseop_opengraph_settings_facebook_debug_item { - display: inline-block; - width: 30%; - vertical-align: top; -} - -#aioseop_opengraph_settings_facebook_debug_result li.aioseop_opengraph_settings_facebook_debug_item:nth-child(even) { - font-weight: bold; -} - -#aioseop_opengraph_settings_facebook_debug_result li.aioseop_opengraph_settings_facebook_debug_item:nth-child(odd) { - width: 70%; -} - -#aiosp_sitemap_addl_pages_metabox table.aioseop_table td, -#aiosp_video_sitemap_addl_pages_metabox table.aioseop_table td { - width: 27%; - padding-left: 5%; -} - -#aiosp_sitemap_addl_pages_metabox table.aioseop_table td:first-child, -#aiosp_video_sitemap_addl_pages_metabox table.aioseop_table td:first-child { - padding-left: 2%; -} - -table.aioseop_table td, table.aioseop_table th { - padding: 3px; -} - -.aioseop_top_label .aioseop_option_input, -.aioseop_no_label .aioseop_option_input { - width: 100%; -} - -#aiosp_settings_form .postbox { - margin: 0 0 20px 0; -} - -.aioseop_settings_left .postbox { - float: left; - width: 100%; -} - -.aioseop_option_setting_label { - min-height: 35px; - display: inline-block; - white-space: nowrap; - overflow: hidden; - padding-left: 1px; - max-width: 229px; - min-width: 160px; - width: 33%; -} - -.aioseop_settings_left .postbox .inside { - padding: 0; - margin: 0; - clear: right; -} - -#aiosp_robots_rules { - clear: left; - margin-left: 20px; - max-width: 1072px; -} - -#aiosp_robots_default_metabox .aioseop_wrapper { - width: 31%; - min-width: 165px; - display: inline-block; - max-width: 265px; -} - -#aiosp_robots_default_metabox .aioseop_help_text_div { - position: absolute; - margin: 5px 0 10px 0; -} - -#aiosp_robots_default_metabox .aioseop_option_input { - width: 94%; - min-width: 94%; -} - -#aiosp_robots_default_metabox table.aioseop_table { - width: 96%; - border: 1px solid #CCC; - margin: 5px 0 10px 0; -} - -#aiosp_robots_default_metabox table.aioseop_table td { - width: 25%; - padding-left: 5%; -} - -#aiosp_settings_form .aioseop_no_label, .aioseop_no_label { - float: left; - width: 92%; - max-width: 100%; - margin: 0 23px 0 13px; -} - -#aiosp_sitemap_status_metabox .handlediv.button-link { - display: none; -} - -#aiosp_sitemap_status_metabox.closed .inside { - display: block; -} - -.aioseop_top_label { - width: 96%; - margin: 0 10px; -} - -.aioseop_hidden_type { - margin: 0; - padding: 0; - height: 0; -} - -#aiosp_title_metabox #aiosp_force_rewrites_wrapper { - display: none; - height: 0; -} - -.aioseop_module.error.below-h2 { - padding: 5px 0; - margin: 0 477px 15px 0 !important; -} - -#aioseop_opengraph_settings .inside { - margin: 0; -} - -#aioseop_opengraph_settings_image_wrapper img { - width: auto; - height: 75px; -} - -#aioseop_opengraph_settings_image_wrapper .aioseop_option_setting_label { - max-width: 160px; - min-width: 100px; - width: 30%; -} - -.aioseop_input input[type="checkbox"], -.aioseop_input input[type="radio"] { - vertical-align: text-bottom; - margin-top: 8px; -} - -#aiosp_importer_exporter_import_export_help_wrapper .aioseop_option_div { - max-height: initial; -} - -#aiosp { - width: auto; -} - -.aioseop_input.aioseop_top_label .aioseop_option_input { - margin: 0 0 10px 0; -} - -.aiosp_file_editor_settings > .aioseop_textarea_type .aioseop_option_div { - max-height: none; -} - -/* Robots.txt styling */ -#aiosp_robots_generator_robotgen_wrapper .aioseop_option_div, -#aiosp_robots_generator_robothtml_wrapper .aioseop_option_div { - max-height: none; -} - -.aioseop_option_input .widefat td { - vertical-align: middle; -} - -.entry-row.robots.quirks { - font-weight: bold; - opacity: 1; -} - -.entry-row.robots { - opacity: 0.8; -} - -.entry-row.robots.invalid { - opacity: 1; - font-weight: bold; -} - -.invalid .entry_label { - font-weight: bold; -} - -.aioseop .aioseop_option_input tbody { - background: #FCFCFC; -} - -.All_in_One_SEO_Pack_Robots .aioseop .aioseop_option_input tbody { - background: transparent; -} - -.entry-row.robots div { - height: 20px; - vertical-align: middle; - width: 90%; - margin: 0 0 4px 0; -} - -.robots img { - margin: 0 0 0 2px; - opacity: 0.6; -} - -.aioseop_option_docs { - width: 98%; - display: none; - border: 1px solid #D3D3D3; - margin-top: 20px; - padding: 1%; - background-color: #EEE; -} - -.aioseop_option_docs h3 { - background: none; -} - -div.aioseop_notice { - position: relative; -} - -div.aioseop_notice a.aioseop_dismiss_link { - position: absolute; - top: 10px; - right: 10px; -} - -.aioseop_error_notice { - color: #f00; - font-weight: bold; -} - -.aioseop_input select { - margin: 7px 0; -} - -.aioseop_help_text ul { - margin: 15px 0 0 20px; -} - -.aioseop_help_text ul li { - line-height: 20px; - margin: 0; -} - -.aioseop_sidebar #side-sortables { - width: 98%; -} - -.aioseop_header_tabs li a.aioseop_header_tab { - font-size: 14px; - line-height: 37px; - text-decoration: none; - cursor: pointer; - -webkit-border-top-right-radius: 3px; - -webkit-border-top-left-radius: 3px; - border-top-right-radius: 3px; - border-top-left-radius: 3px; - border-bottom: none !important; - padding: 0em 0.5em !important; - color: #5F5F5F; -} - -.aioseop_tab { - padding: 10px; -} - -.aioseop_loading { - background-image: url('../../images/activity.gif'); - display: inline-block; - width: 24px; - height: 24px; - margin: 0; - padding: 0; - vertical-align: bottom; -} - -.aioseop_tabs.ui-widget-content { - background: none !important; -} - -.aioseop_tab.ui-widget-content { - border: 1px solid #aaa !important; -} - -.aioseop_tab.ui-widget-content a.aioseop_help_text_link { - color: #888 !important; -} - -.aioseop_tabs.ui-widget { - font-size: 13px !important; - border: none !important; -} - -.aioseop_tabs .ui-widget-header { - border: none !important; - background: none !important; - border-bottom-right-radius: 0px !important; - border-bottom-left-radius: 0px !important; -} - -.aioseop_tabs ul { - margin-left: .2em !important; -} - -.aioseop_tabs .ui-tabs .ui-tabs-panel { - border-width: inherit !important; -} - -.aioseop_tabs .ui-state-default, -.aioseop_tabs .ui-widget-content .ui-state-default, -.aioseop_tabs .ui-widget-header .ui-state-default { - background-image: none !important; -} - -.aioseop_tabs .ui-state-active a { - font-weight: bold !important; -} - -.aiosp_delete { - background-image: url('../../images/delete.png'); - display: inline-block; - width: 16px; - height: 16px; - margin: 0; - padding: 0; - vertical-align: bottom; -} - -form#aiosp_settings_form, -.aioseop_tabs_div { - padding-right: 477px; -} - -.aioseop_tabs_div { - margin-top: 10px; -} - -#aiosp_settings_form ul.sfwd_debug_settings li strong { - display: block; - float: left; - text-align: right; - background-color: #DDD; - margin-right: 8px; - padding: 1px 8px 1px 1px; - overflow: auto; - width: 200px; - min-height: 16px; -} - -#aiosp_settings_form ul.sfwd_debug_settings li:nth-child(2n+1) strong { - background-color: #CCC; -} - -#aiosp_settings_form ul.sfwd_debug_settings li { - clear: left; - margin: 0; - padding: 0; - background-color: #EEE; - overflow: auto; - max-width: 75%; - min-width: 800px; -} - -#aiosp_settings_form ul.sfwd_debug_settings li:nth-child(2n) { - background-color: #DDD; -} - -div.sfwd_debug_mail_sent { - background-color: #080; - border: 1px solid #0A0; - margin: 10px 0 10px 0; - width: 598px; - color: #FFF; - text-align: center; -} - -div.sfwd_debug_error { - background-color: #F00; - color: #FFF; - border: 1px solid #A00; - margin: 10px 0 10px 0; - width: 598px; - text-align: center; - font-weight: bolder; -} - -#aiosp_performance_status_wrapper .aioseop_option_div { - max-height: 420px; -} - -#aioseop_coming_soon, #aioseop_coming_soon2 { - padding-top: 40px; - text-align: center; - height: 258px; - font-size: 16px; -} - -.MRL { - margin-left: 20px !important; - margin-bottom: 10px !important; -} - -/** -* Edit Post screen specific styling -* -*/ -.postbox-container .aioseop_option_div { - width: 100%; -} - -.postbox-container .aioseop_option_div input[type="text"], -.postbox-container .aioseop_option_div textarea { - width: 99%; - max-width: 900px; -} - -.postbox-container .aioseop_option_label { - max-width: none; - height: auto !important; -} - -.postbox-container .aioseop_wrapper { - padding: 0; -} - -.postbox-container .aioseop_input { - margin-bottom: 10px; - padding: 0; -} - -.postbox-container .aioseop_option_input { - width: 63%; - padding: 0; -} - -.postbox-container div#aiosp_upgrade_wrapper { - float: none; - width: auto; - margin: 0; - padding: 0; -} - -.postbox-container div#aiosp_upgrade_wrapper .aioseop_input { - display: block; - padding: 0; -} - -.postbox-container div#aiosp_upgrade_wrapper .aioseop_input .aioseop_option_input { - float: none; - width: auto; - padding: 0; -} - -.postbox-container div#aiosp_upgrade_wrapper .aioseop_input .aioseop_option_input .aioseop_option_div { - width: auto; - min-height: 0; - padding: 10px 0; -} - -.aioseop_tabs .aioseop_options { - margin: 0; -} - -#aioseop_opengraph_settings .aioseop_options { - clear: both; - margin-top: 35px; -} - -/** -* Preview Snippet styling -* -*/ -div#aiosp_snippet_wrapper { - border: 1px solid #888; - clear: both; - padding: 10px 10px 0; - max-width: 97%; - margin-bottom: 15px; -} - -#aiosp_snippet_wrapper > .aioseop_input:first-child { - margin-bottom: 0px; -} - -div#aiosp_snippet_wrapper .aioseop_option_label { - height: auto !important; -} - -#aiosp_snippet_wrapper > .aioseop_input:first-child .aioseop_option_label { - padding: 0; - min-height: inherit; -} - -div#aiosp_snippet_wrapper .aioseop_input.aioseop_top_label .aioseop_option_input { - margin: 0; -} - -div#aioseop_snippet { - font-family: arial, sans-serif; - font-size: 13px; -} - -div#aioseop_snippet > h3 { - margin: 10px 0 5px; - font-size: 18px; - border: 0; - background: inherit; - font-weight: normal; -} - -div#aioseop_snippet > h3 > a { - color: #12c; - text-decoration: none; - cursor: pointer; -} - -div#aioseop_snippet > div { - color: #545454; - max-width: 48em; -} - -div#aioseop_snippet > div > div { - display: block; - margin-bottom: 1px; -} - -div#aioseop_snippet > div > div > cite { - color: #093; - font-style: normal; -} - -div#aioseop_snippet > div > span { - margin: 0; - padding: 0; - border: 0; -} - -/* the good, the bad and the ugly character counts */ -.aioseop_count_good { - color: #515151 !important; - background-color: #eee !important; -} -.aioseop_count_bad { - color: #515151 !important; - background-color: #ff0 !important; -} -.aioseop_count_ugly { - color: #fff !important; - background-color: #f00 !important; -} - -textarea.robots-text { - background-color: #eee; - width: 100%; - height: 100%; -} - -div#aiosp_sitemap_status_metabox .toggle-indicator { - display:none; -} +/** + * Controls all the styling of the plugin. + * + * @author Michael Torbert. + * @author Semper Fi Web Design. + * @copyright http://semperplugins.com + * @package All-in-One-SEO-Pack. + */ + +.form-table.aioseop { + clear: none; +} + +.form-table.aioseop td { + vertical-align: top; + padding: 16px 0 10px 0; + line-height: 20px; + font-size: 12px; +} + +.form-table.aioseop th { + width: 200px; + padding: 10px 0 12px 9px; +} + +.aioseop_help_text_link, +.aioseop_help_text_link:active { + text-align: left; + float: left; + max-width: 30px; + min-width: 20px; + padding-top: 2px; + outline: none; + color: #888; + font-family: sans-serif; + line-height: 1.4em; +} + +.aioseop_help_text_link span { + font-size: 14px; +} + +.aioseop_help_text_link:before { + content: "\f223"; + font-size: 27px; + font-family: dashicons; + vertical-align: middle; +} + +#aioseop-support .aioseop_metabox_text, +#aioseop-support a { + font-size: 14px; + color: #000; + text-decoration: none; +} + +.aioseop_meta_box_help > label { + position: absolute; + margin-left: 8px; +} + +.aioseop_help_text_link img { + width: 40px; + float: left; +} + +.aioseop_meta_box_help, +.aioseop_meta_box_help:active { + float: right; + text-align: right; + min-width: 56px; + max-width: 90px; + text-decoration: none; + height: 15px; + padding-top: 1px; + position: relative; +} + +.aioseop_meta_box_help span { + vertical-align: middle; +} + +.aioseop_tabs .aioseop_meta_box_help, +.aioseop_tabs .aioseop_meta_box_help:active { + margin-top: 4px; +} + +.aioseop_label { + color: #5F5F5F; + font-weight: bold; + line-height: 19px; + display: inline-block; + float: left; + text-align: left; + font-family: 'Open Sans', sans-serif; + padding: 2px 0; + width: 81%; + min-width: 120px; + max-width: 250px; + cursor: default; +} + +.aioseop_option_div { + max-height: 360px; + min-height: 37px; + width: 95%; + overflow-y: auto; +} + +.aioseop_overflowed { + border: 1px solid #e1e1e1; +} + +.aioseop input[type="text"], .aioseop input[type="url"] { + color: #515151; + min-height: 35px; + padding: 10px 0 10px 10px; + font-size: 14px; + width: 95%; + max-width: 600px; +} + +.aioseop textarea { + color: #515151; + padding: 10px 0 0 10px; + margin: 0; + font-size: 14px; + line-height: 25px; + width: 95%; + max-width: 600px; + min-height: 36px; +} + +.aioseop_help_text_div { + text-align: left; + width: 100%; + margin: 0; +} + +.aioseop_help_text { + font-size: 12px; + float: left; + clear: left; + color: #797979; + line-height: 15px; + font-style: italic; +} + +.aioseop_head_tagline { + color: #5F5F5F; + font-size: 13px; +} + +.aioseop_head_nav { + float: left; + font-size: 18px; + margin: 0 0 16px 0; + font-family: "HelveticaNeue-Light", + "Helvetica Neue Light", + "Helvetica Neue", + sans-serif; + border-bottom: 1px solid #CCC; + width: 100%; +} + +.aioseop_head_nav_tab { + padding: 10px 15px 10px 15px; + margin: 0 0 0 15px; + border-radius: 4px 4px 0 0; + border: 1px solid #CCC; + border-bottom: 0 white; + float: left; + opacity: 0.5; + color: black; + text-shadow: white 0 1px 0; + text-decoration: none; +} + +.aioseop_head_nav_tab.aioseop_head_nav_active { + opacity: 1; + margin-bottom: -1px; + border-width: 1px; +} + +.aioseop_head_nav_tab:first-child { + margin-left: 0; +} + +.aioseop_head_nav_tab:hover { + opacity: 1; +} + +.aioseop_header { + float: left; + clear: left; +} + +.aioseop_advert { + padding: 10px; + margin-bottom: 30px; + border: 1px solid #DDD; + height: 200px; + width: 423px; +} + +.aioseop_nopad { + padding-left: 0; + padding-top: 0; +} + +.aioseop_nopad_all { + padding: 0; + height: 220px; + width: 445px; + margin-bottom: 20px; + border: none; +} + +.aioseop_adverts { + float: right; +} + +.wincherad { + width: 100%; + height: 100%; + background-size: 100%; + background-repeat: no-repeat; + margin-bottom: 0; + border: none; +} + +#wincher21 { + background-image: url(../../modules/images/banner21.jpg); +} + +#wincher22 { + background-image: url(../../modules/images/banner22.jpg); +} + +.aioseop_content { + min-width: 760px; + clear: left; +} + +.aioseop_options_wrapper .hndle { + font-size: 15px; + font-family: Georgia, + "Times New Roman", + "Bitstream Charter", + Times, + serif; + font-weight: normal; + min-height: 18px; + padding: 7px 10px; + margin: 0; + line-height: 1; +} + +.aioseop_options_wrapper .submit input.button-primary { + margin-bottom: 5px; +} + +#aiosp_feature_manager_metabox.postbox { + margin-top: 20px; + float: left; +} + +.aioseop_advert p { + margin: 25px 0 25px 0; +} + +.aioseop_options_wrapper .postarea { + border-color: #DFDFDF; + -moz-box-shadow: inset 0 1px 0 #fff; + -webkit-box-shadow: inset 0 1px 0 #fff; + box-shadow: inset 0 1px 0 #fff; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; +} + +.aioseop_advert h3 { + padding: 0; + margin-top: 6px; +} + +.aioseop_metabox_text p { + margin: 0 0 0 0; + width: 101%; +} + +.aioseop_sidebar { + width: 457px; + margin-left: 10px; +} + +.aioseop_metabox_text { + margin-bottom: 0; +} + +.aioseop_metabox_wrapper { + padding: 0; +} + +.aioseop_metabox_text *:last-child { + margin: 0; +} + +.aioseop_metabox_feature { + margin-top: 20px; +} + +.aioseop_translations { + margin-top: 15px; +} + +.aioseop_option_label { + float: left; + margin: 0; + padding-top: 3px; + padding-bottom: 3px; + width: 37%; + min-width: 150px; + max-width: 360px; + min-height: 30px; +} + +.aioseop_metabox_text h2 { + font-size: 14px; + padding: 0; + font-weight: bold; + line-height: 29px; +} + +#aioseop-about { + width: 443px; + margin-bottom: 20px; +} + +#aioseop-about .aioseop_metabox_text #mc-embedded-subscribe-form h2 { + font-size: 13px; +} + +.aioseop_sidebar #mc-embedded-subscribe-form { + margin: 0 0 10px 0; + background: white; + padding: 10px 10px; + border: 1px solid #DDD; +} + +#aioseop-about .aioseop_metabox_text ul { + list-style-type: disc; + padding-left: 15px; +} + +.aioseop input[readonly] { + background-color: #EEE; + margin: 5px 0 5px 0 !important; +} + +.aioseop_settings_left { + float: left; + padding: 0; + margin: 0; + width: 100%; +} + +body.all-in-one-seo_page_all-in-one-seo-pack-aioseop_feature_manager .aioseop_settings_left { + margin-top: 20px; +} + +body.all-in-one-seo_page_all-in-one-seo-pack-pro-aioseop_feature_manager .aioseop_settings_left { + margin-top: 20px; +} + +#aioseop_top_button { + margin-top: 5px; + height: 30px; +} + +#aioseop-list #mce-EMAIL { + margin-top: 5px; + width: 250px; +} + +.aioseop_top { + margin: 10px 10px 0 0; + /* margin: 10px 477px 0px 0px; */ +} + +.aioseop_top #aioseop-list { + margin-bottom: 0; +} + +.aioseop_top #aioseop-list.postbox.closed { + overflow: hidden; +} + +.aioseop_right_sidebar { + float: right; + margin-top: 35px; +} + +#aiosp_settings_form .button-primary.hidden { + display: none; +} + +form#edittag div#aiosp_titleatr_wrapper, +form#edittag div#aiosp_menulabel_wrapper, +form#edittag div#aiosp_sitemap_exclude_wrapper { + display: none; +} + +.All_in_One_SEO_Pack_Feature_Manager > #aiosp_settings_form > #aioseop_top_button { + height: 5px; + position: absolute; + top: 0; + width: 97%; +} + +.All_in_One_SEO_Pack_Feature_Manager > #aiosp_settings_form > .aioseop_settings_left { + margin-top: 10px; +} + +.All_in_One_SEO_Pack_Feature_Manager > .aioseop_right_sidebar.aioseop_options_wrapper { + margin-top: 10px; +} + +div#aiosp_feature_manager_metabox .inside { + padding: 8px; +} + +div.aioseop_feature { + position: relative; + display: inline-block; + float: left; + vertical-align: top; + width: 240px; + height: 288px; + margin: 8px; + border: 1px solid #DEDEDE; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; + background: white; + padding: 10px 0 0; + -webkit-box-shadow: inset 0 1px 0 #fff, + inset 0 0 20px rgba(0, 0, 0, 0.05), + 0 1px 2px rgba(0, 0, 0, 0.1); + -moz-box-shadow: inset 0 1px 0 #fff, + inset 0 0 20px rgba(0, 0, 0, 0.05), + 0 1px 2px rgba(0, 0, 0, 0.1); + box-shadow: inset 0 1px 0 #fff, + inset 0 0 20px rgba(0, 0, 0, 0.05), + 0 1px 2px rgba(0, 0, 0, 0.1); + -webkit-transition-duration: .4s; + -moz-transition-duration: .4s; +} + +.aioseop_feature .flag { + float: right; + margin-right: -7px; + background: none repeat scroll 0 0 #D23D46; + color: #FFFFFF; + padding: 5px 12px 6px 5px; + position: relative; +} + +.aioseop_feature .flag:before { + border-color: #D23D46 #D23D46 #D23D46 transparent; + border-style: solid; + border-width: 14px 4px 15px 10px; + content: ""; + left: -14px; + position: absolute; + top: 0; +} + +.aioseop_feature .flag:after { + border-color: #892026 transparent transparent; + border-style: solid; + border-width: 6px 6px 6px 0; + bottom: -12px; + content: ""; + position: absolute; + right: 0; +} + +.aioseop_feature .flag.pro { + display: none; +} + +#aioseop_coming_soon .free.flag, +.all-in-one-seo_page_all-in-one-seo-pack-pro-modules-aioseop_feature_manager .aioseop_feature .free.flag { + display: none; +} + +#aioseop_coming_soon .flag.pro { + display: block; + margin-top: -30px; +} + +.all-in-one-seo_page_all-in-one-seo-pack-pro-modules-aioseop_feature_manager #aioseop_coming_soon .flag.pro { + display: none; +} + +.aioseop_feature h3 { + font-size: 17px; + margin: 0; + padding: 0 10px 5px 10px; + font-weight: normal; + font-style: normal; + font-family: "Helvetica Neue", + Helvetica, + Arial, + "Lucida Grande", + Verdana, + "Bitstream Vera Sans", + sans-serif; +} + +.aioseop_feature p { + line-height: 150%; + font-size: 12px; + font-family: Georgia, + "Times New Roman", + "Bitstream Charter", + Times, serif; + margin-bottom: 20px; + color: #666; + padding: 0 10px; +} + +.aioseop_feature p.aioseop_desc { + min-height: 80px; +} + +.aioseop_feature .feature_button { + float: right; + margin-bottom: 10px; + margin-right: 10px; + min-width: 80px; + text-align: center; +} + +.aioseop_feature .feature_button:before { + content: "Activate"; +} + +.aioseop_feature .active.feature_button:before { + content: "Deactivate"; +} + +div.aioseop_feature .aioseop_featured_image { + min-height: 100px; + background-repeat: no-repeat; + display: block; + margin: 0 auto; + width: 133px; +} + +div.aioseop_feature .aioseop_featured_image { + background-image: url(../../modules/images/Default-BW-Standard.png); +} + +div.aioseop_feature .aioseop_featured_image.active { + background-image: url(../../modules/images/Default-Color-Standard.png); +} + +div.aioseop_feature#aioseop_sitemap .aioseop_featured_image { + background-image: url(../../modules/images/XMLSitemaps-BW-Standard.png); +} + +div.aioseop_feature#aioseop_sitemap .aioseop_featured_image.active { + background-image: url(../../modules/images/XMLSitemaps-Color-Standard.png); +} + +div.aioseop_feature#aioseop_video_sitemap .aioseop_featured_image { + background-image: url(../../modules/images/VideoSitemap-BW-Standard.png); +} + +div.aioseop_feature#aioseop_video_sitemap .aioseop_featured_image.active { + background-image: url(../../modules/images/VideoSitemap-Color-Standard.png); +} + +div.aioseop_feature#aioseop_opengraph .aioseop_featured_image { + background-image: url(../../modules/images/SocialMeta-BW-Standard.png); +} + +div.aioseop_feature#aioseop_opengraph .aioseop_featured_image.active { + background-image: url(../../modules/images/SocialMeta-Color-Standard.png); +} + +div.aioseop_feature#aioseop_robots .aioseop_featured_image, div.aioseop_feature#aioseop_bad_robots .aioseop_featured_image { + background-image: url(../../modules/images/Robots-BW-Standard.png); +} + +div.aioseop_feature#aioseop_robots .aioseop_featured_image.active, div.aioseop_feature#aioseop_bad_robots .aioseop_featured_image.active { + background-image: url(../../modules/images/Robots-Color-Standard.png); +} + +div.aioseop_feature#aioseop_file_editor .aioseop_featured_image { + background-image: url(../../modules/images/FileEditor-BW-Standard.png); +} + +div.aioseop_feature#aioseop_file_editor .aioseop_featured_image.active { + background-image: url(../../modules/images/FileEditor-Color-Standard.png); +} + +div.aioseop_feature#aioseop_importer_exporter .aioseop_featured_image { + background-image: url(../../modules/images/ImporterExporter-BW-Standard.png); +} + +div.aioseop_feature#aioseop_importer_exporter .aioseop_featured_image.active { + background-image: url(../../modules/images/ImporterExporter-Color-Standard.png); +} + +div.aioseop_feature#aioseop_performance .aioseop_featured_image { + background-image: url(../../modules/images/Performance-BW-Standard.png); +} + +div.aioseop_feature#aioseop_performance .aioseop_featured_image.active { + background-image: url(../../modules/images/Performance-Color-Standard.png); +} + +div.aioseop_feature#aioseop_coming_soon .aioseop_featured_image { + background-image: url(../../modules/images/Default-Color-Standard.png); +} + +div.aioseop_feature#aioseop_coming_soon2 .aioseop_featured_image { + background-image: url(../../modules/images/Default-Color-Standard.png); +} + +.All_in_One_SEO_Pack_Sitemap > form > .wrap > .form-table, +.All_in_One_SEO_Pack_Video_Sitemap > form > .wrap > .form-table { + max-width: 500px; + clear: none; +} + +.aioseop_follow_button { + min-height: 50px; + background-repeat: no-repeat; + display: inline-block; + width: 100px; + background-size: auto 50px !important; + margin-right: 0; +} + +.aioseop_facebook_follow { + background-image: url(../../modules/images/facebook-follow-standard.png); +} + +.aioseop_twitter_follow { + background-image: url(../../modules/images/twitter-follow-standard.png); +} + +@media only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and ( min--moz-device-pixel-ratio: 1.5), only screen and ( -o-min-device-pixel-ratio: 3/2), only screen and ( min-device-pixel-ratio: 1.5), only screen and ( min-resolution: 1.5dppx) { + div.aioseop_feature .aioseop_featured_image { + background-size: auto 100px !important; + } + + div.aioseop_feature .aioseop_featured_image.active { + background-image: url(../../modules/images/Default-Color-Retina.png); + } + + div.aioseop_feature .aioseop_featured_image { + background-image: url(../../modules/images/Default-BW-Retina.png); + } + + div.aioseop_feature#aioseop_sitemap .aioseop_featured_image { + background-image: url(../../modules/images/XMLSitemaps-BW-Retina.png); + } + + div.aioseop_feature#aioseop_sitemap .aioseop_featured_image.active { + background-image: url(../../modules/images/XMLSitemaps-Color-Retina.png); + } + + div.aioseop_feature#aioseop_video_sitemap .aioseop_featured_image { + background-image: url(../../modules/images/VideoSitemap-BW-Retina.png); + } + + div.aioseop_feature#aioseop_video_sitemap .aioseop_featured_image.active { + background-image: url(../../modules/images/VideoSitemap-Color-Retina.png); + } + + div.aioseop_feature#aioseop_opengraph .aioseop_featured_image { + background-image: url(../../modules/images/SocialMeta-BW-Retina.png); + } + + div.aioseop_feature#aioseop_opengraph .aioseop_featured_image.active { + background-image: url(../../modules/images/SocialMeta-Color-Retina.png); + } + + div.aioseop_feature#aioseop_robots .aioseop_featured_image, div.aioseop_feature#aioseop_bad_robots .aioseop_featured_image { + background-image: url(../../modules/images/Robots-BW-Retina.png); + } + + div.aioseop_feature#aioseop_robots .aioseop_featured_image.active, div.aioseop_feature#aioseop_bad_robots .aioseop_featured_image.active { + background-image: url(../../modules/images/Robots-Color-Retina.png); + } + + div.aioseop_feature#aioseop_file_editor .aioseop_featured_image { + background-image: url(../../modules/images/FileEditor-BW-Retina.png); + } + + div.aioseop_feature#aioseop_file_editor .aioseop_featured_image.active { + background-image: url(../../modules/images/FileEditor-Color-Retina.png); + } + + div.aioseop_feature#aioseop_importer_exporter .aioseop_featured_image { + background-image: url(../../modules/images/ImporterExporter-BW-Retina.png); + } + + div.aioseop_feature#aioseop_importer_exporter .aioseop_featured_image.active { + background-image: url(../../modules/images/ImporterExporter-Color-Retina.png); + } + + div.aioseop_feature#aioseop_performance .aioseop_featured_image { + background-image: url(../../modules/images/Performance-BW-Retina.png); + } + + div.aioseop_feature#aioseop_performance .aioseop_featured_image.active { + background-image: url(../../modules/images/Performance-Color-Retina.png); + } + + div.aioseop_feature#aioseop_coming_soon .aioseop_featured_image { + background-image: url(../../modules/images/Default-BW-Retina.png); + } + + div.aioseop_feature#aioseop_coming_soon2 .aioseop_featured_image { + background-image: url(../../modules/images/Default-BW-Retina.png); + } + + .aioseop_facebook_follow { + background-image: url(../../modules/images/facebook-follow-retina.png); + } + + .aioseop_twitter_follow { + background-image: url(../../modules/images/twitter-follow-retina.png); + } +} + +.aioseop_options { + width: 100%; + margin: 18px 0 10px 0; +} + +.aioseop_wrapper { + width: 100%; + padding-left: 5px; +} + +.aioseop_input { + clear: left; + width: 98%; + padding: 5px 1%; + display: inline-block; +} + +.aioseop_option_input { + float: left; + width: 61%; + margin: 0; + padding-left: 1px; + min-width: 160px; + /* max-width: 900px; */ +} + +/*** Sitemap Additional Pages section ***/ +#aiosp_sitemap_addl_pages_metabox .aioseop_options, +#aiosp_video_sitemap_addl_pages_metabox .aioseop_options { + width: 97%; + margin: 5px; +} + +#aiosp_sitemap_addl_pages_metabox .aioseop_wrapper#aiosp_sitemap_addl_instructions_wrapper, +#aiosp_video_sitemap_addl_pages_metabox .aioseop_wrapper#aiosp_video_sitemap_addl_instructions_wrapper { + display: block; + width: 100%; + float: none; + margin: 0; +} + +#aiosp_sitemap_addl_pages_metabox .aioseop_wrapper#aiosp_sitemap_addl_instructions_wrapper .aioseop_input, +#aiosp_video_sitemap_addl_pages_metabox .aioseop_wrapper#aiosp_video_sitemap_addl_instructions_wrapper .aioseop_input { + display: block; + width: 100%; +} + +#aiosp_sitemap_addl_pages_metabox .aioseop_wrapper, +#aiosp_video_sitemap_addl_pages_metabox .aioseop_wrapper { + padding: 0; +} + +#aiosp_sitemap_addl_pages_metabox .aioseop_wrapper .aioseop_input, +#aiosp_video_sitemap_addl_pages_metabox .aioseop_wrapper .aioseop_input { + display: inline-block; + vertical-align: middle; + width: 25%; + min-width: 120px; + height: 70px; +} + +#aiosp_sitemap_addl_pages_metabox .aioseop_wrapper .aioseop_top_label, +#aiosp_video_sitemap_addl_pages_metabox .aioseop_wrapper .aioseop_top_label { + width: 70%; + margin: 0; +} + +#aiosp_sitemap_addl_pages_metabox .aioseop_wrapper .aioseop_option_label, +#aiosp_video_sitemap_addl_pages_metabox .aioseop_wrapper .aioseop_option_label { + height: 30px !important; +} + +#aiosp_sitemap_addl_pages_metabox .aioseop_wrapper#aiosp_sitemap_addl_mod_wrapper input.aiseop-date, +#aiosp_video_sitemap_addl_pages_metabox .aioseop_wrapper#aiosp_video_sitemap_addl_mod_wrapper input.aiseop-date { + height: 36px; +} + +#aiosp_sitemap_addl_pages_metabox .aioseop_options .aioseop_submit_type, +#aiosp_video_sitemap_addl_pages_metabox .aioseop_options .aioseop_submit_type { + margin: 0; +} + +#aiosp_sitemap_addl_pages_metabox .aioseop_options .aioseop_submit_type input.button-primary, +#aiosp_video_sitemap_addl_pages_metabox .aioseop_options .aioseop_submit_type input.button-primary { + margin-left: 0 !important; +} + +#aiosp_sitemap_addl_pages_metabox .aioseop_help_text_div, +#aiosp_video_sitemap_addl_pages_metabox .aioseop_help_text_div { + position: absolute; + width: auto; + margin: 5px 0 10px 0; +} + +#aiosp_sitemap_addl_pages_metabox table.aioseop_table, +#aiosp_video_sitemap_addl_pages_metabox table.aioseop_table { + width: 96%; + border: 1px solid #CCC; + margin: 5px 5px 10px; +} + +/*** Sitemap Exclude Items section ***/ +.selectize-control.aioseop-exclude-terms { + position: static; + width: 95%; + max-width: 600px; +} + +table.aioseop_table tr:nth-child(odd) { + background-color: #EEE; +} + +.All_in_One_SEO_Pack_Opengraph table.aioseop_table tr:nth-child(odd) { + background-color: rgba(238, 238, 238, 0.5); +} + +table.aioseop_table td { + width: 23%; +} + +.All_in_One_SEO_Pack_Opengraph table.aioseop_table { + width: 80%; + max-width: 800px; + display: block; + border-top: 1px solid #dfdfdf; + border-left: 1px solid #dfdfdf; +} + +.All_in_One_SEO_Pack_Opengraph table.aioseop_table th { + width: 18%; + border-right: 1px solid #dfdfdf; + border-bottom: 1px solid #dfdfdf; +} + +.All_in_One_SEO_Pack_Opengraph div.aioseop_meta_info { + margin-top: 10px; + border: 1px solid #dfdfdf; + width: 80%; + max-width: 800px; +} + +.All_in_One_SEO_Pack_Opengraph table.aioseop_table tr.aioseop_table_header th { + background: #f1f1f1; + background-image: -webkit-gradient(linear, left bottom, left top, from(#ececec), to(#f9f9f9)); + background-image: -webkit-linear-gradient(bottom, #ececec, #f9f9f9); + background-image: -moz-linear-gradient(bottom, #ececec, #f9f9f9); + background-image: -o-linear-gradient(bottom, #ececec, #f9f9f9); + background-image: linear-gradient(to top, #ececec, #f9f9f9); + padding: 5px; + border-bottom-color: #dfdfdf; + text-shadow: #fff 0 1px 0; + -webkit-box-shadow: 0 1px 0 #fff; + -moz-box-shadow: 0 1px 0 #fff; + box-shadow: 0 1px 0 #fff; +} + +.All_in_One_SEO_Pack_Opengraph table.aioseop_table td { + border-right: 1px solid #dfdfdf; + border-bottom: 1px solid #dfdfdf; +} + +#aioseop_opengraph_settings_facebook_debug_result li.aioseop_opengraph_settings_facebook_debug_item { + display: inline-block; + width: 30%; + vertical-align: top; +} + +#aioseop_opengraph_settings_facebook_debug_result li.aioseop_opengraph_settings_facebook_debug_item:nth-child(even) { + font-weight: bold; +} + +#aioseop_opengraph_settings_facebook_debug_result li.aioseop_opengraph_settings_facebook_debug_item:nth-child(odd) { + width: 70%; +} + +#aiosp_sitemap_addl_pages_metabox table.aioseop_table td, +#aiosp_video_sitemap_addl_pages_metabox table.aioseop_table td { + width: 27%; + padding-left: 5%; +} + +#aiosp_sitemap_addl_pages_metabox table.aioseop_table td:first-child, +#aiosp_video_sitemap_addl_pages_metabox table.aioseop_table td:first-child { + padding-left: 2%; +} + +table.aioseop_table td, table.aioseop_table th { + padding: 3px; +} + +.aioseop_top_label .aioseop_option_input, +.aioseop_no_label .aioseop_option_input { + width: 100%; +} + +#aiosp_settings_form .postbox { + margin: 0 0 20px 0; +} + +.aioseop_settings_left .postbox { + float: left; + width: 100%; +} + +.aioseop_option_setting_label { + min-height: 35px; + display: inline-block; + white-space: nowrap; + overflow: hidden; + padding-left: 1px; + max-width: 229px; + min-width: 160px; + width: 33%; +} + +.aioseop_settings_left .postbox .inside { + padding: 0; + margin: 0; + clear: right; +} + +#aiosp_robots_rules { + clear: left; + margin-left: 20px; + max-width: 1072px; +} + +#aiosp_robots_default_metabox .aioseop_wrapper { + width: 31%; + min-width: 165px; + display: inline-block; + max-width: 265px; +} + +#aiosp_robots_default_metabox .aioseop_help_text_div { + position: absolute; + margin: 5px 0 10px 0; +} + +#aiosp_robots_default_metabox .aioseop_option_input { + width: 94%; + min-width: 94%; +} + +#aiosp_robots_default_metabox table.aioseop_table { + width: 96%; + border: 1px solid #CCC; + margin: 5px 0 10px 0; +} + +#aiosp_robots_default_metabox table.aioseop_table td { + width: 25%; + padding-left: 5%; +} + +#aiosp_settings_form .aioseop_no_label, .aioseop_no_label { + float: left; + width: 92%; + max-width: 100%; + margin: 0 23px 0 13px; +} + +#aiosp_sitemap_status_metabox .handlediv.button-link { + display: none; +} + +#aiosp_sitemap_status_metabox.closed .inside { + display: block; +} + +.aioseop_top_label { + width: 96%; + margin: 0 10px; +} + +.aioseop_hidden_type { + margin: 0; + padding: 0; + height: 0; +} + +#aiosp_title_metabox #aiosp_force_rewrites_wrapper { + display: none; + height: 0; +} + +.aioseop_module.error.below-h2 { + padding: 5px 0; + margin: 0 477px 15px 0 !important; +} + +#aioseop_opengraph_settings .inside { + margin: 0; +} + +#aioseop_opengraph_settings_image_wrapper img { + width: auto; + height: 75px; +} + +#aioseop_opengraph_settings_image_wrapper .aioseop_option_setting_label { + max-width: 160px; + min-width: 100px; + width: 30%; +} + +.aioseop_input input[type="checkbox"], +.aioseop_input input[type="radio"] { + vertical-align: text-bottom; + margin-top: 8px; +} + +#aiosp_importer_exporter_import_export_help_wrapper .aioseop_option_div { + max-height: initial; +} + +#aiosp { + width: auto; +} + +.aioseop_input.aioseop_top_label .aioseop_option_input { + margin: 0 0 10px 0; +} + +.aiosp_file_editor_settings > .aioseop_textarea_type .aioseop_option_div { + max-height: none; +} + +/* Robots.txt styling */ +#aiosp_robots_generator_robotgen_wrapper .aioseop_option_div, +#aiosp_robots_generator_robothtml_wrapper .aioseop_option_div { + max-height: none; +} + +.aioseop_option_input .widefat td { + vertical-align: middle; +} + +.entry-row.robots.quirks { + font-weight: bold; + opacity: 1; +} + +.entry-row.robots { + opacity: 0.8; +} + +.entry-row.robots.invalid { + opacity: 1; + font-weight: bold; +} + +.invalid .entry_label { + font-weight: bold; +} + +.aioseop .aioseop_option_input tbody { + background: #FCFCFC; +} + +.All_in_One_SEO_Pack_Robots .aioseop .aioseop_option_input tbody { + background: transparent; +} + +.entry-row.robots div { + height: 20px; + vertical-align: middle; + width: 90%; + margin: 0 0 4px 0; +} + +.robots img { + margin: 0 0 0 2px; + opacity: 0.6; +} + +.aioseop_option_docs { + width: 98%; + display: none; + border: 1px solid #D3D3D3; + margin-top: 20px; + padding: 1%; + background-color: #EEE; +} + +.aioseop_option_docs h3 { + background: none; +} + +div.aioseop_notice { + position: relative; +} + +div.aioseop_notice a.aioseop_dismiss_link { + position: absolute; + top: 10px; + right: 10px; +} + +.aioseop_error_notice { + color: #f00; + font-weight: bold; +} + +.aioseop_input select { + margin: 7px 0; +} + +.aioseop_help_text ul { + margin: 15px 0 0 20px; +} + +.aioseop_help_text ul li { + line-height: 20px; + margin: 0; +} + +.aioseop_sidebar #side-sortables { + width: 98%; +} + +.aioseop_header_tabs li a.aioseop_header_tab { + font-size: 14px; + line-height: 37px; + text-decoration: none; + cursor: pointer; + -webkit-border-top-right-radius: 3px; + -webkit-border-top-left-radius: 3px; + border-top-right-radius: 3px; + border-top-left-radius: 3px; + border-bottom: none !important; + padding: 0em 0.5em !important; + color: #5F5F5F; +} + +.aioseop_tab { + padding: 10px; +} + +.aioseop_loading { + background-image: url('../../images/activity.gif'); + display: inline-block; + width: 24px; + height: 24px; + margin: 0; + padding: 0; + vertical-align: bottom; +} + +.aioseop_tabs.ui-widget-content { + background: none !important; +} + +.aioseop_tab.ui-widget-content { + border: 1px solid #aaa !important; +} + +.aioseop_tab.ui-widget-content a.aioseop_help_text_link { + color: #888 !important; +} + +.aioseop_tabs.ui-widget { + font-size: 13px !important; + border: none !important; +} + +.aioseop_tabs .ui-widget-header { + border: none !important; + background: none !important; + border-bottom-right-radius: 0px !important; + border-bottom-left-radius: 0px !important; +} + +.aioseop_tabs ul { + margin-left: .2em !important; +} + +.aioseop_tabs .ui-tabs .ui-tabs-panel { + border-width: inherit !important; +} + +.aioseop_tabs .ui-state-default, +.aioseop_tabs .ui-widget-content .ui-state-default, +.aioseop_tabs .ui-widget-header .ui-state-default { + background-image: none !important; +} + +.aioseop_tabs .ui-state-active a { + font-weight: bold !important; +} + +.aiosp_delete { + background-image: url('../../images/delete.png'); + display: inline-block; + width: 16px; + height: 16px; + margin: 0; + padding: 0; + vertical-align: bottom; +} + +form#aiosp_settings_form, +.aioseop_tabs_div { + padding-right: 477px; +} + +.aioseop_tabs_div { + margin-top: 10px; +} + +#aiosp_settings_form ul.sfwd_debug_settings li strong { + display: block; + float: left; + text-align: right; + background-color: #DDD; + margin-right: 8px; + padding: 1px 8px 1px 1px; + overflow: auto; + width: 200px; + min-height: 16px; +} + +#aiosp_settings_form ul.sfwd_debug_settings li:nth-child(2n+1) strong { + background-color: #CCC; +} + +#aiosp_settings_form ul.sfwd_debug_settings li { + clear: left; + margin: 0; + padding: 0; + background-color: #EEE; + overflow: auto; + max-width: 75%; + min-width: 800px; +} + +#aiosp_settings_form ul.sfwd_debug_settings li:nth-child(2n) { + background-color: #DDD; +} + +div.sfwd_debug_mail_sent { + background-color: #080; + border: 1px solid #0A0; + margin: 10px 0 10px 0; + width: 598px; + color: #FFF; + text-align: center; +} + +div.sfwd_debug_error { + background-color: #F00; + color: #FFF; + border: 1px solid #A00; + margin: 10px 0 10px 0; + width: 598px; + text-align: center; + font-weight: bolder; +} + +#aiosp_performance_status_wrapper .aioseop_option_div { + max-height: 420px; +} + +#aioseop_coming_soon, #aioseop_coming_soon2 { + padding-top: 40px; + text-align: center; + height: 258px; + font-size: 16px; +} + +.MRL { + margin-left: 20px !important; + margin-bottom: 10px !important; +} + +/** +* Edit Post screen specific styling +* +*/ +.postbox-container .aioseop_option_div { + width: 100%; +} + +.postbox-container .aioseop_option_div input[type="text"], +.postbox-container .aioseop_option_div textarea { + width: 99%; + max-width: 900px; +} + +.postbox-container .aioseop_option_label { + max-width: none; + height: auto !important; +} + +.postbox-container .aioseop_wrapper { + padding: 0; +} + +.postbox-container .aioseop_input { + margin-bottom: 10px; + padding: 0; +} + +.postbox-container .aioseop_option_input { + width: 63%; + padding: 0; +} + +.postbox-container div#aiosp_upgrade_wrapper { + float: none; + width: auto; + margin: 0; + padding: 0; +} + +.postbox-container div#aiosp_upgrade_wrapper .aioseop_input { + display: block; + padding: 0; +} + +.postbox-container div#aiosp_upgrade_wrapper .aioseop_input .aioseop_option_input { + float: none; + width: auto; + padding: 0; +} + +.postbox-container div#aiosp_upgrade_wrapper .aioseop_input .aioseop_option_input .aioseop_option_div { + width: auto; + min-height: 0; + padding: 10px 0; +} + +.aioseop_tabs .aioseop_options { + margin: 0; +} + +#aioseop_opengraph_settings .aioseop_options { + clear: both; + margin-top: 35px; +} + +/** +* Preview Snippet styling +* +*/ +div#aiosp_snippet_wrapper { + border: 1px solid #888; + clear: both; + padding: 10px 10px 0; + max-width: 97%; + margin-bottom: 15px; +} + +#aiosp_snippet_wrapper > .aioseop_input:first-child { + margin-bottom: 0px; +} + +div#aiosp_snippet_wrapper .aioseop_option_label { + height: auto !important; +} + +#aiosp_snippet_wrapper > .aioseop_input:first-child .aioseop_option_label { + padding: 0; + min-height: inherit; +} + +div#aiosp_snippet_wrapper .aioseop_input.aioseop_top_label .aioseop_option_input { + margin: 0; +} + +div#aioseop_snippet { + font-family: arial, sans-serif; + font-size: 13px; +} + +div#aioseop_snippet > h3 { + margin: 10px 0 5px; + font-size: 18px; + border: 0; + background: inherit; + font-weight: normal; +} + +div#aioseop_snippet > h3 > a { + color: #12c; + text-decoration: none; + cursor: pointer; +} + +div#aioseop_snippet > div { + color: #545454; + max-width: 48em; +} + +div#aioseop_snippet > div > div { + display: block; + margin-bottom: 1px; +} + +div#aioseop_snippet > div > div > cite { + color: #093; + font-style: normal; +} + +div#aioseop_snippet > div > span { + margin: 0; + padding: 0; + border: 0; +} + +/* the good, the bad and the ugly character counts */ +.aioseop_count_good { + color: #515151 !important; + background-color: #eee !important; +} +.aioseop_count_bad { + color: #515151 !important; + background-color: #ff0 !important; +} +.aioseop_count_ugly { + color: #fff !important; + background-color: #f00 !important; +} + +textarea.robots-text { + background-color: #eee; + width: 100%; + height: 100%; +} + +div#aiosp_sitemap_status_metabox .toggle-indicator { + display:none; +} From eca3b26ebb5f6d69e9caff2c77a0e75fc2cddf96 Mon Sep 17 00:00:00 2001 From: John Wright Date: Wed, 29 May 2019 10:22:00 -0500 Subject: [PATCH 109/121] Import SEO data from Rank Math (#2518) * [2185] Added meta import for the Rank Math SEO plugin to the SEO Data Import Tool * Remove meta keywords import for Rank Math #2185 * Use spaces instead of tabs for mid-line alignment #2185 --- admin/meta_import.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/admin/meta_import.php b/admin/meta_import.php index b5e6789f4..7cbf7f7d8 100644 --- a/admin/meta_import.php +++ b/admin/meta_import.php @@ -526,6 +526,11 @@ function aiosp_seometa_import() { 'META Description' => 'description', 'META Keywords' => 'keywords', ), + 'Rank Math' => array( + 'Custom Doctitle' => 'rank_math_title', + 'META Description' => 'rank_math_description', + 'Canonical URI' => 'rank_math_canonical_url', + ), 'SEOpressor' => array( 'Custom Doctitle' => '_seopressor_meta_title', 'META Description' => '_seopressor_meta_description', From b79cdd8b59ff31f3af6480b447aa17e795ec03b3 Mon Sep 17 00:00:00 2001 From: EkoJR Date: Wed, 29 May 2019 14:37:04 -0700 Subject: [PATCH 110/121] Refactor AIOSEOP_Notices notice operations to include hook (#2517) * Add hook to load notice data * Dev-Add phpDoc to filter hook * Dev-Refine and cleanup Refines some of the operations, and cleans up some deprecated code. * Change unit testing for aioseop_notices * Dev-Change review_plugin activate to hook Instances using ajax were causing issues when the method was used directly. * Dev-Fix notices being reactivated after dismissing Add dismissed field to class * Dev-Cleanup * Dev-Fix Unit Test --- admin/class-aioseop-notices.php | 414 +++++++++++------- admin/display/notice-aioseop.php | 2 +- admin/display/notice-default.php | 2 +- ...ibility.php => blog-visibility-notice.php} | 42 +- .../display/notices/review-plugin-notice.php | 48 ++ ...indexes.php => sitemap-indexes-notice.php} | 40 +- admin/display/notices/wc-detected-notice.php | 45 ++ admin/functions-notice.php | 166 ------- aioseop_class.php | 17 +- all_in_one_seo_pack.php | 26 +- modules/aioseop_sitemap.php | 5 +- tests/base/class-aioseop-notices-testcase.php | 60 ++- .../notices/test-blog-visibility.php | 2 +- .../notices/test-plugin-review.php | 2 +- .../notices/test-pro-promo-woocommerce.php | 2 +- .../notices/test-sitemap-indexes.php | 2 +- tests/classes/aioseop-notices/test-ajax.php | 15 +- .../aioseop-notices/test-delay-time.php | 2 +- .../aioseop-notices/test-enqueue-scripts.php | 5 +- tests/classes/aioseop-notices/test-init.php | 2 +- tests/classes/aioseop-notices/test-user.php | 2 +- 21 files changed, 460 insertions(+), 441 deletions(-) rename admin/display/notices/{blog-visibility.php => blog-visibility-notice.php} (58%) create mode 100644 admin/display/notices/review-plugin-notice.php rename admin/display/notices/{sitemap-indexes.php => sitemap-indexes-notice.php} (53%) create mode 100644 admin/display/notices/wc-detected-notice.php delete mode 100644 admin/functions-notice.php diff --git a/admin/class-aioseop-notices.php b/admin/class-aioseop-notices.php index 38d1e80b5..f587f367f 100644 --- a/admin/class-aioseop-notices.php +++ b/admin/class-aioseop-notices.php @@ -28,7 +28,12 @@ class AIOSEOP_Notices { * * @var array $notices { * @type array $slug { + * -- Server Variables -- * @type string $slug Required. Notice unique ID. + * @type int $time_start The time the notice was added to the object. + * @type int $time_set Set when AJAX/Action_Option was last used to delay time. Primarily for PHPUnit tests. + * + * -- Filter Function Variables -- * @type int $delay_time Amount of time to begin showing message. * @type string $message Content message to display in the container. * @type array $action_option { @@ -49,8 +54,6 @@ class AIOSEOP_Notices { * array() = all, * array('aioseop') = $this->aioseop_screens, * array('CUSTOM') = specific screen(s). - * @type int $time_start The time the notice was added to the object. - * @type int $time_set Set when AJAX/Action_Option was last used to delay time. Primarily for PHPUnit tests. * } * } */ @@ -60,6 +63,8 @@ class AIOSEOP_Notices { * List of notice slugs that are currently active. * NOTE: Amount is reduced by 1 second in order to display at exactly X amount of time. * + * @todo Change name to $display_times for consistancy both conceptually and with usermeta structure. + * * @since 3.0 * @access public * @@ -70,6 +75,19 @@ class AIOSEOP_Notices { */ public $active_notices = array(); + /** + * Dismissed Notices + * + * Stores notices that have been dismissed sitewide. Users are stored in usermeta data 'aioseop_notice_dismissed_{$slug}'. + * + * @since 3.0 + * + * @var array $dismissed { + * @type boolean $notice_slug => $is_dismissed True if dismissed. + * } + */ + public $dismissed = array(); + /** * The default dismiss time. An anti-nag setting. * @@ -118,12 +136,36 @@ public function __construct() { /** * _Requires * - * Additional files required. + * Internal use only. Additional files required. * * @since 3.0 */ private function _requires() { - require_once AIOSEOP_PLUGIN_DIR . 'admin/functions-notice.php'; + $this->autoload_notice_files(); + } + + /** + * Autoload Notice Files + * + * @since 3.0 + * + * @see DirectoryIterator class + * @link https://php.net/manual/en/class.directoryiterator.php + * @see StackOverflow for getting all filenamess in a directory. + * @link https://stackoverflow.com/a/25988433/1376780 + */ + private function autoload_notice_files() { + foreach ( new DirectoryIterator( AIOSEOP_PLUGIN_DIR . 'admin/display/notices/' ) as $file ) { + if ( $file->isFile() && 'php' === $file->getExtension() ) { + $filename = $file->getFilename(); + + // Qualified file pattern; "*-notice.php". + // Prevents any malicious files that may have spreaded. + if ( array_search( 'notice', explode( '-', str_replace( '.php', '', $filename ) ), true ) ) { + include_once AIOSEOP_PLUGIN_DIR . 'admin/display/notices/' . $filename; + } + } + } } /** @@ -217,7 +259,7 @@ private function obj_update_options() { $old_notices_options = $this->obj_get_options(); $notices_options = wp_parse_args( $notices_options, $old_notices_options ); - return update_option( 'aioseop_notices', $notices_options ); + return update_option( 'aioseop_notices', $notices_options, false ); } /** @@ -227,11 +269,40 @@ private function obj_update_options() { * * @since 3.0 * - * @see self::notices Array variable that stores the collection of notices. + * @see AIOSEOP_Notices::notices Array variable that stores the collection of notices. * * @return array Notice variable in self::notices. */ public function notice_defaults() { + return array_merge( + $this->notice_defaults_server(), + $this->notice_defaults_file() + ); + } + + /** + * Notice Defaults Server + * + * @since 3.0 + * + * @return array + */ + public function notice_defaults_server() { + return array( + 'slug' => '', + 'time_start' => time(), + 'time_set' => time(), + ); + } + + /** + * Notice Defaults File + * + * @since 3.0 + * + * @return array + */ + public function notice_defaults_file() { return array( 'slug' => '', 'delay_time' => 0, @@ -240,8 +311,6 @@ public function notice_defaults() { 'class' => 'notice-info', 'target' => 'site', 'screens' => array(), - 'time_start' => time(), - 'time_set' => time(), ); } @@ -265,110 +334,22 @@ public function action_options_defaults() { } /** - * Set Notice Action Options - * - * Sets the Action Options in a Notice. - * - * @since 3.0 - * @access private - * - * @see self::insert_notice() - * @see self::update_notice() - * - * @param array $action_options New action options to be added/updated. - * @return array Action Options with new values added to old. - */ - private function set_action_options( $action_options ) { - $rtn_action_options = array(); - // This helps prevent invalid notices, and empty arrays need to skip this operation when - // there is no actions intended for notice. - if ( ! is_array( $action_options ) ) { - $rtn_action_options[] = $this->action_options_defaults(); - return $rtn_action_options; - } - - foreach ( $action_options as $action_option ) { - $tmp_action_o = $this->action_options_defaults(); - - // For readability and tracking, refrane from using another Foreach loop with the array indexes. - // Button Delay Time. - $tmp_action_o['time'] = $this->default_dismiss_delay; - if ( isset( $action_option['time'] ) ) { - $tmp_action_o['time'] = $action_option['time']; - } - - // Button Text. - if ( isset( $action_option['text'] ) && ! empty( $action_option['text'] ) ) { - $tmp_action_o['text'] = $action_option['text']; - } - - // Link. - if ( isset( $action_option['link'] ) && ! empty( $action_option['link'] ) ) { - $tmp_action_o['link'] = $action_option['link']; - } - - // Dismiss. - if ( isset( $action_option['dismiss'] ) ) { - $tmp_action_o['dismiss'] = $action_option['dismiss']; - } - - // Class. - if ( isset( $action_option['class'] ) && ! empty( $action_option['class'] ) ) { - $tmp_action_o['class'] = $action_option['class']; - } - - $rtn_action_options[] = $tmp_action_o; - } - - return $rtn_action_options; - } - - /** - * Insert Notice + * Add Notice * - * Initial insert for a Notice and Activates it. Used strictly for adding notices - * when no updating or modifications is intended. + * Takes notice and adds it to object and saves to database. * * @since 3.0 * - * @uses self::activate_notice() Used to initialize a notice. - * * @param array $notice See self::notices for more info. * @return boolean True on success. */ - public function insert_notice( $notice = array() ) { + public function add_notice( $notice = array() ) { if ( empty( $notice['slug'] ) || isset( $this->notices[ $notice['slug'] ] ) ) { return false; } $this->notices[ $notice['slug'] ] = $this->prepare_notice( $notice ); - $this->obj_update_options(); - $this->activate_notice( $notice['slug'] ); - - return true; - } - - /** - * Update Notice - * - * Updates an existing Notice without resetting it. Used when modifying - * any existing notices without disturbing its set environment/timeline. - * - * @since 3.0 - * - * @param array $notice See self::notices for more info. - * @return boolean True on success. - */ - public function update_notice( $notice = array() ) { - if ( empty( $notice['slug'] ) || ! isset( $this->notices[ $notice['slug'] ] ) ) { - return false; - } - - $this->notices[ $notice['slug'] ] = $this->prepare_notice( $notice ); - - $this->obj_update_options(); - return true; } @@ -378,13 +359,16 @@ public function update_notice( $notice = array() ) { * @since 3.0 * * @param array $notice The notice to prepare with the database. - * @return bool + * @return array */ public function prepare_notice( $notice = array() ) { - $notice_default = $this->notice_defaults(); - $new_notice = wp_parse_args( $notice, $notice_default ); + $notice_default = $this->notice_defaults_server(); + $notice = wp_parse_args( $notice, $notice_default ); - $new_notice['action_options'] = $this->set_action_options( $new_notice['action_options'] ); + $new_notice = array(); + foreach ( $notice_default as $key => $value ) { + $new_notice[ $key ] = $notice[ $key ]; + } return $new_notice; } @@ -400,6 +384,7 @@ public function prepare_notice( $notice = array() ) { */ public function remove_notice( $slug ) { if ( isset( $this->notices[ $slug ] ) ) { + $this->deactivate_notice( $slug ); unset( $this->notices[ $slug ] ); $this->obj_update_options(); return true; @@ -420,22 +405,22 @@ public function remove_notice( $slug ) { * @return boolean */ public function activate_notice( $slug ) { - if ( empty( $slug ) || ! isset( $this->notices[ $slug ] ) ) { + if ( empty( $slug ) ) { return false; } + $notice = $this->get_notice( $slug ); + if ( 'site' === $notice['target'] && isset( $this->active_notices[ $slug ] ) ) { + return true; + } elseif ( 'user' === $notice['target'] && get_user_meta( get_current_user_id(), 'aioseop_notice_display_time_' . $slug, true ) ) { + return true; + } - // Display at exactly X time, not (X + 1) time. - $display_time = time() + $this->notices[ $slug ]['delay_time']; - $display_time--; - - if ( 'user' === $this->notices[ $slug ]['target'] ) { - $current_user_id = get_current_user_id(); - - update_user_meta( $current_user_id, 'aioseop_notice_dismissed_' . $slug, false ); - update_user_meta( $current_user_id, 'aioseop_notice_display_time_' . $slug, $display_time ); + if ( ! isset( $this->notices[ $slug ] ) ) { + $this->add_notice( $notice ); } - $this->active_notices[ $slug ] = $display_time; + $this->set_notice_delay( $slug, $notice['delay_time'] ); + $this->obj_update_options(); return true; @@ -460,13 +445,156 @@ public function deactivate_notice( $slug ) { return false; } - $this->notices[ $slug ]['active'] = false; + delete_metadata( + 'user', + 0, + 'aioseop_notice_display_time_' . $slug, + '', + true + ); + unset( $this->active_notices[ $slug ] ); + $this->obj_update_options(); + + return true; + } + + /** + * Reset Notice + * + * @since 3.0 + * + * @param string $slug The notice's slug. + * @return bool + */ + public function reset_notice( $slug ) { + if ( empty( $slug ) || ! isset( $this->notices[ $slug ] ) ) { + return false; + } + + $notice = $this->get_notice( $slug ); + unset( $this->active_notices[ $slug ] ); + unset( $this->dismissed[ $slug ] ); + delete_metadata( + 'user', + 0, + 'aioseop_notice_time_set_' . $slug, + '', + true + ); + delete_metadata( + 'user', + 0, + 'aioseop_notice_display_time_' . $slug, + '', + true + ); + delete_metadata( + 'user', + 0, + 'aioseop_notice_dismissed_' . $slug, + '', + true + ); + + $this->set_notice_delay( $slug, $notice['delay_time'] ); + $this->obj_update_options(); return true; } + /** + * Set Notice Delay + * + * @since 3.0 + * + * @param string $slug The notice's slug. + * @param int $delay_time Amount of time to delay. + * @return boolean + */ + public function set_notice_delay( $slug, $delay_time ) { + if ( empty( $slug ) ) { + return false; + } + $time_set = time(); + + // Display at exactly X time, not (X + 1) time. + $display_time = $time_set + $delay_time - 1; + $notice = $this->get_notice( $slug ); + if ( 'user' === $notice['target'] ) { + $current_user_id = get_current_user_id(); + + update_user_meta( $current_user_id, 'aioseop_notice_time_set_' . $slug, $time_set ); + update_user_meta( $current_user_id, 'aioseop_notice_display_time_' . $slug, $display_time ); + } + + $this->notices[ $slug ]['time_set'] = $time_set; + $this->active_notices[ $slug ] = $display_time; + + return true; + } + + /** + * Set Notice Dismiss + * + * @since 3.0 + * + * @param string $slug The notice's slug. + * @param boolean $dismiss Sets to dismiss a notice. + */ + public function set_notice_dismiss( $slug, $dismiss ) { + $notice = $this->get_notice( $slug ); + if ( 'site' === $notice['target'] ) { + $this->dismissed[ $slug ] = $dismiss; + } elseif ( 'user' === $notice['target'] ) { + $current_user_id = get_current_user_id(); + + update_user_meta( $current_user_id, 'aioseop_notice_dismissed_' . $slug, $dismiss ); + } + } + + /** + * Get Notice + * + * @since 3.0 + * + * @param string $slug The notice's slug. + * @return array + */ + public function get_notice( $slug ) { + // Set defaults for notice. + $rtn_notice = $this->notice_defaults(); + + if ( isset( $this->notices[ $slug ] ) ) { + // Get minimized (database) data. + $rtn_notice = array_merge( $rtn_notice, $this->notices[ $slug ] ); + } + + /** + * Admin Notice {$slug} + * + * Applies the notice data values for a given notice slug. + * `aioseop_admin_notice-{$slug}` with the slug being the individual notice. + * + * @since 3.0 + * + * @params array $notice_data See `\AIOSEOP_Notices::$notices` for structural documentation. + */ + $notice_data = apply_filters( 'aioseop_admin_notice-' . $slug, array() ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores + + if ( ! empty( $notice_data ) ) { + $rtn_notice = array_merge( $rtn_notice, $notice_data ); + + foreach ( $rtn_notice['action_options'] as &$action_option ) { + // Set defaults for `$notice['action_options']`. + $action_option = array_merge( $this->action_options_defaults(), $action_option ); + } + } + + return $rtn_notice; + } + /*** DISPLAY Methods **************************************************/ /** * Deregister Scripts @@ -506,7 +634,8 @@ public function admin_enqueue_scripts() { // Localization. $notice_actions = array(); foreach ( $this->active_notices as $notice_slug => $notice_display_time ) { - foreach ( $this->notices[ $notice_slug ]['action_options'] as $action_index => $action_arr ) { + $notice = $this->get_notice( $notice_slug ); + foreach ( $notice['action_options'] as $action_index => $action_arr ) { $notice_actions[ $notice_slug ][] = $action_index; } } @@ -583,26 +712,31 @@ public function display_notice( $template ) { $current_user_id = get_current_user_id(); foreach ( $this->active_notices as $a_notice_slug => $a_notice_time_display ) { $notice_show = true; + $notice = $this->get_notice( $a_notice_slug ); // Screen Restriction. - if ( ! empty( $this->notices[ $a_notice_slug ]['screens'] ) ) { + if ( ! empty( $notice['screens'] ) ) { // Checks if on aioseop screen. - if ( in_array( 'aioseop', $this->notices[ $a_notice_slug ]['screens'], true ) ) { + if ( in_array( 'aioseop', $notice['screens'], true ) ) { if ( ! in_array( $current_screen->id, $this->aioseop_screens, true ) ) { continue; } } // Checks the other screen restrictions by slug/id. - if ( ! in_array( 'aioseop', $this->notices[ $a_notice_slug ]['screens'], true ) ) { - if ( ! in_array( $current_screen->id, $this->notices[ $a_notice_slug ]['screens'], true ) ) { + if ( ! in_array( 'aioseop', $notice['screens'], true ) ) { + if ( ! in_array( $current_screen->id, $notice['screens'], true ) ) { continue; } } } + if ( isset( $this->dismissed[ $a_notice_slug ] ) && $this->dismissed[ $a_notice_slug ] ) { + $notice_show = false; + } + // User Settings. - if ( 'user' === $this->notices[ $a_notice_slug ]['target'] ) { + if ( 'user' === $notice['target'] ) { $user_dismissed = get_user_meta( $current_user_id, 'aioseop_notice_dismissed_' . $a_notice_slug, true ); if ( ! $user_dismissed ) { $user_notice_time_display = get_user_meta( $current_user_id, 'aioseop_notice_display_time_' . $a_notice_slug, true ); @@ -620,7 +754,7 @@ public function display_notice( $template ) { 'notice-warning', 'notice-do-nag', ); - if ( defined( 'DISABLE_NAG_NOTICES' ) && true === DISABLE_NAG_NOTICES && ( ! in_array( $this->notices[ $a_notice_slug ]['class'], $important_admin_notices, true ) ) ) { + if ( defined( 'DISABLE_NAG_NOTICES' ) && true === DISABLE_NAG_NOTICES && ( ! in_array( $notice['class'], $important_admin_notices, true ) ) ) { // Skip if `DISABLE_NAG_NOTICES` is implemented (as true). // Important notices, WP's CSS `notice-error` & `notice-warning`, are still rendered. continue; @@ -676,35 +810,17 @@ public function ajax_notice_action() { $action_options['time'] = $this->default_dismiss_delay; $action_options['dismiss'] = false; - if ( isset( $this->notices[ $notice_slug ]['action_options'][ $action_index ] ) ) { - $action_options = $this->notices[ $notice_slug ]['action_options'][ $action_index ]; - } - - // User Notices or Sitewide. - if ( 'user' === $this->notices[ $notice_slug ]['target'] ) { - // Always sets the action time, even if dismissed, so last timestamp is recorded. - $current_user_id = get_current_user_id(); - if ( $action_options['time'] ) { - $time_set = time(); - // Adds action_option delay time, reduced by 1 second to display at exact time. - $metadata = $time_set + $action_options['time'] - 1; + $notice = $this->get_notice( $notice_slug ); - update_user_meta( $current_user_id, 'aioseop_notice_time_set_' . $notice_slug, $time_set ); - update_user_meta( $current_user_id, 'aioseop_notice_display_time_' . $notice_slug, $metadata ); - } - if ( $action_options['dismiss'] ) { - update_user_meta( $current_user_id, 'aioseop_notice_dismissed_' . $notice_slug, $action_options['dismiss'] ); - } - } else { - if ( $action_options['time'] ) { - $this->notices[ $notice_slug ]['time_set'] = time(); - // Adds action_option delay time, reduced by 1 second to display at exact time. - $this->active_notices[ $notice_slug ] = $this->notices[ $notice_slug ]['time_set'] + $action_options['time'] - 1; - } + if ( isset( $notice['action_options'][ $action_index ] ) ) { + $action_options = array_merge( $action_options, $notice['action_options'][ $action_index ] ); + } - if ( $action_options['dismiss'] ) { - $this->deactivate_notice( $notice_slug ); - } + if ( $action_options['time'] ) { + $this->set_notice_delay( $notice_slug, $action_options['time'] ); + } + if ( $action_options['dismiss'] ) { + $this->set_notice_dismiss( $notice_slug, $action_options['dismiss'] ); } $this->obj_update_options(); diff --git a/admin/display/notice-aioseop.php b/admin/display/notice-aioseop.php index 7da847902..3411fd097 100644 --- a/admin/display/notice-aioseop.php +++ b/admin/display/notice-aioseop.php @@ -10,7 +10,7 @@ * @subpackage AIOSEOP_Notices */ -$notice = $this->notices[ $a_notice_slug ]; +// $notice = $this->get_notice[ $a_notice_slug ]; $notice_class = 'notice-info'; if ( isset( $notice['class'] ) && ! empty( $notice['class'] ) ) { $notice_class = $notice['class']; diff --git a/admin/display/notice-default.php b/admin/display/notice-default.php index cf3a78a51..6814dabe1 100644 --- a/admin/display/notice-default.php +++ b/admin/display/notice-default.php @@ -10,7 +10,7 @@ * @subpackage AIOSEOP_Notices */ -$notice = $this->notices[ $a_notice_slug ]; +// $notice = $this->notices[ $a_notice_slug ]; $notice_class = 'notice-info'; if ( isset( $notice['class'] ) && ! empty( $notice['class'] ) ) { $notice_class = $notice['class']; diff --git a/admin/display/notices/blog-visibility.php b/admin/display/notices/blog-visibility-notice.php similarity index 58% rename from admin/display/notices/blog-visibility.php rename to admin/display/notices/blog-visibility-notice.php index 54cb3af87..1c62958fe 100644 --- a/admin/display/notices/blog-visibility.php +++ b/admin/display/notices/blog-visibility-notice.php @@ -8,34 +8,6 @@ */ -/** - * Set Notice for Disabled Public Blog - * - * Admin Notice when "Discourage search engines from indexing this site" is - * enabled in Settings > Reading. - * - * @since 3.0 - * - * @global AIOSEOP_Notices $aioseop_notices - * - * @param boolean $update Updates the notice with new content and configurations. - * @param boolean $reset Notice are re-initiated. - */ -function aioseop_notice_set_blog_public_disabled( $update = false, $reset = false ) { - global $aioseop_notices; - - $notice = aioseop_notice_blog_visibility(); - - if ( ! $aioseop_notices->insert_notice( $notice ) ) { - if ( $update ) { - $aioseop_notices->update_notice( $notice ); - } - if ( $reset || ! isset( $aioseop_notices->active_notices[ $notice['slug'] ] ) ) { - $aioseop_notices->activate_notice( $notice['slug'] ); - } - } -} - /** * Notice - Blog Visibility * @@ -53,7 +25,6 @@ function aioseop_notice_blog_visibility() { 'delay_time' => 0, /* translators: %s is a placeholder, which means that it should not be translated. It will be replaced with the name of the plugin, All in One SEO Pack. "Settings > Reading" refers to the "Reading" submenu in WordPress Core. */ 'message' => sprintf( __( 'Warning: %s has detected that you are blocking access to search engines. You can change this in Settings > Reading if this was unintended.', 'all-in-one-seo-pack' ), AIOSEOP_PLUGIN_NAME ), - 'delay_options' => array(), 'class' => 'notice-error', 'target' => 'site', 'screens' => array(), @@ -75,15 +46,4 @@ function aioseop_notice_blog_visibility() { ), ); } - -/** - * Disable Notice for Disabled Public Blog - * - * @since 3.0 - * - * @global AIOSEOP_Notices $aioseop_notices - */ -function aioseop_notice_disable_blog_public_disabled() { - global $aioseop_notices; - $aioseop_notices->deactivate_notice( 'blog_public_disabled' ); -} +add_filter( 'aioseop_admin_notice-blog_public_disabled', 'aioseop_notice_blog_visibility' ); diff --git a/admin/display/notices/review-plugin-notice.php b/admin/display/notices/review-plugin-notice.php new file mode 100644 index 000000000..e9e67ee37 --- /dev/null +++ b/admin/display/notices/review-plugin-notice.php @@ -0,0 +1,48 @@ + 'review_plugin', + 'delay_time' => 1036800, + 'target' => 'user', + 'screens' => array(), + 'class' => 'notice-info', + /* translators: %1$s is a placeholder, which means that it should not be translated. It will be replaced with the name of the plugin, All in One SEO Pack. */ + 'message' => sprintf( __( 'You have been using %1$s for a while now. That is awesome! If you like %1$s, then please leave us a 5-star rating. Huge thanks in advance!', 'all-in-one-seo-pack' ), AIOSEOP_PLUGIN_NAME ), + 'action_options' => array( + array( + 'time' => 0, + 'text' => __( 'Add a review', 'all-in-one-seo-pack' ), + 'link' => 'https://wordpress.org/support/plugin/all-in-one-seo-pack/reviews?rate=5#new-post', + 'dismiss' => false, + 'class' => '', + ), + array( + 'text' => __( 'Remind me later', 'all-in-one-seo-pack' ), + 'time' => 432000, + 'dismiss' => false, + 'class' => '', + ), + array( + 'time' => 0, + 'text' => __( 'No, thanks', 'all-in-one-seo-pack' ), + 'dismiss' => true, + 'class' => '', + ), + ), + ); +} +add_filter( 'aioseop_admin_notice-review_plugin', 'aioseop_notice_review_plugin' ); diff --git a/admin/display/notices/sitemap-indexes.php b/admin/display/notices/sitemap-indexes-notice.php similarity index 53% rename from admin/display/notices/sitemap-indexes.php rename to admin/display/notices/sitemap-indexes-notice.php index 4d862bf03..9ed834cf3 100644 --- a/admin/display/notices/sitemap-indexes.php +++ b/admin/display/notices/sitemap-indexes-notice.php @@ -7,33 +7,6 @@ * @subpackage AIOSEOP_Notices */ -/** - * Set Notice with Sitemap Index +1000 - * - * When there's 1000+ URLs with indexing enabled. - * - * @since 3.0 - * - * @global AIOSEOP_Notices $aioseop_notices - * - * @param boolean $update Updates the notice with new content and configurations. - * @param boolean $reset Notice are re-initiated. - */ -function aioseop_notice_activate_sitemap_indexes( $update = false, $reset = false ) { - global $aioseop_notices; - - $notice = aioseop_notice_sitemap_indexes(); - - if ( ! $aioseop_notices->insert_notice( $notice ) ) { - if ( $update ) { - $aioseop_notices->update_notice( $notice ); - } - if ( $reset || ! isset( $aioseop_notices->active_notices[ $notice['slug'] ] ) ) { - $aioseop_notices->activate_notice( $notice['slug'] ); - } - } -} - /** * Notice - Sitemap Indexes * @@ -68,15 +41,4 @@ function aioseop_notice_sitemap_indexes() { ), ); } - -/** - * Disable Notice for Sitemap - * - * @since 3.0 - * - * @global AIOSEOP_Notices $aioseop_notices - */ -function aioseop_notice_disable_sitemap_indexes() { - global $aioseop_notices; - $aioseop_notices->deactivate_notice( 'woocommerce_detected' ); -} +add_filter( 'aioseop_admin_notice-sitemap_max_warning', 'aioseop_notice_sitemap_indexes' ); diff --git a/admin/display/notices/wc-detected-notice.php b/admin/display/notices/wc-detected-notice.php new file mode 100644 index 000000000..0dc3080ab --- /dev/null +++ b/admin/display/notices/wc-detected-notice.php @@ -0,0 +1,45 @@ + 'woocommerce_detected', + 'delay_time' => 0, + /* translators: %s is a placeholder, which means that it should not be translated. It will be replaced with the name of the premium version of the plugin, All in One SEO Pack Pro. */ + 'message' => sprintf( __( 'We have detected you are running WooCommerce. Upgrade to %s to unlock our advanced e-commerce features, including SEO for Product Categories and more.', 'all-in-one-seo-pack' ), 'All in One SEO Pack Pro' ), + + 'class' => 'notice-info', + 'target' => 'site', + 'screens' => array(), + 'action_options' => array( + array( + 'time' => 0, + 'text' => __( 'Upgrade', 'all-in-one-seo-pack' ), + 'link' => 'https://semperplugins.com/plugins/all-in-one-seo-pack-pro-version/?loc=woo', + 'dismiss' => false, + 'class' => 'button-primary', + ), + array( + 'time' => 2592000, // 30 days. + 'text' => __( 'No Thanks', 'all-in-one-seo-pack' ), + 'link' => '', + 'dismiss' => false, + 'class' => 'button-secondary', + ), + ), + ); +} +add_filter( 'aioseop_admin_notice-woocommerce_detected', 'aioseop_notice_pro_promo_woocommerce' ); diff --git a/admin/functions-notice.php b/admin/functions-notice.php deleted file mode 100644 index d04a1dd16..000000000 --- a/admin/functions-notice.php +++ /dev/null @@ -1,166 +0,0 @@ -insert_notice( $notice ) ) { - if ( $update ) { - $aioseop_notices->update_notice( $notice ); - } - if ( $reset || ! isset( $aioseop_notices->active_notices[ $notice['slug'] ] ) ) { - $aioseop_notices->activate_notice( $notice['slug'] ); - } - } - } - - /** - * Notice - Pro Promotion for WooCommerce - * - * @since 3.0 - * - * @return array - */ - function aioseop_notice_pro_promo_woocommerce() { - return array( - 'slug' => 'woocommerce_detected', - 'delay_time' => 0, - /* translators: %s is a placeholder, which means that it should not be translated. It will be replaced with the name of the premium version of the plugin, All in One SEO Pack Pro. */ - 'message' => sprintf( __( 'We have detected you are running WooCommerce. Upgrade to %s to unlock our advanced e-commerce features, including SEO for Product Categories and more.', 'all-in-one-seo-pack' ), 'All in One SEO Pack Pro' ), - - 'class' => 'notice-info', - 'target' => 'user', - 'screens' => array(), - 'action_options' => array( - array( - 'time' => 0, - 'text' => __( 'Upgrade', 'all-in-one-seo-pack' ), - 'link' => 'https://semperplugins.com/plugins/all-in-one-seo-pack-pro-version/?loc=woo', - 'dismiss' => false, - 'class' => 'button-primary button-orange', - ), - array( - 'time' => 2592000, // 30 days. - 'text' => __( 'No Thanks', 'all-in-one-seo-pack' ), - 'link' => '', - 'dismiss' => false, - 'class' => 'button-secondary', - ), - ), - ); - } - - /** - * Disable Notice for WooCommerce/Upgrade-to-Pro - * - * @todo Add to Pro version to disable message set by Non-Pro. - * - * @since 3.0 - * - * @global AIOSEOP_Notices $aioseop_notices - */ - function aioseop_notice_disable_woocommerce_detected_on_nonpro() { - global $aioseop_notices; - $aioseop_notices->deactivate_notice( 'woocommerce_detected' ); - } - - /** - * Set Notice on Activation to Review Plugin - * - * A delayed notice that is set during activation, or initialization (old installs), - * to later display a review/rate AIOSEOP plugin. Delay time: 12 days. - * Delay "...give me a week." 5 days - * - * @since 3.0 - * - * @global AIOSEOP_Notices $aioseop_notices - * - * @param boolean $update Updates the notice with new content and configurations. - * @param boolean $reset Notice are re-initiated. - */ - function aioseop_notice_set_activation_review_plugin( $update = false, $reset = false ) { - global $aioseop_notices; - - // TODO Optimize - Create a callback function/method to store most of the configurations (Avoid Database concept). - // Dynamic variable could be stored in the database. Config functions could go into a config file/folder. - $notice = aioseop_notice_review_plugin(); - - if ( $aioseop_notices->insert_notice( $notice ) ) { - // aioseop_footer_set_review(); - } elseif ( $update ) { - $aioseop_notices->update_notice( $notice ); - - if ( $reset ) { - $aioseop_notices->activate_notice( $notice['slug'] ); - // aioseop_footer_remove_review(); - // aioseop_footer_set_review(); - } - } - } - - /** - * Notice - Review Plugin - * - * @since 3.0 - * - * @return array Notice configuration. - */ - function aioseop_notice_review_plugin() { - return array( - 'slug' => 'activation_review_plugin', - 'delay_time' => 1036800, - 'target' => 'user', - 'screens' => array(), - 'class' => 'notice-info', - /* translators: %1$s is a placeholder, which means that it should not be translated. It will be replaced with the name of the plugin, All in One SEO Pack. */ - 'message' => sprintf( __( 'You have been using %1$s for a while now. That is awesome! If you like %1$s, then please leave us a 5-star rating. Huge thanks in advance!', 'all-in-one-seo-pack' ), AIOSEOP_PLUGIN_NAME ), - 'action_options' => array( - array( - 'time' => 0, - 'text' => __( 'Add a review', 'all-in-one-seo-pack' ), - 'link' => 'https://wordpress.org/support/plugin/all-in-one-seo-pack/reviews?rate=5#new-post', - 'dismiss' => false, - 'class' => '', - ), - array( - 'text' => __( 'Remind me later', 'all-in-one-seo-pack' ), - 'time' => 432000, - 'dismiss' => false, - 'class' => '', - ), - array( - 'time' => 0, - 'text' => __( 'No, thanks', 'all-in-one-seo-pack' ), - 'dismiss' => true, - 'class' => '', - ), - ), - ); - } -} diff --git a/aioseop_class.php b/aioseop_class.php index e24920abc..605f40bab 100644 --- a/aioseop_class.php +++ b/aioseop_class.php @@ -3507,18 +3507,19 @@ function add_hooks() { * * Checks if 'Search Engine Visibility' is enabled in Settings > Reading. * + * @todo Change to earlier hook. Before `admin_enqueue` if possible. + * * @since ? - * @since 2.4.2 Changed to `admin/functions-notice.php` with class AIOSEOP_Notices. + * @since 3.0 Changed to AIOSEOP_Notices class. * * @see `self::constructor()` with 'all_admin_notices' Filter Hook - * @uses `admin/functions-notice.php` aioseop_notice_set_blog_public_disabled() - * @uses `admin/functions-notice.php` aioseop_notice_disable_blog_public_disabled() */ function visibility_warning() { + global $aioseop_notices; if ( '0' === get_option( 'blog_public' ) ) { - aioseop_notice_set_blog_public_disabled(); + $aioseop_notices->activate_notice( 'blog_public_disabled' ); } elseif ( '1' === get_option( 'blog_public' ) ) { - aioseop_notice_disable_blog_public_disabled(); + $aioseop_notices->deactivate_notice( 'blog_public_disabled' ); } } @@ -3529,10 +3530,12 @@ function visibility_warning() { * @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_notice_activate_pro_promo_woocommerce(); + $aioseop_notices->activate_notice( 'woocommerce_detected' ); } else { - aioseop_notice_disable_woocommerce_detected_on_nonpro(); + global $aioseop_notices; + $aioseop_notices->deactivate_notice( 'woocommerce_detected' ); } } diff --git a/all_in_one_seo_pack.php b/all_in_one_seo_pack.php index 2b08ab729..abcb17a55 100644 --- a/all_in_one_seo_pack.php +++ b/all_in_one_seo_pack.php @@ -263,8 +263,9 @@ function aioseop_activate() { } $aiosp_activation = true; - require_once( AIOSEOP_PLUGIN_DIR . 'admin/class-aioseop-notices.php' ); - aioseop_notice_set_activation_review_plugin( false, true ); + require_once AIOSEOP_PLUGIN_DIR . 'admin/class-aioseop-notices.php'; + global $aioseop_notices; + $aioseop_notices->reset_notice( 'review_plugin' ); // These checks might be duplicated in the function being called. if ( ! is_network_admin() || ! isset( $_GET['activate-multi'] ) ) { @@ -390,6 +391,8 @@ function aiosp_action_links( $actions, $plugin_file, $action_links = array(), $p /** * Inits All-in-One-Seo plugin class. * + * @global AIOSEOP_Notices $aioseop_notices + * * @since ?? // When was this added? * @since 2.3.12.3 Loads third party compatibility class. */ @@ -438,7 +441,8 @@ function aioseop_init_class() { add_action( 'init', array( $aiosp, 'add_hooks' ) ); add_action( 'admin_init', array( $aioseop_updates, 'version_updates' ), 11 ); - aioseop_notice_set_activation_review_plugin(); + + add_action( 'admin_init', 'aioseop_review_plugin_notice' ); if ( defined( 'DOING_AJAX' ) && ! empty( $_POST ) && ! empty( $_POST['action'] ) && 'aioseop_ajax_scan_header' === $_POST['action'] ) { remove_action( 'init', array( $aiosp, 'add_hooks' ) ); @@ -453,6 +457,22 @@ function aioseop_init_class() { } } +if ( ! function_exists( 'aioseop_review_plugin_notice' ) ) { + /** + * Review Plugin Notice + * + * Activates the review notice. + * Note: This couldn't be used directly in `aioseop_init_class()` since ajax instances was causing + * the database options to reset. + * + * @since 3.0 + */ + function aioseop_review_plugin_notice() { + global $aioseop_notices; + $aioseop_notices->activate_notice( 'review_plugin' ); + } +} + if ( ! function_exists( 'aioseop_admin_enqueue_styles' ) ) { /** * Admin Enqueue Styles diff --git a/modules/aioseop_sitemap.php b/modules/aioseop_sitemap.php index 28e8acb9c..d8dbae959 100644 --- a/modules/aioseop_sitemap.php +++ b/modules/aioseop_sitemap.php @@ -435,10 +435,11 @@ public function sitemap_notices() { $sitemap_urls = $post_counts + $num_terms; + global $aioseop_notices; if ( 1001 > $sitemap_urls ) { - aioseop_notice_disable_sitemap_indexes(); + $aioseop_notices->deactivate_notice( 'sitemap_max_warning' ); } else { - aioseop_notice_activate_sitemap_indexes( false, true ); + $aioseop_notices->activate_notice( 'sitemap_max_warning' ); } } } diff --git a/tests/base/class-aioseop-notices-testcase.php b/tests/base/class-aioseop-notices-testcase.php index a7e55d88d..419af39a6 100644 --- a/tests/base/class-aioseop-notices-testcase.php +++ b/tests/base/class-aioseop-notices-testcase.php @@ -213,6 +213,28 @@ protected function validate_attr_notices( $notices ) { * @param array $notice Class variable `AIOSEOP_Notices::notices`. */ protected function validate_attr_notice( $notice ) { + $notices_attrs = array( + 'slug' => 'string', + 'time_set' => 'int', + 'time_start' => 'int', + ); + + foreach ( $notices_attrs as $attr_name => $attr_type ) { + $this->assertArrayHasKey( $attr_name, $notice, 'Index/Key not found in Notice Array.' ); + $this->assertInternalType( $attr_type, $notice[ $attr_name ], 'Invalid value type (' . $attr_type . ') in ' . $attr_name ); + } + } + + /** + * Validates notice in AIOSEOP_Notices::notices + * + * Checks to see if the array variables are correctly set. + * + * @since 3.0 + * + * @param array $notice Class variable `AIOSEOP_Notices::notices`. + */ + protected function validate_notice( $notice ) { $notices_attrs = array( 'slug' => 'string', 'delay_time' => 'int', @@ -221,6 +243,7 @@ protected function validate_attr_notice( $notice ) { 'class' => 'string', 'target' => 'string', 'screens' => 'array', + 'time_set' => 'int', 'time_start' => 'int', ); @@ -252,7 +275,7 @@ protected function validate_attr_notice( $notice ) { * * @return array */ - protected function mock_notice() { + public function mock_notice() { return array( 'slug' => 'notice_slug_1', 'delay_time' => 3600, // 1 Hour. @@ -303,7 +326,8 @@ protected function add_notice( $notice = array() ) { } // Insert Successful and activated. - $this->assertTrue( $aioseop_notices->insert_notice( $notice ) ); + add_filter( 'aioseop_admin_notice-' . $notice['slug'], array( $this, 'mock_notice' ) ); + $this->assertTrue( $aioseop_notices->activate_notice( $notice['slug'] ) ); $this->assertTrue( in_array( $notice['slug'], $notice, true ) ); $this->assertTrue( isset( $aioseop_notices->active_notices[ $notice['slug'] ] ) ); @@ -335,36 +359,37 @@ public function test_add_notice( $notice = array() ) { $notice = $this->mock_notice(); } + // Slug should be set. + $this->assertTrue( in_array( $notice['slug'], $notice, true ) ); + $this->assertFalse( empty( $notice['slug'] ) ); + // Shouldn't exist yet. - $this->assertFalse( $aioseop_notices->activate_notice( $notice['slug'] ) ); $this->assertFalse( $aioseop_notices->deactivate_notice( $notice['slug'] ) ); + $this->assertFalse( $aioseop_notices->reset_notice( $notice['slug'] ) ); - // Cannot update before insert. - $this->assertFalse( $aioseop_notices->update_notice( $notice ) ); + // Expexted fail - Cannot load notice. + $this->assertFalse( $aioseop_notices->activate_notice( '' ) ); // Insert Successful and activated. - $this->assertTrue( $aioseop_notices->insert_notice( $notice ) ); - $this->assertTrue( in_array( $notice['slug'], $notice, true ) ); - - // Re-Insert Failed. - $this->assertFalse( $aioseop_notices->insert_notice( $notice ) ); + add_filter( 'aioseop_admin_notice-' . $notice['slug'], array( $this, 'mock_notice' ) ); + $this->assertTrue( $aioseop_notices->activate_notice( $notice['slug'] ) ); + $this->assertTrue( isset( $aioseop_notices->active_notices[ $notice['slug'] ] ) ); // Deactivate. $this->assertTrue( $aioseop_notices->deactivate_notice( $notice['slug'] ) ); + $this->assertFalse( isset( $aioseop_notices->active_notices[ $notice['slug'] ] ) ); $this->assertFalse( $aioseop_notices->deactivate_notice( $notice['slug'] ) ); $this->assertFalse( isset( $aioseop_notices->active_notices[ $notice['slug'] ] ) ); - // Update success, but notice is not active. - $this->assertTrue( $aioseop_notices->update_notice( $notice ) ); - $this->assertFalse( isset( $aioseop_notices->active_notices[ $notice['slug'] ] ) ); + // Notice should still exist. + $this->assertTrue( isset( $aioseop_notices->notices[ $notice['slug'] ] ) ); // Activate. $this->assertTrue( $aioseop_notices->activate_notice( $notice['slug'] ) ); $this->assertTrue( isset( $aioseop_notices->active_notices[ $notice['slug'] ] ) ); - $this->assertNotNull( $aioseop_notices->active_notices[ $notice['slug'] ] ); - // Update Successful. - $this->assertTrue( $aioseop_notices->update_notice( $notice ) ); + // Remove. + $this->assertTrue( $aioseop_notices->remove_notice( $notice['slug'] ) ); } /** @@ -401,7 +426,8 @@ public function test_enqueue_scripts_on_screens( $screen_id, $url, $dir ) { $notice = $this->mock_notice(); // Insert Successful and activated. - $this->assertTrue( $aioseop_notices->insert_notice( $notice ) ); + add_filter( 'aioseop_admin_notice-notice_slug_1', array( $this, 'mock_notice' ) ); + $this->assertTrue( $aioseop_notices->activate_notice( $notice['slug'] ) ); $this->assertTrue( in_array( $notice['slug'], $notice, true ) ); $this->assertTrue( isset( $aioseop_notices->active_notices[ $notice['slug'] ] ) ); diff --git a/tests/classes/aioseop-notices/notices/test-blog-visibility.php b/tests/classes/aioseop-notices/notices/test-blog-visibility.php index 6767ce692..66ec5f2e4 100644 --- a/tests/classes/aioseop-notices/notices/test-blog-visibility.php +++ b/tests/classes/aioseop-notices/notices/test-blog-visibility.php @@ -29,7 +29,7 @@ class Test_Notice_BlogVisibility extends AIOSEOP_Notices_TestCase { * * @return array */ - protected function mock_notice() { + public function mock_notice() { return aioseop_notice_blog_visibility(); } } diff --git a/tests/classes/aioseop-notices/notices/test-plugin-review.php b/tests/classes/aioseop-notices/notices/test-plugin-review.php index a23a90c88..2102d893d 100644 --- a/tests/classes/aioseop-notices/notices/test-plugin-review.php +++ b/tests/classes/aioseop-notices/notices/test-plugin-review.php @@ -29,7 +29,7 @@ class Test_Plugin_Review extends AIOSEOP_Notices_TestCase { * * @return array */ - protected function mock_notice() { + public function mock_notice() { return aioseop_notice_review_plugin(); } } diff --git a/tests/classes/aioseop-notices/notices/test-pro-promo-woocommerce.php b/tests/classes/aioseop-notices/notices/test-pro-promo-woocommerce.php index e6dddfdaa..6a53d0756 100644 --- a/tests/classes/aioseop-notices/notices/test-pro-promo-woocommerce.php +++ b/tests/classes/aioseop-notices/notices/test-pro-promo-woocommerce.php @@ -31,7 +31,7 @@ class Test_Notice_ProPromoWooCommerce extends AIOSEOP_Notices_TestCase { * * @return array */ - protected function mock_notice() { + public function mock_notice() { return aioseop_notice_pro_promo_woocommerce(); } } diff --git a/tests/classes/aioseop-notices/notices/test-sitemap-indexes.php b/tests/classes/aioseop-notices/notices/test-sitemap-indexes.php index bbd1fa44c..8453da039 100644 --- a/tests/classes/aioseop-notices/notices/test-sitemap-indexes.php +++ b/tests/classes/aioseop-notices/notices/test-sitemap-indexes.php @@ -31,7 +31,7 @@ class Test_Notice_SitemapIndexes extends AIOSEOP_Notices_TestCase { * * @return array */ - protected function mock_notice() { + public function mock_notice() { return aioseop_notice_sitemap_indexes(); } } diff --git a/tests/classes/aioseop-notices/test-ajax.php b/tests/classes/aioseop-notices/test-ajax.php index 504580569..e17b9e006 100644 --- a/tests/classes/aioseop-notices/test-ajax.php +++ b/tests/classes/aioseop-notices/test-ajax.php @@ -99,7 +99,7 @@ public function clean_aioseop_notices() { * * @return array */ - protected function mock_notice() { + public function mock_notice() { return array( 'slug' => 'notice_delay_ajax', 'delay_time' => 0, @@ -137,7 +137,7 @@ protected function mock_notice() { * * @return array */ - protected function mock_notice_target_user() { + public function mock_notice_target_user() { return array( 'slug' => 'notice_slug_user', 'delay_time' => 0, @@ -188,7 +188,9 @@ protected function add_notice( $notice = array() ) { } // Insert Successful and activated. - $this->assertTrue( $aioseop_notices->insert_notice( $notice ) ); + add_filter( 'aioseop_admin_notice-notice_delay_ajax', array( $this, 'mock_notice' ) ); + add_filter( 'aioseop_admin_notice-notice_slug_user', array( $this, 'mock_notice_target_user' ) ); + $this->assertTrue( $aioseop_notices->activate_notice( $notice['slug'] ) ); $this->assertTrue( in_array( $notice['slug'], $notice, true ) ); $this->assertTrue( isset( $aioseop_notices->active_notices[ $notice['slug'] ] ) ); @@ -323,6 +325,7 @@ public function test_notice_action_delay_time() { global $aioseop_notices; $notice = $this->mock_notice(); $this->add_notice(); + $notice = $aioseop_notices->get_notice( $notice['slug'] ); /* * Action_Options 0 - No delay, no dismiss. @@ -356,7 +359,7 @@ public function test_notice_action_delay_time() { $this->assertArrayHasKey( $notice['slug'], $aioseop_notices->notices, 'AJAX Notice should still be added.' ); $this->assertArrayHasKey( $notice['slug'], $aioseop_notices->active_notices, 'AJAX Notice should still be active.' ); // Check delay time. - $expected_time = $aioseop_notices->notices[ $notice['slug'] ]['time_set'] + $aioseop_notices->notices[ $notice['slug'] ]['action_options']['0']['time']; + $expected_time = $aioseop_notices->notices[ $notice['slug'] ]['time_set'] + $notice['action_options']['0']['time']; // Add 1 to compensate for exact time display. $actual_time = $aioseop_notices->active_notices[ $notice['slug'] ] + 1; @@ -391,7 +394,7 @@ public function test_notice_action_delay_time() { $this->assertArrayHasKey( $notice['slug'], $aioseop_notices->active_notices, 'AJAX Notice should still be active.' ); // Check delay time. - $expected_time = $aioseop_notices->notices[ $notice['slug'] ]['time_set'] + $aioseop_notices->notices[ $notice['slug'] ]['action_options']['1']['time']; + $expected_time = $aioseop_notices->notices[ $notice['slug'] ]['time_set'] + $notice['action_options']['1']['time']; // Add 1 to compensate for exact time display. $actual_time = $aioseop_notices->active_notices[ $notice['slug'] ] + 1; @@ -423,7 +426,7 @@ public function test_notice_action_delay_time() { // Check if notice is still active. $this->assertArrayHasKey( $notice['slug'], $aioseop_notices->notices, 'AJAX Notice should still be added.' ); - $this->assertArrayNotHasKey( $notice['slug'], $aioseop_notices->active_notices, 'AJAX Notice should not be active still.' ); + $this->assertArrayHasKey( $notice['slug'], $aioseop_notices->dismissed, 'AJAX Notice should not be active still.' ); // No delay time to check. } diff --git a/tests/classes/aioseop-notices/test-delay-time.php b/tests/classes/aioseop-notices/test-delay-time.php index b52a2099b..991f93fd2 100644 --- a/tests/classes/aioseop-notices/test-delay-time.php +++ b/tests/classes/aioseop-notices/test-delay-time.php @@ -53,7 +53,7 @@ public function tearDown() { * * @return array */ - protected function mock_notice() { + public function mock_notice() { return array( 'slug' => 'notice_delay_delay_time', 'delay_time' => 2, // 1 Hour. diff --git a/tests/classes/aioseop-notices/test-enqueue-scripts.php b/tests/classes/aioseop-notices/test-enqueue-scripts.php index 5eb0fd411..3276cc6f3 100644 --- a/tests/classes/aioseop-notices/test-enqueue-scripts.php +++ b/tests/classes/aioseop-notices/test-enqueue-scripts.php @@ -42,7 +42,7 @@ public function setUp() { * * @return array */ - protected function mock_notice() { + public function mock_notice() { $rtn_notice = parent::mock_notice(); $rtn_notice['delay_time'] = 0; return $rtn_notice; @@ -82,7 +82,8 @@ public function test_enqueue_scripts_on_screens( $screen_id, $url, $dir ) { $notice = $this->mock_notice(); // Insert Successful and activated. - $this->assertTrue( $aioseop_notices->insert_notice( $notice ) ); + add_filter( 'aioseop_admin_notice-' . $notice['slug'], array( $this, 'mock_notice' ) ); + $this->assertTrue( $aioseop_notices->activate_notice( $notice['slug'] ) ); $this->assertTrue( in_array( $notice['slug'], $notice, true ) ); $this->assertTrue( isset( $aioseop_notices->active_notices[ $notice['slug'] ] ) ); diff --git a/tests/classes/aioseop-notices/test-init.php b/tests/classes/aioseop-notices/test-init.php index b10ffc704..5fedbf8ed 100644 --- a/tests/classes/aioseop-notices/test-init.php +++ b/tests/classes/aioseop-notices/test-init.php @@ -57,7 +57,7 @@ public function tearDown() { * * @return array */ - protected function mock_notice() { + public function mock_notice() { return array( 'slug' => 'notice_slug_1', 'delay_time' => 3600, // 1 Hour. diff --git a/tests/classes/aioseop-notices/test-user.php b/tests/classes/aioseop-notices/test-user.php index 68548335f..13b1606fb 100644 --- a/tests/classes/aioseop-notices/test-user.php +++ b/tests/classes/aioseop-notices/test-user.php @@ -61,7 +61,7 @@ public function tearDown() { * * @return array */ - protected function mock_notice() { + public function mock_notice() { return array( 'slug' => 'notice_slug_user', 'delay_time' => 0, // 1 Hour. From dc4b05427298138b0ebbe32986866181a59ab7e1 Mon Sep 17 00:00:00 2001 From: Michael Torbert Date: Wed, 29 May 2019 17:58:20 -0400 Subject: [PATCH 111/121] remove rewrite_titles option #69 (#2522) * remove rewrite_titles option #69 * Fix Grunt issues #69 * Fix Grunt issues (2) #69 --- admin/class-aioseop-helper.php | 2 - aioseop_class.php | 68 +++++++++------------------------ modules/aioseop_performance.php | 27 ++++++------- 3 files changed, 29 insertions(+), 68 deletions(-) diff --git a/admin/class-aioseop-helper.php b/admin/class-aioseop-helper.php index 0e60ccaff..a37c821ec 100644 --- a/admin/class-aioseop-helper.php +++ b/admin/class-aioseop-helper.php @@ -130,7 +130,6 @@ private function help_text_general() { 'aiosp_use_static_home_info' => __( 'Checking this option uses the title, description, and keywords set on your static Front Page.', 'all-in-one-seo-pack' ), // Title Settings. - 'aiosp_rewrite_titles' => __( "If enabled, all of your title and meta description tags will be rewritten, regardless of whether they were automatically generated by the plugin or entered by you manually. You can specify the title format for each post type or taxonomy below, as well as the description format.

                      For instance, all post titles will be rewritten as 'Post Title | Site Name' by default if you have this setting enabled. You can adjust each title format with your own text or by using our macros.", 'all-in-one-seo-pack' ), 'aiosp_home_page_title_format' => __( 'This controls the format of the title tag for your Homepage.', 'all-in-one-seo-pack' ) . '
                      ' . __( 'The following macros are supported:', 'all-in-one-seo-pack' ) . @@ -493,7 +492,6 @@ private function help_text_general() { 'aiosp_use_static_home_info' => 'https://semperplugins.com/documentation/home-page-settings/#use-static-front-page-instead', // Title Settings. - 'aiosp_rewrite_titles' => 'https://semperplugins.com/documentation/title-settings/#rewrite-titles', 'aiosp_home_page_title_format' => 'https://semperplugins.com/documentation/title-settings/#title-format-fields', 'aiosp_page_title_format' => 'https://semperplugins.com/documentation/title-settings/#title-format-fields', 'aiosp_post_title_format' => 'https://semperplugins.com/documentation/title-settings/#title-format-fields', diff --git a/aioseop_class.php b/aioseop_class.php index 605f40bab..7d952b3b1 100644 --- a/aioseop_class.php +++ b/aioseop_class.php @@ -138,15 +138,6 @@ function __construct() { 'default' => 0, 'condshow' => array( 'aiosp_can' => 'on' ), ), - 'rewrite_titles' => array( - 'name' => __( 'Rewrite Titles:', 'all-in-one-seo-pack' ), - 'default' => 1, - 'type' => 'radio', - 'initial_options' => array( - 1 => __( 'Enabled', 'all-in-one-seo-pack' ), - 0 => __( 'Disabled', 'all-in-one-seo-pack' ), - ), - ), 'force_rewrites' => array( 'name' => __( 'Force Rewrites:', 'all-in-one-seo-pack' ), 'default' => 1, @@ -170,73 +161,61 @@ function __construct() { 'name' => __( 'Home Page Title Format:', 'all-in-one-seo-pack' ), 'type' => 'text', 'default' => '%page_title%', - 'condshow' => array( 'aiosp_rewrite_titles' => 1 ), ), 'page_title_format' => array( 'name' => __( 'Page Title Format:', 'all-in-one-seo-pack' ), 'type' => 'text', 'default' => '%page_title% | %site_title%', - 'condshow' => array( 'aiosp_rewrite_titles' => 1 ), ), 'post_title_format' => array( 'name' => __( 'Post Title Format:', 'all-in-one-seo-pack' ), 'type' => 'text', 'default' => '%post_title% | %site_title%', - 'condshow' => array( 'aiosp_rewrite_titles' => 1 ), ), 'category_title_format' => array( 'name' => __( 'Category Title Format:', 'all-in-one-seo-pack' ), 'type' => 'text', 'default' => '%category_title% | %site_title%', - 'condshow' => array( 'aiosp_rewrite_titles' => 1 ), ), 'archive_title_format' => array( 'name' => __( 'Archive Title Format:', 'all-in-one-seo-pack' ), 'type' => 'text', 'default' => '%archive_title% | %site_title%', - 'condshow' => array( 'aiosp_rewrite_titles' => 1 ), ), 'date_title_format' => array( 'name' => __( 'Date Archive Title Format:', 'all-in-one-seo-pack' ), 'type' => 'text', 'default' => '%date% | %site_title%', - 'condshow' => array( 'aiosp_rewrite_titles' => 1 ), ), 'author_title_format' => array( 'name' => __( 'Author Archive Title Format:', 'all-in-one-seo-pack' ), 'type' => 'text', 'default' => '%author% | %site_title%', - 'condshow' => array( 'aiosp_rewrite_titles' => 1 ), ), 'tag_title_format' => array( 'name' => __( 'Tag Title Format:', 'all-in-one-seo-pack' ), 'type' => 'text', 'default' => '%tag% | %site_title%', - 'condshow' => array( 'aiosp_rewrite_titles' => 1 ), ), 'search_title_format' => array( 'name' => __( 'Search Title Format:', 'all-in-one-seo-pack' ), 'type' => 'text', 'default' => '%search% | %site_title%', - 'condshow' => array( 'aiosp_rewrite_titles' => 1 ), ), 'description_format' => array( 'name' => __( 'Description Format', 'all-in-one-seo-pack' ), 'type' => 'text', 'default' => '%description%', - 'condshow' => array( 'aiosp_rewrite_titles' => 1 ), ), '404_title_format' => array( 'name' => __( '404 Title Format:', 'all-in-one-seo-pack' ), 'type' => 'text', 'default' => __( 'Nothing found for %request_words%', 'all-in-one-seo-pack' ), - 'condshow' => array( 'aiosp_rewrite_titles' => 1 ), ), 'paged_format' => array( 'name' => __( 'Paged Format:', 'all-in-one-seo-pack' ), 'type' => 'text', 'default' => sprintf( ' - %s %%page%%', __( 'Part', 'all-in-one-seo-pack' ) ), - 'condshow' => array( 'aiosp_rewrite_titles' => 1 ), ), 'cpostactive' => array( 'name' => __( 'SEO on only these Content Types:', 'all-in-one-seo-pack' ), @@ -659,7 +638,6 @@ function __construct() { 'name' => __( 'Title Settings', 'all-in-one-seo-pack' ), 'help_link' => 'https://semperplugins.com/documentation/title-settings/', 'options' => array( - 'rewrite_titles', 'force_rewrites', 'home_page_title_format', 'page_title_format', @@ -1258,10 +1236,8 @@ function wp_title() { global $aioseop_options; $title = false; $post = $this->get_queried_object(); - if ( ! empty( $aioseop_options['aiosp_rewrite_titles'] ) ) { - $title = $this->get_aioseop_title( $post ); - $title = $this->apply_cf_fields( $title ); - } + $title = $this->get_aioseop_title( $post ); + $title = $this->apply_cf_fields( $title ); if ( false === $title ) { $title = $this->get_original_title(); @@ -2974,7 +2950,6 @@ function add_page_hooks() { 'type' => 'text', 'default' => '%post_title% | %site_title%', 'condshow' => array( - 'aiosp_rewrite_titles' => 1, 'aiosp_cpostactive\[\]' => $p, ), ); @@ -3006,7 +2981,6 @@ function add_page_hooks() { 'type' => 'text', 'default' => '%taxonomy_title% | %site_title%', 'condshow' => array( - 'aiosp_rewrite_titles' => 1, 'aiosp_taxactive\[\]' => $p, ), ); @@ -3267,36 +3241,31 @@ function filter_options( $options, $location ) { } if ( $location == null ) { $prefix = $this->prefix; - if ( isset( $options[ "{$prefix}rewrite_titles" ] ) && ( ! empty( $options[ "{$prefix}rewrite_titles" ] ) ) ) { - $options[ "{$prefix}rewrite_titles" ] = 1; - } 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; + return; } - if ( ! empty( $aioseop_options['aiosp_rewrite_titles'] ) ) { - $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 ); - } + $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 ); } } @@ -3852,7 +3821,7 @@ function check_rewrite_handler() { $force_rewrites = $aioseop_options['aiosp_force_rewrites']; } - if ( ! empty( $aioseop_options['aiosp_rewrite_titles'] ) && $force_rewrites ) { + if ( $force_rewrites ) { // Make the title rewrite as short as possible. if ( function_exists( 'ob_list_handlers' ) ) { $active_handlers = ob_list_handlers(); @@ -3868,11 +3837,10 @@ function check_rewrite_handler() { $this->log( 'another plugin interfering?' ); // If we get here there *could* be trouble with another plugin :(. $this->ob_start_detected = true; - if ( $this->option_isset( 'rewrite_titles' ) ) { // Try alternate method -- pdb. - $aioseop_options['aiosp_rewrite_titles'] = 0; - $force_rewrites = 0; - add_filter( 'wp_title', array( $this, 'wp_title' ), 20 ); - } + + // 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" ); diff --git a/modules/aioseop_performance.php b/modules/aioseop_performance.php index 1715b93a2..146c8e613 100644 --- a/modules/aioseop_performance.php +++ b/modules/aioseop_performance.php @@ -46,17 +46,15 @@ function __construct( $mod ) { ); global $aiosp, $aioseop_options; - if ( aioseop_option_isset( 'aiosp_rewrite_titles' ) && $aioseop_options['aiosp_rewrite_titles'] ) { - $this->default_options['force_rewrites'] = array( - 'name' => __( 'Force Rewrites:', 'all-in-one-seo-pack' ), - 'default' => 1, - 'type' => 'radio', - 'initial_options' => array( - 1 => __( 'Enabled', 'all-in-one-seo-pack' ), - 0 => __( 'Disabled', 'all-in-one-seo-pack' ), - ), - ); - } + $this->default_options['force_rewrites'] = array( + 'name' => __( 'Force Rewrites:', 'all-in-one-seo-pack' ), + 'default' => 1, + 'type' => 'radio', + 'initial_options' => array( + 1 => __( 'Enabled', 'all-in-one-seo-pack' ), + 0 => __( 'Disabled', 'all-in-one-seo-pack' ), + ), + ); $this->layout = array( 'default' => array( @@ -96,12 +94,9 @@ function display_options_filter( $options, $location ) { if ( $location == null ) { $options[ $this->prefix . 'force_rewrites' ] = 1; global $aiosp; - if ( aioseop_option_isset( 'aiosp_rewrite_titles' ) ) { - $opts = $aiosp->get_current_options( array(), null ); - $options[ $this->prefix . 'force_rewrites' ] = $opts['aiosp_force_rewrites']; - } + $opts = $aiosp->get_current_options( array(), null ); + $options[ $this->prefix . 'force_rewrites' ] = $opts['aiosp_force_rewrites']; } - return $options; } From 7cc95af6cb5ec38fa96c0d9265d8521865b18071 Mon Sep 17 00:00:00 2001 From: Arnaud Broes Date: Thu, 30 May 2019 11:38:58 +0200 Subject: [PATCH 112/121] Fix typo in PR template --- PULL_REQUEST_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md index 7879b2a51..4c290a3c2 100644 --- a/PULL_REQUEST_TEMPLATE.md +++ b/PULL_REQUEST_TEMPLATE.md @@ -27,7 +27,7 @@ _Put an `x` in the boxes that apply. You can also fill these out after creating -Don't assume the tester knows the entire backstory of the issue, and don't force him/her to decipher the code to try and figure out what -it's doing or how to test it. -Do provide step by step instructions on how to test. -Do note things to watch out for. --Do not what aspects the tester should try and break. +-Do note what aspects the tester should try and break. ## Further comments From 1fa7c3b1733f0646ee913836e61f93764b2bd9ea Mon Sep 17 00:00:00 2001 From: Arnaud Broes Date: Thu, 30 May 2019 16:02:57 +0200 Subject: [PATCH 113/121] Fix Grunt issues (3) #69 (#2530) --- aioseop_class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aioseop_class.php b/aioseop_class.php index 7d952b3b1..4357cef2c 100644 --- a/aioseop_class.php +++ b/aioseop_class.php @@ -3247,8 +3247,8 @@ function filter_options( $options, $location ) { } return $options; - } - + } + function template_redirect() { global $aioseop_options; From 1142db0a831fe67930eb2513fff19ba2f1026268 Mon Sep 17 00:00:00 2001 From: Michael Torbert Date: Thu, 30 May 2019 11:45:15 -0400 Subject: [PATCH 114/121] fix spelling error --- modules/aioseop_sitemap.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/aioseop_sitemap.php b/modules/aioseop_sitemap.php index d8dbae959..baf6dcc68 100644 --- a/modules/aioseop_sitemap.php +++ b/modules/aioseop_sitemap.php @@ -1354,7 +1354,7 @@ public function get_problem_files( $files, &$msg ) { $problem_files[] = $f; // This is causing all problem_files to be deleted automatically; which may be the intent. - // TODO Either create a seperate variable for this set of problem_files, or a final loop to clean problem_files before returning. + // TODO Either create a separate variable for this set of problem_files, or a final loop to clean problem_files before returning. foreach ( $problem_files as $f => $file ) { $files[ $f ] = realpath( $file ); $this->delete_file( realpath( $file ) ); From 7adf1566935ce8efb0272db7e08ed31fd48bf716 Mon Sep 17 00:00:00 2001 From: Michael Torbert Date: Thu, 30 May 2019 11:45:56 -0400 Subject: [PATCH 115/121] fix spelling error --- admin/class-aioseop-helper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admin/class-aioseop-helper.php b/admin/class-aioseop-helper.php index a37c821ec..090e5f750 100644 --- a/admin/class-aioseop-helper.php +++ b/admin/class-aioseop-helper.php @@ -654,7 +654,7 @@ private function help_text_sitemap() { 'aiosp_sitemap_addl_freq' => __( 'The frequency of the page.', 'all-in-one-seo-pack' ), 'aiosp_sitemap_addl_mod' => __( 'Last modified date of the page.', 'all-in-one-seo-pack' ), 'aiosp_sitemap_excl_terms' => __( 'Exclude any category, tag or custom taxonomy from the XML sitemap. Start typing the name of a category, tag or taxonomy term in the field and a dropdown will populate with the matching terms for you to select from.

                      This will also exclude any content belonging to the specified term. For example, if you exclude the "Uncategorized" category then all posts in that category will also be excluded from the sitemap.', 'all-in-one-seo-pack' ), - 'aiosp_sitemap_excl_pages' => __( 'Use page slugs or page IDs, seperated by commas, to exclude pages from the sitemap.', 'all-in-one-seo-pack' ), + 'aiosp_sitemap_excl_pages' => __( 'Use page slugs or page IDs, separated by commas, to exclude pages from the sitemap.', 'all-in-one-seo-pack' ), // Priorities. 'aiosp_sitemap_prio_homepage' => sprintf( __( 'Manually set the %1$s of your %2$s.', 'all-in-one-seo-pack' ), __( 'priority', 'all-in-one-seo-pack' ), __( 'Homepage', 'all-in-one-seo-pack' ) ), From 68e647c391568546ee466d23a1953ea2789eb5df Mon Sep 17 00:00:00 2001 From: Michael Torbert Date: Thu, 30 May 2019 17:06:07 -0400 Subject: [PATCH 116/121] update pro strings in commonstrings.php (#2532) * update pro strings #2525 * Fix some Grunt issues and fatal error #2525 * Fix other fatal error and Grunt issues #2525 * Order placeholders #2525 * Escape placeholdeers #2525 * Escape correct placeholders #2525 --- inc/commonstrings.php | 130 ++++++++++++++++++++++++++++-------------- 1 file changed, 88 insertions(+), 42 deletions(-) diff --git a/inc/commonstrings.php b/inc/commonstrings.php index 9d411e64c..98ca90410 100644 --- a/inc/commonstrings.php +++ b/inc/commonstrings.php @@ -12,67 +12,113 @@ class AIOSP_Common_Strings { /** * AIOSP_Common_Strings constructor. * - * We'll just put all the strings in the contruct for lack of a better. + * We'll just put all the strings in the contruct for lack of a better place. */ private function __construct() { - // Video sitemap strings. - __( 'Video Sitemap', 'all-in-one-seo-pack' ); - __( 'Show Only Posts With Videos', 'all-in-one-seo-pack' ); - __( 'Restrict Access to Video Sitemap', 'all-in-one-seo-pack' ); + // From aioseop-helper-filters.php. + __( 'This will be the license key received when the product was purchased. This is used for automatic upgrades.', 'all-in-one-seo-pack' ); + /* translators: %s is a placeholder, which means that it should not be translated. It will be replaced with the name of the plugin, All in One SEO Pack. */ + __( 'Use these checkboxes to select which Taxonomies you want to use %s with.', 'all-in-one-seo-pack' ); + __( 'This displays an SEO News widget on the dashboard.', 'all-in-one-seo-pack' ); + /* translators: %s is a placeholder, which means that it should not be translated. It will be replaced with the name of the plugin, All in One SEO Pack. */ + __( 'Check this to add %s to the Admin Bar for easy access to your SEO settings.', 'all-in-one-seo-pack' ); + /* translators: %s is a placeholder, which means that it should not be translated. It will be replaced with the name of the plugin, All in One SEO Pack. */ + __( 'Check this to move the %s menu item to the top of your WordPress Dashboard menu.', 'all-in-one-seo-pack' ); + __( 'Check this if you want to track outbound forms with Google Analytics.', 'all-in-one-seo-pack' ); + __( 'Check this if you want to track events with Google Analytics.', 'all-in-one-seo-pack' ); + __( 'Check this if you want to track url changes for single pages with Google Analytics.', 'all-in-one-seo-pack' ); + __( 'Check this if you want to track how long pages are in visible state with Google Analytics.', 'all-in-one-seo-pack' ); + /* translators: 'This option allows users to track media queries, allowing them to find out if users are viewing a responsive layout or not and which layout changes have been applied if the browser window has been resized by the user, see https://github.com/googleanalytics/autotrack/blob/master/docs/plugins/media-query-tracker.md. */ + __( 'Check this if you want to track media query matching and queries with Google Analytics.', 'all-in-one-seo-pack' ); + /* translators: The term "viewport" refers to the area of the page that is visible to the user, see https://www.w3schools.com/css/css_rwd_viewport.asp. */ + __( 'Check this if you want to track when elements are visible within the viewport with Google Analytics.', 'all-in-one-seo-pack' ); + __( 'Check this if you want to track how far down a user scrolls a page with Google Analytics.', 'all-in-one-seo-pack' ); + __( 'Check this if you want to track interactions with the official Facebook and Twitter widgets with Google Analytics.', 'all-in-one-seo-pack' ); + __( 'Check this if you want to ensure consistency in URL paths reported to Google Analytics.', 'all-in-one-seo-pack' ); + __( 'Your site title', 'all-in-one-seo-pack' ); + __( 'Your site description', 'all-in-one-seo-pack' ); + + /* translators: %s is a placeholder, which means that it should not be translated. It will be replaced with a noun. */ + __( 'The original title of the %s', 'all-in-one-seo-pack' ); + /* translators: %s is a placeholder, which means that it should not be translated. It will be replaced with a noun. */ + __( 'The description of the %s', 'all-in-one-seo-pack' ); + __( 'Taxonomy', 'all-in-one-seo-pack' ); + __( 'The following macros are supported:', 'all-in-one-seo-pack' ); + __( 'Click here for documentation on this setting', 'all-in-one-seo-pack' ); + __( 'Click here for documentation on this setting.', 'all-in-one-seo-pack' ); + __( 'Create RSS Sitemap as well.', 'all-in-one-seo-pack' ); + __( 'Notify search engines based on the selected schedule, and also update static sitemap daily if in use. (this uses WP-Cron, so make sure this is working properly on your server as well)', 'all-in-one-seo-pack' ); + __( 'Organize sitemap entries into distinct files in your sitemap. Enable this only if your sitemap contains over 50,000 URLs or the file is over 5MB in size.', 'all-in-one-seo-pack' ); + __( 'Allows you to specify the maximum number of posts in a sitemap (up to 50,000).', 'all-in-one-seo-pack' ); + __( 'Select which Post Types appear in your sitemap.', 'all-in-one-seo-pack' ); + __( 'Select which taxonomy archives appear in your sitemap', 'all-in-one-seo-pack' ); + __( 'Include Date Archives in your sitemap.', 'all-in-one-seo-pack' ); + __( 'Include Author Archives in your sitemap.', 'all-in-one-seo-pack' ); + __( 'Exclude Images in your sitemap.', 'all-in-one-seo-pack' ); + __( 'Create a compressed sitemap file in .xml.gz format.', 'all-in-one-seo-pack' ); + __( 'Places a link to your Sitemap.xml into your virtual Robots.txt file.', 'all-in-one-seo-pack' ); + __( 'Dynamically creates the XML sitemap instead of using a static file.', 'all-in-one-seo-pack' ); __( 'If checked, only posts that have videos in them will be displayed on the sitemap.', 'all-in-one-seo-pack' ); - __( 'Enable this option to only allow access to your sitemap by site administrators and major search engines.', 'all-in-one-seo-pack' ); - __( 'You do not have access to this page; try logging in as an administrator.', 'all-in-one-seo-pack' ); + __( 'Enable this option to look for videos in custom fields as well.', 'all-in-one-seo-pack' ); + __( 'URL to the page. This field accepts relative URLs or absolute URLs with the protocol specified.', 'all-in-one-seo-pack' ); + __( 'The priority of the page.', 'all-in-one-seo-pack' ); + __( 'The frequency of the page.', 'all-in-one-seo-pack' ); + __( 'Last modified date of the page.', 'all-in-one-seo-pack' ); + __( 'Entries from these taxonomy terms will be excluded from the sitemap.', 'all-in-one-seo-pack' ); + __( 'Use page slugs or page IDs, separated by commas, to exclude pages from the sitemap.', 'all-in-one-seo-pack' ); + /* translators: %1$s and %2$s are placeholders, which means that it should not be translated. They will be replaced with nouns in the application. */ + __( 'Manually set the %1$s of your %2$s.', 'all-in-one-seo-pack' ); + __( 'priority', 'all-in-one-seo-pack' ); + __( 'Homepage', 'all-in-one-seo-pack' ); + __( 'Post', 'all-in-one-seo-pack' ); + __( 'Taxonomies', 'all-in-one-seo-pack' ); + __( 'Archive Pages', 'all-in-one-seo-pack' ); + __( 'Author Pages', 'all-in-one-seo-pack' ); - // Update checker strings (incomplete... need to separate out html). - __( 'Purchase one now', 'all-in-one-seo-pack' ); - __( 'License Key is not set yet or invalid. ', 'all-in-one-seo-pack' ); - __( 'Need a license key?', 'all-in-one-seo-pack' ); - __( 'Notice: ', 'all-in-one-seo-pack' ); - __( 'Manage Licenses', 'all-in-one-seo-pack' ); + // From aioseop_taxonomy_functions.php. + __( 'SEO Title', 'all-in-one-seo-pack' ); + __( 'SEO Description', 'all-in-one-seo-pack' ); + __( 'SEO Keywords', 'all-in-one-seo-pack' ); - // These are Pro option strings. - /* translators: %s is a placeholder, which means that it should not be translated. It will be replaced with the name of the plugin, All in One SEO Pack. */ - sprintf( __( 'Use these checkboxes to select which Taxonomies you want to use %s with.', 'all-in-one-seo-pack' ), AIOSEOP_PLUGIN_NAME ); + // From functions_general.php. __( 'Show SEO News', 'all-in-one-seo-pack' ); __( 'Display Menu In Admin Bar:', 'all-in-one-seo-pack' ); __( 'Display Menu At The Top:', 'all-in-one-seo-pack' ); - __( 'This displays an SEO News widget on the dashboard.', 'all-in-one-seo-pack' ); - /* translators: %s is a placeholder, which means that it should not be translated. It will be replaced with the name of the plugin, All in One SEO Pack. */ - sprintf( __( 'Check this to add %s to the Admin Bar for easy access to your SEO settings.', 'all-in-one-seo-pack' ), AIOSEOP_PLUGIN_NAME ); - /* translators: %s is a placeholder, which means that it should not be translated. It will be replaced with the name of the plugin, All in One SEO Pack. */ - sprintf( __( 'Check this to move the %s menu item to the top of your WordPress Dashboard menu.', 'all-in-one-seo-pack' ), AIOSEOP_PLUGIN_NAME ); - __( '%s is almost ready.', 'all-in-one-seo-pack' ); - __( 'You must enter a valid License Key for it to work.', 'all-in-one-seo-pack' ); - __( "There is a new version of %1\$s available. Go to the plugins page for details.", 'all-in-one-seo-pack' ); - sprintf( __( 'Your license has expired. Please %1$sclick here%2$s to purchase a new one.', 'all-in-one-seo-pack' ), '', '' ); __( 'Track Outbound Forms:', 'all-in-one-seo-pack' ); __( 'Track Events:', 'all-in-one-seo-pack' ); - __( 'Track URL Changes:', 'all-in-one-seo-pack' ); + __( 'Track Url Changes:', 'all-in-one-seo-pack' ); __( 'Track Page Visibility:', 'all-in-one-seo-pack' ); __( 'Track Media Query:', 'all-in-one-seo-pack' ); __( 'Track Elements Visibility:', 'all-in-one-seo-pack' ); __( 'Track Page Scrolling:', 'all-in-one-seo-pack' ); __( 'Track Facebook and Twitter:', 'all-in-one-seo-pack' ); __( 'Ensure URL Consistency:', 'all-in-one-seo-pack' ); - __( 'Check this if you want to track outbound forms with Google Analytics.', 'all-in-one-seo-pack' ); - __( 'Check this if you want to track events with Google Analytics.', 'all-in-one-seo-pack' ); - __( 'Check this if you want to track URL changes for single pages with Google Analytics.', 'all-in-one-seo-pack' ); - __( 'Check this if you want to track how long pages are in visible state with Google Analytics.', 'all-in-one-seo-pack' ); - /* - Translators: 'This option allows users to track media queries, allowing them to find out if users are viewing a responsive layout or not and which layout changes - have been applied if the browser window has been resized by the user, see https://github.com/googleanalytics/autotrack/blob/master/docs/plugins/media-query-tracker.md. - */ - __( 'Check this if you want to track media query matching and queries with Google Analytics.', 'all-in-one-seo-pack' ); + // From sfwd_update_checker.php. + __( '%s is almost ready.', 'all-in-one-seo-pack' ); + /* translators: leave all the code inside the brackets < and > unchanged.*/ + __( 'You must enter a valid License Key for it to work.', 'all-in-one-seo-pack' ); + __( 'Need a license key?', 'all-in-one-seo-pack' ); + __( 'Purchase one now', 'all-in-one-seo-pack' ); + /* translators: leave all the code inside the brackets < and > unchanged.*/ + __( "There is a new version of %1\$s available. Go to the plugins page for details.", 'all-in-one-seo-pack' ); + /* translators: %1$s and %2$s are placeholders, which means that it should not be translated. They will be replaced with nouns in the application. */ + __( 'Your license has expired. Please %1$s click here %2$s to purchase a new one.', 'all-in-one-seo-pack' ); + __( 'Manage Licenses', 'all-in-one-seo-pack' ); + __( 'License Key is not set yet or invalid. ', 'all-in-one-seo-pack' ); + /* transalators: Following this alert is the text of the notice. For example... "Notice: you have not entered a valid license key". */ + __( 'Notice: ', 'all-in-one-seo-pack' ); - /* - Translators: The term 'viewport' refers to the area of the page that is visible to the user, see https://www.w3schools.com/css/css_rwd_viewport.asp. - */ - __( 'Check this if you want to track when elements are visible within the viewport with Google Analytics.', 'all-in-one-seo-pack' ); - __( 'Check this if you want to ensure consistency in URL paths reported to Google Analytics.', 'all-in-one-seo-pack' ); - __( 'Check this if you want to track how far down a user scrolls a page with Google Analytics.', 'all-in-one-seo-pack' ); - __( 'Check this if you want to track interactions with the official Facebook and Twitter widgets with Google Analytics.', 'all-in-one-seo-pack' ); + // From video_sitemap.php. + __( 'Video Sitemap', 'all-in-one-seo-pack' ); + __( 'Show Only Posts With Videos', 'all-in-one-seo-pack' ); + __( 'Include Custom Fields', 'all-in-one-seo-pack' ); + __( 'Video sitemap scan completed successfully!', 'all-in-one-seo-pack' ); + /* translators: This expression means "a small period/brief period of time". */ + __( 'a short while', 'all-in-one-seo-pack' ); + /* translators: %s is a placeholder, which means that it should not be translated. It will be replaced with a period of time, such as "5 minutes" or "a short while". */ + __( 'Video sitemap scan in progress. Please check again in %s.', 'all-in-one-seo-pack' ); } } From 7add4dd3c3cc70d0214a742666310e7e0897b7c7 Mon Sep 17 00:00:00 2001 From: Arnaud Broes Date: Fri, 31 May 2019 00:00:56 +0200 Subject: [PATCH 117/121] Improve look of meta box and menus (#2512) * Improve look of metabox and menus #1168 * Move new CSS to correct lines #1168 * Fix a few minor bugs #1168 * Add aria labels #1168 * Add missing double quote #1168 * Fix missing single quotes #1168 * Add CSS to JQuery Selectize input fields #1168 * Fix alignment of settings in Additional Pages section #1168 * Remove inline styles #1168 * Increase border-radius for radio buttons #1168 * Remove margin on Add Rule button & add margin to robots.txt textarea #1168 * Add gutter between Update Options button #1168 * Change colour of section titles to black #1168 * Improve robots.txt menu look #1168 * Increase width restriction on Preview Snippet container #1168 * Style "Analyze" button as secondary button #1168 * Increase width on textarea scrollbar #1168 * Fix RTL issues #1168 * Add missing aria-labels #1168 * Add missing closing bracket #1168 * PR comments #1168 * Add margin to activation button in Feature Manager #1168 * remove extra class for #1168 --- admin/aioseop_module_class.php | 6 +- admin/display/general-metaboxes.php | 2 +- admin/meta_import.php | 7 +- aioseop_class.php | 8 +- all_in_one_seo_pack.php | 10 ++ css/aioseop-font-icons-rtl.css | 8 ++ css/modules/aioseop_module-rtl.css | 53 +++++++-- css/modules/aioseop_module.css | 161 +++++++++++++++++++++----- js/quickedit_functions.min.js | 2 +- modules/aioseop_importer_exporter.php | 1 + modules/aioseop_robots.php | 1 - modules/aioseop_sitemap.php | 8 +- 12 files changed, 211 insertions(+), 56 deletions(-) create mode 100644 css/aioseop-font-icons-rtl.css diff --git a/admin/aioseop_module_class.php b/admin/aioseop_module_class.php index 234d8a011..8c99972bb 100644 --- a/admin/aioseop_module_class.php +++ b/admin/aioseop_module_class.php @@ -2341,7 +2341,7 @@ function get_option_html( $args ) { $buf .= '' . "\n"; break; case 'html': @@ -2737,12 +2737,12 @@ function display_settings_page( $location = null ) { 'page_options' => array( 'type' => 'hidden', 'value' => 'aiosp_home_description' ), 'Submit' => array( 'type' => 'submit', - 'class' => 'button-primary', + 'class' => 'aioseop_update_options_button button-primary', 'value' => __( 'Update Options', 'all-in-one-seo-pack' ) . ' »', ), 'Submit_Default' => array( 'type' => 'submit', - 'class' => 'button-secondary', + 'class' => 'aioseop_reset_settings_button button-secondary', 'value' => sprintf( __( 'Reset %s Settings to Defaults', 'all-in-one-seo-pack' ), $name ) . ' »', ), ); diff --git a/admin/display/general-metaboxes.php b/admin/display/general-metaboxes.php index 0e52cb0f5..e610bb4c3 100644 --- a/admin/display/general-metaboxes.php +++ b/admin/display/general-metaboxes.php @@ -126,7 +126,7 @@ static function display_extra_metaboxes( $add, $meta ) {

                      + class="button-primary" aria-label="">

                      - - + + diff --git a/aioseop_class.php b/aioseop_class.php index 4357cef2c..56708ccf2 100644 --- a/aioseop_class.php +++ b/aioseop_class.php @@ -3080,10 +3080,14 @@ public function admin_enqueue_scripts( $hook_suffix ) { * @return mixed */ function filter_submit( $submit ) { - $submit['Submit_Default']['value'] = __( 'Reset General Settings to Defaults', 'all-in-one-seo-pack' ) . ' »'; + $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' => 'button-secondary', + 'class' => 'aioseop_reset_settings_button button-secondary', 'value' => __( 'Reset ALL Settings to Defaults', 'all-in-one-seo-pack' ) . ' »', ); diff --git a/all_in_one_seo_pack.php b/all_in_one_seo_pack.php index abcb17a55..8038743eb 100644 --- a/all_in_one_seo_pack.php +++ b/all_in_one_seo_pack.php @@ -499,6 +499,16 @@ function aioseop_admin_enqueue_styles( $hook_suffix ) { AIOSEOP_VERSION ); } + if ( function_exists( 'is_rtl' ) && is_rtl() ) { + if ( ! wp_style_is( 'aioseop-font-icons-rtl', 'registered' ) && ! wp_style_is( 'aioseop-font-icons-rtl', 'enqueued' ) ) { + wp_enqueue_style( + 'aioseop-font-icons-rtl', + AIOSEOP_PLUGIN_URL . 'css/aioseop-font-icons-rtl.css', + array(), + AIOSEOP_VERSION + ); + } + } } } diff --git a/css/aioseop-font-icons-rtl.css b/css/aioseop-font-icons-rtl.css new file mode 100644 index 000000000..016af6141 --- /dev/null +++ b/css/aioseop-font-icons-rtl.css @@ -0,0 +1,8 @@ +/** + * RTL overrides for Font Icons. + * + * @since 3.0.0 + */ +.aioseop-label-quickedit { + padding: 0 20px 0 0; +} diff --git a/css/modules/aioseop_module-rtl.css b/css/modules/aioseop_module-rtl.css index 8c0bc0d97..7e4c33922 100644 --- a/css/modules/aioseop_module-rtl.css +++ b/css/modules/aioseop_module-rtl.css @@ -45,14 +45,6 @@ direction: rtl } -.aioseop input[type="text"] { - padding: 2px 10px 2px 0 -} - -.aioseop textarea { - padding: 10px 10px 0 0 -} - .aioseop_help_text_div { text-align: right; margin: 8px 0 10px 0 @@ -317,3 +309,48 @@ form#aiosp_settings_form, #aioseop-about .aioseop_metabox_text ul { padding-right: 15px; } + +.aioseop input[readonly] { + text-align: center; +} + +.aioseop_input input[type="checkbox"]:before { + margin: -4px -4px 0 0; +} + +.aioseop_header_tabs li:first-child a.aioseop_header_tab { + border: none; +} + +.aioseop_feature h3 { + text-align: left; +} + +.aioseop_feature .flag:before { + border-width: 13.5px 4px 15px 10px; +} + +#aioseop_coming_soon, #aioseop_coming_soon2 b { + text-align: center; +} + +.aioseop_feature p.aioseop_desc { + text-align: right; +} + +#aioseop_coming_soon .flag.pro { + height: 17.5px; + font-size: 13.5px; +} + +#aiosp_robots_default_metabox table.aioseop_table { + margin: 5px 10px 10px 0; +} + +textarea.robots-text { + margin: 0 10px 0 10px; +} + +.All_in_One_SEO_Pack_Feature_Manager > .aioseop_right_sidebar.aioseop_options_wrapper { + margin: 30px 0 0 0; +} \ No newline at end of file diff --git a/css/modules/aioseop_module.css b/css/modules/aioseop_module.css index a4757a29c..ce6ce06fa 100644 --- a/css/modules/aioseop_module.css +++ b/css/modules/aioseop_module.css @@ -42,9 +42,10 @@ .aioseop_help_text_link:before { content: "\f223"; - font-size: 27px; + font-size: 22px; font-family: dashicons; vertical-align: middle; + margin-right: 4px; } #aioseop-support .aioseop_metabox_text, @@ -83,21 +84,23 @@ .aioseop_tabs .aioseop_meta_box_help, .aioseop_tabs .aioseop_meta_box_help:active { margin-top: 4px; + margin-right: 45px; } .aioseop_label { color: #5F5F5F; - font-weight: bold; + font-weight: 600; line-height: 19px; display: inline-block; float: left; text-align: left; - font-family: 'Open Sans', sans-serif; + font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen-Sans, Ubuntu, Cantarell, Helvetica Neue, sans-serif; padding: 2px 0; width: 81%; min-width: 120px; max-width: 250px; cursor: default; + font-size: 13.5px; } .aioseop_option_div { @@ -114,7 +117,7 @@ .aioseop input[type="text"], .aioseop input[type="url"] { color: #515151; min-height: 35px; - padding: 10px 0 10px 10px; + padding: 10px; font-size: 14px; width: 95%; max-width: 600px; @@ -122,8 +125,8 @@ .aioseop textarea { color: #515151; - padding: 10px 0 0 10px; - margin: 0; + padding: 10px; + margin: 1px; font-size: 14px; line-height: 25px; width: 95%; @@ -131,6 +134,33 @@ min-height: 36px; } +.aioseop input, textarea { + border-radius: 4px; + border: 1px solid #8d96a0; + margin: 1px; + font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif !important; +} + +.aioseop input:focus, textarea:focus { + box-shadow: 0 0 0 1px #007cba; +} + +.aioseop textarea::-webkit-scrollbar { + width: 12px; +} + +.aioseop textarea::-webkit-scrollbar-track { + background: #f1f1f1; +} + +.aioseop textarea::-webkit-scrollbar-thumb { + background: #aeaeae; +} + +.aioseop textarea::-webkit-scrollbar-thumb:hover { + background: #888; +} + .aioseop_help_text_div { text-align: left; width: 100%; @@ -161,6 +191,7 @@ sans-serif; border-bottom: 1px solid #CCC; width: 100%; + margin: 8px 0 0 0; } .aioseop_head_nav_tab { @@ -326,7 +357,7 @@ } .aioseop_metabox_text h2 { - font-size: 14px; + font-size: 30px; padding: 0; font-weight: bold; line-height: 29px; @@ -355,7 +386,7 @@ .aioseop input[readonly] { background-color: #EEE; - margin: 5px 0 5px 0 !important; + margin: 5px 1px 5px 1px !important; } .aioseop_settings_left { @@ -398,7 +429,7 @@ body.all-in-one-seo_page_all-in-one-seo-pack-pro-aioseop_feature_manager .aioseo .aioseop_right_sidebar { float: right; - margin-top: 35px; + margin-top: 55px; } #aiosp_settings_form .button-primary.hidden { @@ -423,7 +454,7 @@ form#edittag div#aiosp_sitemap_exclude_wrapper { } .All_in_One_SEO_Pack_Feature_Manager > .aioseop_right_sidebar.aioseop_options_wrapper { - margin-top: 10px; + margin-top: 30px; } div#aiosp_feature_manager_metabox .inside { @@ -443,7 +474,7 @@ div.aioseop_feature { -webkit-border-radius: 3px; border-radius: 3px; background: white; - padding: 10px 0 0; + padding: 10px 0; -webkit-box-shadow: inset 0 1px 0 #fff, inset 0 0 20px rgba(0, 0, 0, 0.05), 0 1px 2px rgba(0, 0, 0, 0.1); @@ -537,8 +568,9 @@ div.aioseop_feature { .aioseop_feature .feature_button { float: right; - margin-bottom: 10px; - margin-right: 10px; + display: inline-block; + position: relative; + margin: 0 10px 10px 0; min-width: 80px; text-align: center; } @@ -792,15 +824,6 @@ div.aioseop_feature#aioseop_coming_soon2 .aioseop_featured_image { padding: 0; } -#aiosp_sitemap_addl_pages_metabox .aioseop_wrapper .aioseop_input, -#aiosp_video_sitemap_addl_pages_metabox .aioseop_wrapper .aioseop_input { - display: inline-block; - vertical-align: middle; - width: 25%; - min-width: 120px; - height: 70px; -} - #aiosp_sitemap_addl_pages_metabox .aioseop_wrapper .aioseop_top_label, #aiosp_video_sitemap_addl_pages_metabox .aioseop_wrapper .aioseop_top_label { width: 70%; @@ -848,6 +871,11 @@ div.aioseop_feature#aioseop_coming_soon2 .aioseop_featured_image { max-width: 600px; } +.selectize-input { + padding: 10px 0 10px 10px !important; + border: 1px solid #8d96a0 !important; +} + table.aioseop_table tr:nth-child(odd) { background-color: #EEE; } @@ -936,7 +964,7 @@ table.aioseop_table td, table.aioseop_table th { } #aiosp_settings_form .postbox { - margin: 0 0 20px 0; + margin: 20px 0 0 0; } .aioseop_settings_left .postbox { @@ -999,7 +1027,6 @@ table.aioseop_table td, table.aioseop_table th { float: left; width: 92%; max-width: 100%; - margin: 0 23px 0 13px; } #aiosp_sitemap_status_metabox .handlediv.button-link { @@ -1048,10 +1075,29 @@ table.aioseop_table td, table.aioseop_table th { .aioseop_input input[type="checkbox"], .aioseop_input input[type="radio"] { + border: 1.25px solid #6c7781; vertical-align: text-bottom; margin-top: 8px; } +.aioseop_input input[type="checkbox"]:before { + margin: -3px 0 0 -5px; + color: white; +} + +.aioseop_input input[type="radio"] { + border-radius: 8px; +} + +.aioseop_input input[type="radio"]:before { + content: none !important; +} + +.aioseop_input input[type="radio"]:checked, +.aioseop_input input[type="checkbox"]:checked { + background: #11a0d2; +} + #aiosp_importer_exporter_import_export_help_wrapper .aioseop_option_div { max-height: initial; } @@ -1145,7 +1191,8 @@ div.aioseop_notice a.aioseop_dismiss_link { } .aioseop_input select { - margin: 7px 0; + border-radius: 4px; + border: 1px solid #8d96a0; } .aioseop_help_text ul { @@ -1173,6 +1220,7 @@ div.aioseop_notice a.aioseop_dismiss_link { border-bottom: none !important; padding: 0em 0.5em !important; color: #5F5F5F; + font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif !important; } .aioseop_tab { @@ -1386,11 +1434,12 @@ div.sfwd_debug_error { * */ div#aiosp_snippet_wrapper { - border: 1px solid #888; - clear: both; - padding: 10px 10px 0; - max-width: 97%; - margin-bottom: 15px; + border-radius: 4px; + border: 1px solid #8d96a0; + clear: both; + padding: 10px 10px 0; + max-width: 97%; + margin-bottom: 15px; } #aiosp_snippet_wrapper > .aioseop_input:first-child { @@ -1408,6 +1457,7 @@ div#aiosp_snippet_wrapper .aioseop_option_label { div#aiosp_snippet_wrapper .aioseop_input.aioseop_top_label .aioseop_option_input { margin: 0; + width: 99%; } div#aioseop_snippet { @@ -1465,11 +1515,60 @@ div#aioseop_snippet > div > span { } textarea.robots-text { + color: black; background-color: #eee; - width: 100%; height: 100%; + margin: 0 0 0 10px; } div#aiosp_sitemap_status_metabox .toggle-indicator { display:none; } + +.required.email { + border-radius: 4px; + border: 1px solid #8d96a0; + margin: 1px; + font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif !important; +} + +.ui-sortable-handle span { + font-size: 16px; + font-weight: 600; + font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen-Sans, Ubuntu, Cantarell, Helvetica Neue, sans-serif; + color: black; +} + +.aioseop_file_upload { + border: none !important; +} + +.aioseop_upload_image_button { + float: left; + margin: 0 0 5px 0 !important; +} + +.aioseop_delete_files_button { + margin: 0 5px 10px 0 !important; +} + +.aioseop_rename_files_button { + margin: 0 0 10px 0 !important; +} + +.aioseop_update_options_button, +.aioseop_reset_settings_button { + margin: 10px 0 0 0 !important; +} + +#aiosp_robots_default_metabox .aioseop_option_label { + margin-left: 10px; +} + +#aiosp_robots_default_metabox .add-edit-rule { + margin-left: 5px; +} + +#aiosp_file_editor_htaccess_metabox { + margin: 0 !important; +} diff --git a/js/quickedit_functions.min.js b/js/quickedit_functions.min.js index dbb3efec1..0a4caa0e9 100644 --- a/js/quickedit_functions.min.js +++ b/js/quickedit_functions.min.js @@ -1 +1 @@ -function aioseop_ajax_edit_meta_form(e,i,t){var a,o=jQuery("#aioseop_"+i+"_"+e),s=jQuery("#aioseop_label_"+i+"_"+e).text(),_=o.html();a='",a+='",o.html(a),o.attr("class","aioseop_mpc_admin_meta_options aio_editing"),jQuery("#aioseop_"+i+"_cancel_"+e).click(function(){o.html(_),o.attr("class","aioseop_mpc_admin_meta_options")}),jQuery("#aioseop_"+i+"_save_"+e).click(function(){var a=jQuery("#aioseop_new_"+i+"_"+e).val();handle_post_meta(e,a,i,t)})}function handle_post_meta(e,i,t,o){jQuery("div#aioseop_"+t+"_"+e).fadeOut("fast",function(){var a='
                      Please wait…
                      ',jQuery("div#aioseop_"+t+"_"+e).fadeIn("fast",function(){var a=new sack(aioseopadmin.requestUrl);a.execute=1,a.method="POST",a.setVar("action","aioseop_ajax_save_meta"),a.setVar("post_id",e),a.setVar("new_meta",i),a.setVar("target_meta",t),a.setVar("_inline_edit",jQuery("input#_inline_edit").val()),a.setVar("_nonce",o),a.onError=function(){alert("Ajax error on saving title")},a.runAJAX()}),jQuery("div#aioseop_"+t+"_"+e).html(a),jQuery("div#aioseop_"+t+"_"+e).attr("class","aioseop_mpc_admin_meta_options")})}jQuery(document).on("click",".visibility-notice",function(){jQuery.ajax({url:ajaxurl,data:{action:"aioseo_dismiss_visibility_notice"}})}),jQuery(document).on("click",".yst_notice",function(){jQuery.ajax({url:ajaxurl,data:{action:"aioseo_dismiss_yst_notice"}})}),jQuery(document).on("click",".woo-upgrade-notice",function(){jQuery.ajax({url:ajaxurl,data:{action:"aioseo_dismiss_woo_upgrade_notice"}})}),jQuery(document).on("click",".sitemap_max_urls_notice",function(){jQuery.ajax({url:ajaxurl,data:{action:"aioseo_dismiss_sitemap_max_url_notice"}})}); \ No newline at end of file +function aioseop_ajax_edit_meta_form(e,i,t){var a,o=jQuery("#aioseop_"+i+"_"+e),s=jQuery("#aioseop_label_"+i+"_"+e).text(),_=o.html();a='",a+='",o.html(a),o.attr("class","aioseop_mpc_admin_meta_options aio_editing"),jQuery("#aioseop_"+i+"_cancel_"+e).click(function(){o.html(_),o.attr("class","aioseop_mpc_admin_meta_options")}),jQuery("#aioseop_"+i+"_save_"+e).click(function(){var a=jQuery("#aioseop_new_"+i+"_"+e).val();handle_post_meta(e,a,i,t)})}function handle_post_meta(e,i,t,o){jQuery("div#aioseop_"+t+"_"+e).fadeOut("fast",function(){var a='',a+='
                      Please wait…
                      ',jQuery("div#aioseop_"+t+"_"+e).fadeIn("fast",function(){var a=new sack(aioseopadmin.requestUrl);a.execute=1,a.method="POST",a.setVar("action","aioseop_ajax_save_meta"),a.setVar("post_id",e),a.setVar("new_meta",i),a.setVar("target_meta",t),a.setVar("_inline_edit",jQuery("input#_inline_edit").val()),a.setVar("_nonce",o),a.onError=function(){alert("Ajax error on saving title")},a.runAJAX()}),jQuery("div#aioseop_"+t+"_"+e).html(a),jQuery("div#aioseop_"+t+"_"+e).attr("class","aioseop_mpc_admin_meta_options")})}jQuery(document).on("click",".visibility-notice",function(){jQuery.ajax({url:ajaxurl,data:{action:"aioseo_dismiss_visibility_notice"}})}),jQuery(document).on("click",".yst_notice",function(){jQuery.ajax({url:ajaxurl,data:{action:"aioseo_dismiss_yst_notice"}})}),jQuery(document).on("click",".woo-upgrade-notice",function(){jQuery.ajax({url:ajaxurl,data:{action:"aioseo_dismiss_woo_upgrade_notice"}})}),jQuery(document).on("click",".sitemap_max_urls_notice",function(){jQuery.ajax({url:ajaxurl,data:{action:"aioseo_dismiss_sitemap_max_url_notice"}})}); \ No newline at end of file diff --git a/modules/aioseop_importer_exporter.php b/modules/aioseop_importer_exporter.php index 168dd520b..496430d6a 100644 --- a/modules/aioseop_importer_exporter.php +++ b/modules/aioseop_importer_exporter.php @@ -23,6 +23,7 @@ function __construct() { 'name' => __( 'Import', 'all-in-one-seo-pack' ), 'default' => '', 'type' => 'file', + 'class' => 'aioseop_file_upload', 'save' => false, ), 'export_choices' => array( diff --git a/modules/aioseop_robots.php b/modules/aioseop_robots.php index 951355b94..8de1ac429 100644 --- a/modules/aioseop_robots.php +++ b/modules/aioseop_robots.php @@ -54,7 +54,6 @@ function __construct() { 'type' => 'submit', 'class' => 'button-primary add-edit-rule', 'name' => __( 'Add Rule', 'all-in-one-seo-pack' ) . ' »', - 'style' => 'margin-left: 20px;', 'label' => 'none', 'save' => false, 'value' => 1, diff --git a/modules/aioseop_sitemap.php b/modules/aioseop_sitemap.php index baf6dcc68..c69f0fd6b 100644 --- a/modules/aioseop_sitemap.php +++ b/modules/aioseop_sitemap.php @@ -299,27 +299,23 @@ public function __construct() { 'addl_url' => array( 'name' => __( 'Page URL', 'all-in-one-seo-pack' ), 'type' => 'url', - 'label' => 'top', 'save' => false, ), 'addl_prio' => array( 'name' => __( 'Page Priority', 'all-in-one-seo-pack' ), 'type' => 'select', 'initial_options' => $prio, - 'label' => 'top', 'save' => false, ), 'addl_freq' => array( 'name' => __( 'Page Frequency', 'all-in-one-seo-pack' ), 'type' => 'select', 'initial_options' => $freq, - 'label' => 'top', 'save' => false, ), 'addl_mod' => array( 'name' => __( 'Last Modified', 'all-in-one-seo-pack' ), 'type' => 'date', - 'label' => 'top', 'save' => false, 'class' => 'aiseop-date', ), @@ -1388,8 +1384,8 @@ public function sitemap_warning( $files ) { $msg .= "\n"; } $msg .= "\n"; - $msg .= " "; - $msg .= ""; + $msg .= ""; + $msg .= " "; $msg = '
                      ' . $msg . '
                      '; } From 59bc1f4233f3263bd21402e7e61cf235df9e7739 Mon Sep 17 00:00:00 2001 From: Arnaud Broes Date: Fri, 31 May 2019 00:22:48 +0200 Subject: [PATCH 118/121] Don't run conflicting shortcodes in autogenerated descriptions (#2488) * Don't run conflicting shortcodes in autogenerated descriptions #1747 * Add unit test #1747 * Check all shortcodes for conflicts #1747 * Fix for shortcodes in Gutenberg Classic blocks #1747 * Run shortcodes after conflicting shortcodes #1168 * Concatenate $gallery_content #1747 --- aioseop_class.php | 2 +- inc/aioseop_functions.php | 60 + modules/aioseop_opengraph.php | 3848 ++++++++--------- modules/aioseop_sitemap.php | 2 +- .../test-shortcodes-in-description.php | 72 + tests/modules/sitemap/test-sitemap.php | 2 +- 6 files changed, 2059 insertions(+), 1927 deletions(-) create mode 100644 tests/modules/general/test-shortcodes-in-description.php diff --git a/aioseop_class.php b/aioseop_class.php index 56708ccf2..372c17e5b 100644 --- a/aioseop_class.php +++ b/aioseop_class.php @@ -2372,7 +2372,7 @@ function get_post_description( $post ) { if ( ! AIOSEOPPRO || ( AIOSEOPPRO && apply_filters( $this->prefix . 'generate_descriptions_from_content', true, $post ) ) ) { $content = $post->post_content; if ( ! empty( $aioseop_options['aiosp_run_shortcodes'] ) ) { - $content = do_shortcode( $content ); + $content = aioseop_do_shortcodes( $content ); } $description = $content; } else { diff --git a/inc/aioseop_functions.php b/inc/aioseop_functions.php index 5e86947ef..6d1bdc47d 100644 --- a/inc/aioseop_functions.php +++ b/inc/aioseop_functions.php @@ -1142,3 +1142,63 @@ function aioseop_get_menu_icon() { return 'data:image/svg+xml;base64,' . base64_encode( $svg ); } } + +/** + * Runs shortcodes in autogenerated titles & descriptions. + * + * @since 3.0.0 + * + * @param string $content Content of the post + * + * @return string $content Content after shortcodes have been run. + */ +function aioseop_do_shortcodes( $content ) { + $conflicting_shortcodes = array( + 'WooCommerce Login' => '[woocommerce_my_account]', + ); + + $rtn_conflict_shortcodes = array(); + foreach ( $conflicting_shortcodes as $shortcode ) { + // Second check is needed for shortcodes in Gutenberg Classic blocks. + if ( stripos( $content, $shortcode, 0 ) || 0 === stripos( $content, $shortcode, 0 ) ) { + global $shortcode_tags; + $shortcode_tag = str_replace( array('[', ']'), '', $shortcode ); + if ( array_key_exists( $shortcode_tag, $shortcode_tags ) ) { + $rtn_conflict_shortcodes[ $shortcode_tag ] = $shortcode_tags[ $shortcode_tag ]; + } + } + } + + if ( ! empty( $rtn_conflict_shortcodes ) ) { + return aioseop_do_shortcode_helper( $content, $rtn_conflict_shortcodes ); + } + + return do_shortcode( $content ); +} + +/** + * Ignores shortcodes that are known to conflict. + * Acts as a helper function for aioseop_do_shortcodes(). + * + * @since 3.0.0 + * + * @param string $content Content of the post + * @param array $conflicting_shortcodes List of conflicting shortcodes + * + * @return string $content Content after shortcodes have been run whilst ignoring conflicting shortcodes. + */ +function aioseop_do_shortcode_helper( $content, $conflicting_shortcodes ) { + + foreach ( $conflicting_shortcodes as $shortcode_tag => $shortcode_callback ) { + remove_shortcode( $shortcode_tag ); + } + + $content = do_shortcode( $content ); + + // Adds shortcodes back since remove_shortcode() disables them site-wide. + foreach ( $conflicting_shortcodes as $shortcode_tag => $shortcode_callback ) { + add_shortcode( $shortcode_tag, $shortcode_callback ); + } + + return $content; +} diff --git a/modules/aioseop_opengraph.php b/modules/aioseop_opengraph.php index ae48662d2..ce1348342 100644 --- a/modules/aioseop_opengraph.php +++ b/modules/aioseop_opengraph.php @@ -1,1924 +1,1924 @@ -name = __( 'Social Meta', 'all-in-one-seo-pack' ); // Human-readable name of the plugin - $this->prefix = 'aiosp_opengraph_'; // option prefix - $this->file = __FILE__; // the current file - $this->fb_object_types = array( - 'Activities' => array( - 'activity' => __( 'Activity', 'all-in-one-seo-pack' ), - 'sport' => __( 'Sport', 'all-in-one-seo-pack' ), - ), - 'Businesses' => array( - 'bar' => __( 'Bar', 'all-in-one-seo-pack' ), - 'company' => __( 'Company', 'all-in-one-seo-pack' ), - 'cafe' => __( 'Cafe', 'all-in-one-seo-pack' ), - 'hotel' => __( 'Hotel', 'all-in-one-seo-pack' ), - 'restaurant' => __( 'Restaurant', 'all-in-one-seo-pack' ), - ), - 'Groups' => array( - 'cause' => __( 'Cause', 'all-in-one-seo-pack' ), - 'sports_league' => __( 'Sports League', 'all-in-one-seo-pack' ), - 'sports_team' => __( 'Sports Team', 'all-in-one-seo-pack' ), - ), - 'Organizations' => array( - 'band' => __( 'Band', 'all-in-one-seo-pack' ), - 'government' => __( 'Government', 'all-in-one-seo-pack' ), - 'non_profit' => __( 'Non Profit', 'all-in-one-seo-pack' ), - 'school' => __( 'School', 'all-in-one-seo-pack' ), - 'university' => __( 'University', 'all-in-one-seo-pack' ), - ), - 'People' => array( - 'actor' => __( 'Actor', 'all-in-one-seo-pack' ), - 'athlete' => __( 'Athlete', 'all-in-one-seo-pack' ), - 'author' => __( 'Author', 'all-in-one-seo-pack' ), - 'director' => __( 'Director', 'all-in-one-seo-pack' ), - 'musician' => __( 'Musician', 'all-in-one-seo-pack' ), - 'politician' => __( 'Politician', 'all-in-one-seo-pack' ), - 'profile' => __( 'Profile', 'all-in-one-seo-pack' ), - 'public_figure' => __( 'Public Figure', 'all-in-one-seo-pack' ), - ), - 'Places' => array( - 'city' => __( 'City', 'all-in-one-seo-pack' ), - 'country' => __( 'Country', 'all-in-one-seo-pack' ), - 'landmark' => __( 'Landmark', 'all-in-one-seo-pack' ), - 'state_province' => __( 'State Province', 'all-in-one-seo-pack' ), - ), - 'Products and Entertainment' => array( - 'album' => __( 'Album', 'all-in-one-seo-pack' ), - 'book' => __( 'Book', 'all-in-one-seo-pack' ), - 'drink' => __( 'Drink', 'all-in-one-seo-pack' ), - 'food' => __( 'Food', 'all-in-one-seo-pack' ), - 'game' => __( 'Game', 'all-in-one-seo-pack' ), - 'movie' => __( 'Movie', 'all-in-one-seo-pack' ), - 'product' => __( 'Product', 'all-in-one-seo-pack' ), - 'song' => __( 'Song', 'all-in-one-seo-pack' ), - 'tv_show' => __( 'TV Show', 'all-in-one-seo-pack' ), - 'episode' => __( 'Episode', 'all-in-one-seo-pack' ), - ), - 'Websites' => array( - 'article' => __( 'Article', 'all-in-one-seo-pack' ), - 'website' => __( 'Website', 'all-in-one-seo-pack' ), - ), - ); - parent::__construct(); - - if ( is_admin() ) { - add_action( 'admin_init', array( $this, 'admin_init' ), 5 ); - } else { - add_action( 'wp', array( $this, 'type_setup' ) ); - } - - if ( ! is_admin() || defined( 'DOING_AJAX' ) || defined( 'AIOSEOP_UNIT_TESTING' ) ) { - $this->do_opengraph(); - } - // Set variables after WordPress load. - add_action( 'init', array( &$this, 'init' ), 999999 ); - add_filter( 'jetpack_enable_open_graph', '__return_false' ); // Avoid having duplicate meta tags - add_filter( $this->prefix . 'meta', array( $this, 'handle_meta_tag' ), 10, 5 ); - // Force refresh of Facebook cache. - add_action( 'post_updated', array( &$this, 'force_fb_refresh_update' ), 10, 3 ); - add_action( 'transition_post_status', array( &$this, 'force_fb_refresh_transition' ), 10, 3 ); - add_action( 'edited_term', array( &$this, 'save_tax_data' ), 10, 3 ); - // Adds special filters - add_filter( 'aioseop_opengraph_placeholder', array( &$this, 'filter_placeholder' ) ); - add_action( 'aiosp_activate_opengraph', array( $this, 'activate_module' ) ); - add_action( 'created_term', array( $this, 'created_term' ), 10, 3 ); - // Call to init to generate menus - $this->init(); - } - - /** - * Process meta tags for specific idiosyncrasies. - * - * @since 3.0 - * - * @param string $value The value that is proposed to be shown in the tag. - * @param string $network The social network. - * @param string $meta_tag The meta tag without the network name prefixed. - * @param string $network_meta_tag The meta tag with the network name prefixed. This is not always $network:$meta_tag. - * @param array $extra_params Extra parameters that might be required to process the meta tag. - * - * @return string The final value that will be shown. - */ - function handle_meta_tag( $value, $network, $meta_tag, $network_meta_tag, $extra_params ) { - switch ( $meta_tag ) { - case 'type': - // https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/1013 - if ( 'blog' === $value ) { - $value = 'website'; - } - break; - } - - /** - * Disables truncation of meta tags. Return true to shortcircuit and disable truncation. - * - * @since 3.0 - * - * @issue https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/808 - * @issue https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/2296 - * - * @param bool The value that is proposed to be shown in the tag. - * @param string $network The social network. - * @param string $meta_tag The meta tag without the network name prefixed. - * @param string $network_meta_tag The meta tag with the network name prefixed. This is not always $network:$meta_tag. - * @param array $extra_params Extra parameters that might be required to process the meta tag. - */ - if ( true === apply_filters( $this->prefix . 'disable_meta_tag_truncation', false, $network, $meta_tag, $network_meta_tag ) ) { - return $value; - } - - if ( isset( $extra_params['auto_generate_desc'] ) && $extra_params['auto_generate_desc'] ) { - switch ( $network_meta_tag ) { - case 'twitter:title': - // https://developer.twitter.com/en/docs/tweets/optimize-with-cards/overview/markup.html - $value = trim( $this->substr( $value, 0, 70 ) ); - break; - case 'og:description': - case 'twitter:description': - $value = trim( $this->substr( $value, 0, 200 ) ); - break; - } - } - return $value; - } - - /** - * Sets the terms defaults after a new term is created. - * - * @param int $term_id Term ID. - * @param int $tt_id Term taxonomy ID. - * @param string $taxonomy Taxonomy slug. - */ - function created_term( $term_id, $tt_id, $taxonomy_name ) { - $k = 'settings'; - $prefix = $this->get_prefix( $k ); - $tax = get_taxonomy( $taxonomy_name ); - $this->set_object_type_for_taxonomy( $prefix, $k, $taxonomy_name, $tax, false, array( $term_id ) ); - } - - /** - * Sets the defaults for a taxonomy. - * - * @param string $prefix The prefix of this module. - * @param string $k The key against which the options will be determined/set. - * @param string $taxonomy_name The name of the taxonomy. - * @param Object $tax The taxonomy object. - * @param bool $bail_if_no_terms Bail if the taxonomy has no terms. - * @param array $terms The terms in the taxonomy. - */ - private function set_object_type_for_taxonomy( $prefix, $k, $taxonomy_name, $tax, $bail_if_no_terms = false, $terms = null ) { - $object_type = null; - if ( ! $terms ) { - $terms = get_terms( - $taxonomy_name, array( - 'meta_query' => array( - array( - 'key' => '_' . $prefix . $k, - 'compare' => 'NOT EXISTS', - ), - ), - 'number' => PHP_INT_MAX, - 'fields' => 'ids', - 'hide_empty' => false, - ) - ); - } - - if ( empty( $terms ) && $bail_if_no_terms ) { - return false; - } - - if ( true === $tax->_builtin ) { - $object_type = 'article'; - } else { - // custom taxonomy. Let's get a post against this to determine its post type. - $posts = get_posts( - array( - 'numberposts' => 1, - 'post_type' => 'any', - 'tax_query' => array( - array( - 'taxonomy' => $taxonomy_name, - 'field' => 'term_id', - 'terms' => $terms, - ), - ), - ) - ); - if ( $posts ) { - global $aioseop_options; - $post_type = $posts[0]->post_type; - if ( isset( $aioseop_options['modules'] ) && isset( $aioseop_options['modules'][ $this->prefix . 'options' ] ) ) { - $og_options = $aioseop_options['modules'][ $this->prefix . 'options' ]; - - // now let's see what default object type is set for this post type. - $object_type_set = $og_options[ $this->prefix . $post_type . '_fb_object_type' ]; - if ( ! empty( $object_type_set ) ) { - $object_type = $object_type_set; - } - } - } - } - - if ( $object_type ) { - $opts[ $prefix . $k . '_category' ] = $object_type; - foreach ( $terms as $term_id ) { - update_term_meta( $term_id, '_' . $prefix . $k, $opts ); - } - } - - return true; - } - - /** - * Called when this module is activated. - */ - public function activate_module() { - if ( $this->locations !== null ) { - foreach ( $this->locations as $k => $v ) { - if ( ! isset( $v['type'] ) || 'metabox' !== $v['type'] ) { - continue; - } - $this->set_virgin_tax_terms( $k ); - } - } - } - /** - * This iterates over all taxonomies that do not have a opengraph setting defined and sets the defaults. - * - * @param string $k The key against which the options will be determined/set. - */ - private function set_virgin_tax_terms( $k ) { - $prefix = $this->get_prefix( $k ); - $opts = $this->default_options( $k ); - $taxonomies = get_taxonomies( array( 'public' => true ), 'object' ); - if ( ! $taxonomies ) { - return; - } - foreach ( $taxonomies as $name => $tax ) { - $this->set_object_type_for_taxonomy( $prefix, $k, $name, $tax, true, null ); - - } - } - - /** - * Hook called after WordPress has been loaded. - * - * @since 2.4.14 - */ - public function init() { - $count_desc = __( ' characters. We recommend a maximum of %1$s chars for the %2$s.', 'all-in-one-seo-pack' ); - // Create default options - $this->default_options = array( - 'scan_header' => array( - 'name' => __( 'Scan Header', 'all-in-one-seo-pack' ), - 'type' => 'custom', - 'save' => true, - ), - 'setmeta' => array( - 'name' => __( 'Use AIOSEO Title and Description', 'all-in-one-seo-pack' ), - 'type' => 'checkbox', - ), - 'key' => array( - 'name' => __( 'Facebook Admin ID', 'all-in-one-seo-pack' ), - 'default' => '', - 'type' => 'text', - ), - 'appid' => array( - 'name' => __( 'Facebook App ID', 'all-in-one-seo-pack' ), - 'default' => '', - 'type' => 'text', - ), - 'title_shortcodes' => array( - 'name' => __( 'Run Shortcodes In Title', 'all-in-one-seo-pack' ), - ), - 'description_shortcodes' => array( - 'name' => __( 'Run Shortcodes In Description', 'all-in-one-seo-pack' ), - ), - 'sitename' => array( - 'name' => __( 'Site Name', 'all-in-one-seo-pack' ), - 'default' => get_bloginfo( 'name' ), - 'type' => 'text', - ), - 'hometitle' => array( - 'name' => __( 'Home Title', 'all-in-one-seo-pack' ), - 'default' => '', - 'type' => 'text', - 'class' => 'aioseop_count_chars', - 'count' => true, - 'count_desc' => $count_desc, - 'size' => 95, - 'condshow' => array( - 'aiosp_opengraph_setmeta' => array( - 'lhs' => 'aiosp_opengraph_setmeta', - 'op' => '!=', - 'rhs' => 'on', - ), - ), - ), - 'description' => array( - 'name' => __( 'Home Description', 'all-in-one-seo-pack' ), - 'default' => '', - 'type' => 'textarea', - 'class' => 'aioseop_count_chars', - 'count' => true, - 'count_desc' => $count_desc, - 'size' => 200, - 'condshow' => array( - 'aiosp_opengraph_setmeta' => array( - 'lhs' => 'aiosp_opengraph_setmeta', - 'op' => '!=', - 'rhs' => 'on', - ), - ), - ), - 'homeimage' => array( - 'name' => __( 'Home Image', 'all-in-one-seo-pack' ), - 'type' => 'image', - ), - 'generate_descriptions' => array( - 'name' => __( 'Use Content For Autogenerated OG Descriptions', 'all-in-one-seo-pack' ), - 'default' => 0, - ), - 'defimg' => array( - 'name' => __( 'Select OG:Image Source', 'all-in-one-seo-pack' ), - 'type' => 'select', - 'initial_options' => array( - '' => __( 'Default Image' ), - 'featured' => __( 'Featured Image' ), - 'attach' => __( 'First Attached Image' ), - 'content' => __( 'First Image In Content' ), - 'custom' => __( 'Image From Custom Field' ), - 'author' => __( 'Post Author Image' ), - 'auto' => __( 'First Available Image' ), - ), - ), - 'fallback' => array( - 'name' => __( 'Use Default If No Image Found', 'all-in-one-seo-pack' ), - 'type' => 'checkbox', - ), - 'dimg' => array( - 'name' => __( 'Default OG:Image', 'all-in-one-seo-pack' ), - 'default' => AIOSEOP_PLUGIN_IMAGES_URL . 'default-user-image.png', - 'type' => 'image', - ), - 'dimgwidth' => array( - 'name' => __( 'Default Image Width', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - ), - 'dimgheight' => array( - 'name' => __( 'Default Image Height', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - ), - 'meta_key' => array( - 'name' => __( 'Use Custom Field For Image', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - ), - 'image' => array( - 'name' => __( 'Image', 'all-in-one-seo-pack' ), - 'type' => 'radio', - 'initial_options' => array( - 0 => '', - ), - ), - 'customimg' => array( - 'name' => __( 'Custom Image', 'all-in-one-seo-pack' ), - 'type' => 'image', - ), - 'imagewidth' => array( - 'name' => __( 'Specify Image Width', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - ), - 'imageheight' => array( - 'name' => __( 'Specify Image Height', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - ), - 'video' => array( - 'name' => __( 'Custom Video', 'all-in-one-seo-pack' ), - 'type' => 'text', - ), - 'videowidth' => array( - 'name' => __( 'Specify Video Width', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - 'condshow' => array( - 'aioseop_opengraph_settings_video' => array( - 'lhs' => 'aioseop_opengraph_settings_video', - 'op' => '!=', - 'rhs' => '', - ), - ), - ), - 'videoheight' => array( - 'name' => __( 'Specify Video Height', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - 'condshow' => array( - 'aioseop_opengraph_settings_video' => array( - 'lhs' => 'aioseop_opengraph_settings_video', - 'op' => '!=', - 'rhs' => '', - ), - ), - ), - 'defcard' => array( - 'name' => __( 'Default Twitter Card', 'all-in-one-seo-pack' ), - 'type' => 'select', - 'default' => 'summary', - 'initial_options' => array( - 'summary' => __( 'Summary', 'all-in-one-seo-pack' ), - 'summary_large_image' => __( 'Summary Large Image', 'all-in-one-seo-pack' ), - - /* - REMOVING THIS TWITTER CARD TYPE FROM SOCIAL META MODULE - 'photo' => __( 'Photo', 'all-in-one-seo-pack' ) - */ - ), - ), - 'setcard' => array( - 'name' => __( 'Twitter Card Type', 'all-in-one-seo-pack' ), - 'type' => 'select', - 'initial_options' => array( - 'summary_large_image' => __( 'Summary Large Image', 'all-in-one-seo-pack' ), - 'summary' => __( 'Summary', 'all-in-one-seo-pack' ), - - /* - REMOVING THIS TWITTER CARD TYPE FROM SOCIAL META MODULE - 'photo' => __( 'Photo', 'all-in-one-seo-pack' ) - */ - ), - ), - 'twitter_site' => array( - 'name' => __( 'Twitter Site', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - ), - 'twitter_creator' => array( - 'name' => __( 'Show Twitter Author', 'all-in-one-seo-pack' ), - ), - 'twitter_domain' => array( - 'name' => __( 'Twitter Domain', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - ), - 'customimg_twitter' => array( - 'name' => __( 'Custom Twitter Image', 'all-in-one-seo-pack' ), - 'type' => 'image', - ), - 'gen_tags' => array( - 'name' => __( 'Automatically Generate Article Tags', 'all-in-one-seo-pack' ), - ), - 'gen_keywords' => array( - 'name' => __( 'Use Keywords In Article Tags', 'all-in-one-seo-pack' ), - 'default' => 'on', - 'condshow' => array( 'aiosp_opengraph_gen_tags' => 'on' ), - ), - 'gen_categories' => array( - 'name' => __( 'Use Categories In Article Tags', 'all-in-one-seo-pack' ), - 'default' => 'on', - 'condshow' => array( 'aiosp_opengraph_gen_tags' => 'on' ), - ), - 'gen_post_tags' => array( - 'name' => __( 'Use Post Tags In Article Tags', 'all-in-one-seo-pack' ), - 'default' => 'on', - 'condshow' => array( 'aiosp_opengraph_gen_tags' => 'on' ), - ), - 'types' => array( - 'name' => __( 'Enable Facebook Meta for Post Types', 'all-in-one-seo-pack' ), - 'type' => 'multicheckbox', - 'default' => array( 'post' => 'post', 'page' => 'page' ), - 'initial_options' => $this->get_post_type_titles( array( '_builtin' => false ) ), - ), - 'title' => array( - 'name' => __( 'Title', 'all-in-one-seo-pack' ), - 'default' => '', - 'type' => 'text', - 'size' => 95, - 'count' => 1, - 'count_desc' => $count_desc, - ), - 'desc' => array( - 'name' => __( 'Description', 'all-in-one-seo-pack' ), - 'default' => '', - 'type' => 'textarea', - 'cols' => 50, - 'rows' => 4, - 'count' => 1, - 'count_desc' => $count_desc, - ), - 'category' => array( - 'name' => __( 'Facebook Object Type', 'all-in-one-seo-pack' ), - 'type' => 'select', - 'style' => '', - 'default' => '', - 'initial_options' => $this->fb_object_types, - ), - 'facebook_debug' => array( - 'name' => __( 'Facebook Debug', 'all-in-one-seo-pack' ), - 'type' => 'html', - 'save' => false, - 'default' => '' . __( 'Debug This Post', 'all-in-one-seo-pack' ) . '', - ), - 'section' => array( - 'name' => __( 'Article Section', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - 'condshow' => array( 'aioseop_opengraph_settings_category' => 'article' ), - ), - 'tag' => array( - 'name' => __( 'Article Tags', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - 'condshow' => array( 'aioseop_opengraph_settings_category' => 'article' ), - ), - 'facebook_publisher' => array( - 'name' => __( 'Show Facebook Publisher on Articles', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - ), - 'facebook_author' => array( - 'name' => __( 'Show Facebook Author on Articles', 'all-in-one-seo-pack' ), - ), - 'profile_links' => array( - 'name' => __( 'Social Profile Links', 'all-in-one-seo-pack' ), - 'type' => 'textarea', - 'cols' => 60, - 'rows' => 5, - ), - 'person_or_org' => array( - 'name' => __( 'Person or Organization?', 'all-in-one-seo-pack' ), - 'type' => 'radio', - 'initial_options' => array( - 'person' => __( 'Person', 'all-in-one-seo-pack' ), - 'org' => __( 'Organization', 'all-in-one-seo-pack' ), - ), - ), - 'social_name' => array( - 'name' => __( 'Associated Name', 'all-in-one-seo-pack' ), - 'type' => 'text', - 'default' => '', - ), - ); - // load initial options / set defaults - $this->update_options(); - $display = array(); - if ( isset( $this->options['aiosp_opengraph_types'] ) && ! empty( $this->options['aiosp_opengraph_types'] ) ) { - $display = $this->options['aiosp_opengraph_types']; - } - $this->locations = array( - 'opengraph' => array( - 'name' => $this->name, - 'prefix' => 'aiosp_', - 'type' => 'settings', - 'options' => array( - 'scan_header', - 'setmeta', - 'key', - 'appid', - 'sitename', - 'title_shortcodes', - 'description_shortcodes', - 'hometitle', - 'description', - 'homeimage', - 'generate_descriptions', - 'defimg', - 'fallback', - 'dimg', - 'dimgwidth', - 'dimgheight', - 'meta_key', - 'defcard', - 'profile_links', - 'person_or_org', - 'social_name', - 'twitter_site', - 'twitter_creator', - 'twitter_domain', - 'gen_tags', - 'gen_keywords', - 'gen_categories', - 'gen_post_tags', - 'types', - 'facebook_publisher', - 'facebook_author', - ), - ), - 'settings' => array( - 'name' => __( 'Social Settings', 'all-in-one-seo-pack' ), - 'type' => 'metabox', - 'help_link' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/', - 'options' => array( - 'title', - 'desc', - 'image', - 'customimg', - 'imagewidth', - 'imageheight', - 'video', - 'videowidth', - 'videoheight', - 'category', - 'facebook_debug', - 'section', - 'tag', - 'setcard', - 'customimg_twitter', - ), - 'display' => apply_filters( 'aioseop_opengraph_display', $display ), - 'prefix' => 'aioseop_opengraph_', - ), - ); - $this->layout = array( - 'home' => array( - 'name' => __( 'Home Page Settings', 'all-in-one-seo-pack' ), - 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#use-aioseo-title-and-description', - 'options' => array( 'setmeta', 'sitename', 'hometitle', 'description', 'homeimage' ), - ), - 'image' => array( - 'name' => __( 'Image Settings', 'all-in-one-seo-pack' ), - 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#select-og-image-source', - 'options' => array( 'defimg', 'fallback', 'dimg', 'dimgwidth', 'dimgheight', 'meta_key' ), - ), - 'links' => array( - 'name' => __( 'Social Profile Links', 'all-in-one-seo-pack' ), - 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#social-profile-links', - 'options' => array( 'profile_links', 'person_or_org', 'social_name' ), - ), - 'facebook' => array( - 'name' => __( 'Facebook Settings', 'all-in-one-seo-pack' ), - 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#facebook-settings', - 'options' => array( - 'key', - 'appid', - 'types', - 'gen_tags', - 'gen_keywords', - 'gen_categories', - 'gen_post_tags', - 'facebook_publisher', - 'facebook_author', - ), - ), - 'twitter' => array( - 'name' => __( 'Twitter Settings', 'all-in-one-seo-pack' ), - 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#default-twitter-card', - 'options' => array( 'defcard', 'setcard', 'twitter_site', 'twitter_creator', 'twitter_domain' ), - ), - 'default' => array( - 'name' => __( 'Advanced Settings', 'all-in-one-seo-pack' ), - 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/', - 'options' => array(), // this is set below, to the remaining options -- pdb - ), - 'scan_meta' => array( - 'name' => __( 'Scan Social Meta', 'all-in-one-seo-pack' ), - 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#scan_meta', - 'options' => array( 'scan_header' ), - ), - ); - $other_options = array(); - foreach ( $this->layout as $k => $v ) { - $other_options = array_merge( $other_options, $v['options'] ); - } - - $this->layout['default']['options'] = array_diff( array_keys( $this->default_options ), $other_options ); - } - - /** - * Forces FaceBook OpenGraph to refresh its cache when a post is changed to - * - * @param $new_status - * @param $old_status - * @param $post - * - * @todo this and force_fb_refresh_update can probably have the remote POST extracted out. - * - * @see https://developers.facebook.com/docs/sharing/opengraph/using-objects#update - * @since 2.3.11 - */ - function force_fb_refresh_transition( $new_status, $old_status, $post ) { - if ( 'publish' !== $new_status ) { - return; - } - if ( 'future' !== $old_status ) { - return; - } - - $current_post_type = get_post_type(); - - // Only ping Facebook if Social SEO is enabled on this post type. - if ( $this->option_isset( 'types' ) && is_array( $this->options['aiosp_opengraph_types'] ) && in_array( $current_post_type, $this->options['aiosp_opengraph_types'] ) ) { - $post_url = aioseop_get_permalink( $post->ID ); - $endpoint = sprintf( - 'https://graph.facebook.com/?%s', http_build_query( - array( - 'id' => $post_url, - 'scrape' => true, - ) - ) - ); - wp_remote_post( $endpoint, array( 'blocking' => false ) ); - } - } - - /** - * Forces FaceBook OpenGraph refresh on update. - * - * @param $post_id - * @param $post_after - * - * @see https://developers.facebook.com/docs/sharing/opengraph/using-objects#update - * @since 2.3.11 - */ - function force_fb_refresh_update( $post_id, $post_after ) { - - $current_post_type = get_post_type(); - - // Only ping Facebook if Social SEO is enabled on this post type. - if ( 'publish' === $post_after->post_status && $this->option_isset( 'types' ) && is_array( $this->options['aiosp_opengraph_types'] ) && in_array( $current_post_type, $this->options['aiosp_opengraph_types'] ) ) { - $post_url = aioseop_get_permalink( $post_id ); - $endpoint = sprintf( - 'https://graph.facebook.com/?%s', http_build_query( - array( - 'id' => $post_url, - 'scrape' => true, - ) - ) - ); - wp_remote_post( $endpoint, array( 'blocking' => false ) ); - } - } - - function settings_page_init() { - add_filter( 'aiosp_output_option', array( $this, 'display_custom_options' ), 10, 2 ); - } - - function filter_options( $options, $location ) { - if ( $location == 'settings' ) { - $prefix = $this->get_prefix( $location ) . $location . '_'; - list( $legacy, $images ) = $this->get_all_images( $options ); - if ( isset( $options ) && isset( $options[ "{$prefix}image" ] ) ) { - $thumbnail = $options[ "{$prefix}image" ]; - if ( ctype_digit( (string) $thumbnail ) || ( $thumbnail == 'post' ) ) { - if ( $thumbnail == 'post' ) { - $thumbnail = $images['post1']; - } elseif ( ! empty( $legacy[ $thumbnail ] ) ) { - $thumbnail = $legacy[ $thumbnail ]; - } - } - $options[ "{$prefix}image" ] = $thumbnail; - } - if ( empty( $options[ $prefix . 'image' ] ) ) { - $img = array_keys( $images ); - if ( ! empty( $img ) && ! empty( $img[1] ) ) { - $options[ $prefix . 'image' ] = $img[1]; - } - } - } - - return $options; - } - - /** - * Applies filter to module settings. - * - * @since 2.3.11 - * @since 2.4.14 Added filter for description and title placeholders. - * @since 2.3.15 do_shortcode on description. - * - * @see [plugin]\admin\aioseop_module_class.php > display_options() - */ - function filter_settings( $settings, $location, $current ) { - global $aiosp, $post; - if ( $location == 'opengraph' || $location == 'settings' ) { - $prefix = $this->get_prefix( $location ) . $location . '_'; - if ( $location == 'opengraph' ) { - return $settings; - } - if ( $location == 'settings' ) { - list( $legacy, $settings[ $prefix . 'image' ]['initial_options'] ) = $this->get_all_images( $current ); - $opts = array( 'title', 'desc' ); - $current_post_type = get_post_type(); - if ( isset( $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ] ) ) { - $flat_type_list = array(); - foreach ( $this->fb_object_types as $k => $v ) { - if ( is_array( $v ) ) { - $flat_type_list = array_merge( $flat_type_list, $v ); - } else { - $flat_type_list[ $k ] = $v; - } - } - $default_fb_type = $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ]; - // https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/1013 - // if 'blog' is the selected type but because it is no longer a schema type, we use 'website' instead. - if ( 'blog' === $default_fb_type ) { - $default_fb_type = 'website'; - } - if ( isset( $flat_type_list[ $default_fb_type ] ) ) { - $default_fb_type = $flat_type_list[ $default_fb_type ]; - } - $settings[ $prefix . 'category' ]['initial_options'] = array_merge( - array( - $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ] => __( 'Default ', 'all-in-one-seo-pack' ) . ' - ' . $default_fb_type, - ), - $settings[ $prefix . 'category' ]['initial_options'] - ); - } - if ( isset( $this->options['aiosp_opengraph_defcard'] ) ) { - $settings[ $prefix . 'setcard' ]['default'] = $this->options['aiosp_opengraph_defcard']; - } - $info = $aiosp->get_page_snippet_info(); - $title = $info['title']; - $description = $info['description']; - - // Description options - if ( is_object( $post ) ) { - // Always show excerpt - $description = empty( $this->options['aiosp_opengraph_generate_descriptions'] ) - ? $aiosp->trim_excerpt_without_filters( - $aiosp->internationalize( preg_replace( '/\s+/', ' ', $post->post_excerpt ) ), - 200 - ) - : $aiosp->trim_excerpt_without_filters( - $aiosp->internationalize( preg_replace( '/\s+/', ' ', $post->post_content ) ), - 200 - ); - } - - // #1308 - we want to make sure we are ignoring php version only in the admin area while editing the post, so that it does not impact #932. - $screen = get_current_screen(); - $ignore_php_version = is_admin() && isset( $screen->id ) && 'post' == $screen->id; - - // Add filters - $description = apply_filters( 'aioseop_description', $description, false, $ignore_php_version ); - // Add placholders - $settings[ "{$prefix}title" ]['placeholder'] = apply_filters( 'aioseop_opengraph_placeholder', $title ); - $settings[ "{$prefix}desc" ]['placeholder'] = apply_filters( 'aioseop_opengraph_placeholder', $description ); - } - if ( isset( $current[ $prefix . 'setmeta' ] ) && $current[ $prefix . 'setmeta' ] ) { - foreach ( $opts as $opt ) { - if ( isset( $settings[ $prefix . $opt ] ) ) { - $settings[ $prefix . $opt ]['type'] = 'hidden'; - $settings[ $prefix . $opt ]['label'] = 'none'; - unset( $settings[ $prefix . $opt ]['count'] ); - } - } - } - } - - return $settings; - } - - /** - * Applies filter to module options. - * These will display in the "Social Settings" object tab. - * filter:{prefix}override_options - * - * @since 2.3.11 - * @since 2.4.14 Overrides empty og:type values. - * - * @see [plugin]\admin\aioseop_module_class.php > display_options() - * - * @global array $aioseop_options Plugin options. - * - * @param array $options Current options. - * @param string $location Location where filter is called. - * @param array $settings Settings. - * - * @return array - */ - function override_options( $options, $location, $settings ) { - global $aioseop_options; - // Prepare default and prefix - $prefix = $this->get_prefix( $location ) . $location . '_'; - $opts = array(); - - foreach ( $settings as $k => $v ) { - if ( $v['save'] ) { - $opts[ $k ] = $v['default']; - } - } - foreach ( $options as $k => $v ) { - switch ( $k ) { - case $prefix . 'category': - if ( empty( $v ) ) { - // Get post type - $type = isset( get_current_screen()->post_type ) - ? get_current_screen()->post_type - : null; - // Assign default from plugin options - if ( ! empty( $type ) - && isset( $aioseop_options['modules'] ) - && isset( $aioseop_options['modules']['aiosp_opengraph_options'] ) - && isset( $aioseop_options['modules']['aiosp_opengraph_options'][ 'aiosp_opengraph_' . $type . '_fb_object_type' ] ) - ) { - $options[ $prefix . 'category' ] = - $aioseop_options['modules']['aiosp_opengraph_options'][ 'aiosp_opengraph_' . $type . '_fb_object_type' ]; - } - } - break; - } - if ( $v === null ) { - unset( $options[ $k ] ); - } - } - $options = wp_parse_args( $options, $opts ); - - // https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/1013 - $post_types = $this->get_post_type_titles(); - foreach ( $post_types as $slug => $name ) { - $field = 'aiosp_opengraph_' . $slug . '_fb_object_type'; - if ( isset( $options[ $field ] ) && 'blog' === $options[ $field ] ) { - $options[ $field ] = 'website'; - } - } - - return $options; - } - - /** - * Applies filter to metabox settings before they are saved. - * Sets custom as default if a custom image is uploaded. - * filter:{prefix}filter_metabox_options - * filter:{prefix}filter_term_metabox_options - * - * @since 2.3.11 - * @since 2.4.14 Fixes for aioseop-pro #67 and other bugs found. - * - * @see [plugin]\admin\aioseop_module_class.php > save_post_data() - * @see [this file] > save_tax_data() - * - * @param array $options List of current options. - * @param string $location Location where filter is called. - * @param int $id Either post_id or term_id. - * - * @return array - */ - function filter_metabox_options( $options, $location, $post_id ) { - if ( $location == 'settings' ) { - $prefix = $this->get_prefix( $location ) . $location . '_'; - if ( isset( $options[ $prefix . 'customimg_checker' ] ) - && $options[ $prefix . 'customimg_checker' ] - ) { - $options[ $prefix . 'image' ] = $options[ $prefix . 'customimg' ]; - } - } - return $options; - } - - /** Custom settings **/ - function display_custom_options( $buf, $args ) { - if ( $args['name'] == 'aiosp_opengraph_scan_header' ) { - $buf .= '
                      '; - $args['options']['type'] = 'submit'; - $args['attr'] = " class='button-primary' "; - $args['value'] = $args['options']['default'] = __( 'Scan Now', 'all-in-one-seo-pack' ); - $buf .= __( 'Scan your site for duplicate social meta tags.', 'all-in-one-seo-pack' ); - $buf .= '

                      ' . $this->get_option_html( $args ); - $buf .= '
                      '; - } - - return $buf; - } - - function add_attributes( $output ) { - // avoid having duplicate meta tags - $type = $this->type; - if ( empty( $type ) ) { - $type = 'website'; - } - $schema_types = array( - 'album' => 'MusicAlbum', - 'article' => 'Article', - 'bar' => 'BarOrPub', - 'blog' => 'Blog', - 'book' => 'Book', - 'cafe' => 'CafeOrCoffeeShop', - 'city' => 'City', - 'country' => 'Country', - 'episode' => 'Episode', - 'food' => 'FoodEvent', - 'game' => 'Game', - 'hotel' => 'Hotel', - 'landmark' => 'LandmarksOrHistoricalBuildings', - 'movie' => 'Movie', - 'product' => 'Product', - 'profile' => 'ProfilePage', - 'restaurant' => 'Restaurant', - 'school' => 'School', - 'sport' => 'SportsEvent', - 'website' => 'WebSite', - ); - - if ( ! empty( $schema_types[ $type ] ) ) { - $type = $schema_types[ $type ]; - } else { - $type = 'WebSite'; - } - - $attributes = apply_filters( - $this->prefix . 'attributes', array( - 'prefix="og: http://ogp.me/ns#"', - ) - ); - - foreach ( $attributes as $attr ) { - if ( strpos( $output, $attr ) === false ) { - $output .= "\n\t$attr "; - } - } - - return $output; - } - - /** - * Add our social meta. - * - * @since 1.0.0 - * @since 2.3.11.5 Support for multiple fb_admins. - * @since 2.3.13 Adds filter:aioseop_description on description. - * @since 2.4.14 Fixes for aioseop-pro #67. - * @since 2.3.15 Always do_shortcode on descriptions, removed for titles. - * - * @global object $post Current WP_Post object. - * @global object $aiosp All in one seo plugin object. - * @global array $aioseop_options All in one seo plugin options. - * @global object $wp_query WP_Query global instance. - */ - function add_meta() { - global $post, $aiosp, $aioseop_options, $wp_query; - $metabox = $this->get_current_options( array(), 'settings' ); - $key = $this->options['aiosp_opengraph_key']; - $key = $this->options['aiosp_opengraph_key']; - $dimg = $this->options['aiosp_opengraph_dimg']; - $current_post_type = get_post_type(); - $title = $description = $image = $video = ''; - $type = $this->type; - $sitename = $this->options['aiosp_opengraph_sitename']; - $tag = ''; - - // for some reason, options is not populated correctly during unit tests. - if ( defined( 'AIOSEOP_UNIT_TESTING' ) ) { - $this->options = $aioseop_options['modules'][ $this->prefix . 'options' ]; - } - - $appid = isset( $this->options['aiosp_opengraph_appid'] ) ? $this->options['aiosp_opengraph_appid'] : ''; - - if ( ! empty( $aioseop_options['aiosp_hide_paginated_descriptions'] ) ) { - $first_page = false; - if ( $aiosp->get_page_number() < 2 ) { - $first_page = true; - } - } else { - $first_page = true; - } - $url = $aiosp->aiosp_mrt_get_url( $wp_query ); - $url = apply_filters( 'aioseop_canonical_url', $url ); - - // this will collect the extra values that are required outside the below IF block. - $extra_params = array(); - - $setmeta = $this->options['aiosp_opengraph_setmeta']; - $social_links = ''; - if ( is_front_page() ) { - $title = $this->options['aiosp_opengraph_hometitle']; - if ( $first_page ) { - $description = $this->options['aiosp_opengraph_description']; - if ( empty( $description ) ) { - $description = get_bloginfo( 'description' ); - } - } - if ( ! empty( $this->options['aiosp_opengraph_homeimage'] ) ) { - $thumbnail = $this->options['aiosp_opengraph_homeimage']; - } else { - $thumbnail = $this->options['aiosp_opengraph_dimg']; - } - - /* If Use AIOSEO Title and Desc Selected */ - if ( $setmeta ) { - $title = $aiosp->wp_title(); - if ( $first_page ) { - $description = $aiosp->get_aioseop_description( $post ); - } - } - - /* Add some defaults */ - if ( empty( $title ) ) { - $title = get_bloginfo( 'name' ); - } - if ( empty( $sitename ) ) { - $sitename = get_bloginfo( 'name' ); - } - - if ( empty( $description ) && $first_page && ! empty( $post ) && ! post_password_required( $post ) ) { - - if ( ! empty( $post->post_content ) || ! empty( $post->post_excerpt ) ) { - $description = $aiosp->trim_excerpt_without_filters( $aiosp->internationalize( preg_replace( '/\s+/', ' ', $post->post_excerpt ) ), 200 ); - - if ( ! empty( $this->options['aiosp_opengraph_generate_descriptions'] ) ) { - $description = $aiosp->trim_excerpt_without_filters( $aiosp->internationalize( preg_replace( '/\s+/', ' ', $post->post_content ) ), 200 ); - } - } - } - - if ( empty( $description ) && $first_page ) { - $description = get_bloginfo( 'description' ); - } - if ( ! empty( $this->options['aiosp_opengraph_profile_links'] ) ) { - $social_links = $this->options['aiosp_opengraph_profile_links']; - if ( ! empty( $this->options['aiosp_opengraph_social_name'] ) ) { - $social_name = $this->options['aiosp_opengraph_social_name']; - } else { - $social_name = ''; - } - if ( $this->options['aiosp_opengraph_person_or_org'] == 'person' ) { - $social_type = 'Person'; - } else { - $social_type = 'Organization'; - } - } - } elseif ( is_singular() && $this->option_isset( 'types' ) - && is_array( $this->options['aiosp_opengraph_types'] ) - && in_array( $current_post_type, $this->options['aiosp_opengraph_types'] ) - ) { - - if ( $type == 'article' ) { - if ( ! empty( $metabox['aioseop_opengraph_settings_section'] ) ) { - $section = $metabox['aioseop_opengraph_settings_section']; - } - if ( ! empty( $metabox['aioseop_opengraph_settings_tag'] ) ) { - $tag = $metabox['aioseop_opengraph_settings_tag']; - } - if ( ! empty( $this->options['aiosp_opengraph_facebook_publisher'] ) ) { - $publisher = $this->options['aiosp_opengraph_facebook_publisher']; - } - } - - if ( ! empty( $this->options['aiosp_opengraph_twitter_domain'] ) ) { - $domain = $this->options['aiosp_opengraph_twitter_domain']; - } - - if ( $type == 'article' && ! empty( $post ) ) { - if ( isset( $post->post_author ) && ! empty( $this->options['aiosp_opengraph_facebook_author'] ) ) { - $author = get_the_author_meta( 'facebook', $post->post_author ); - } - - if ( isset( $post->post_date_gmt ) ) { - $published_time = date( 'Y-m-d\TH:i:s\Z', mysql2date( 'U', $post->post_date_gmt ) ); - } - - if ( isset( $post->post_modified_gmt ) ) { - $modified_time = date( 'Y-m-d\TH:i:s\Z', mysql2date( 'U', $post->post_modified_gmt ) ); - } - } - - $image = $metabox['aioseop_opengraph_settings_image']; - $video = $metabox['aioseop_opengraph_settings_video']; - $title = $metabox['aioseop_opengraph_settings_title']; - $description = $metabox['aioseop_opengraph_settings_desc']; - - // Let's make a note of manually provided descriptions/titles as they might need special handling. - // @issue https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/808 - // @issue https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/2296 - $title_from_main_settings = trim( strip_tags( get_post_meta( $post->ID, '_aioseop_title', true ) ) ); - $desc_from_main_settings = trim( strip_tags( get_post_meta( $post->ID, '_aioseop_description', true ) ) ); - if ( empty( $title ) && empty( $title_from_main_settings ) ) { - $extra_params['auto_generate_title'] = true; - } - if ( empty( $description ) && empty( $desc_from_main_settings ) ) { - $extra_params['auto_generate_desc'] = true; - } - - /* Add AIOSEO variables if Site Title and Desc from AIOSEOP not selected */ - global $aiosp; - if ( empty( $title ) ) { - $title = $aiosp->wp_title(); - } - if ( empty( $description ) ) { - $description = trim( strip_tags( get_post_meta( $post->ID, '_aioseop_description', true ) ) ); - } - - /* Add default title */ - if ( empty( $title ) ) { - $title = get_the_title(); - } - - // Add default description. - if ( empty( $description ) && ! post_password_required( $post ) ) { - - $description = $post->post_excerpt; - - if ( $this->options['aiosp_opengraph_generate_descriptions'] || empty( $description ) ) { - if ( ! AIOSEOPPRO || ( AIOSEOPPRO && apply_filters( $this->prefix . 'generate_descriptions_from_content', true, $post ) ) ) { - $description = $post->post_content; - } else { - $description = $post->post_excerpt; - } - } - } - if ( empty( $type ) ) { - $type = 'article'; - } - } elseif ( AIOSEOPPRO && ( is_category() || is_tag() || is_tax() ) ) { - if ( isset( $this->options['aioseop_opengraph_settings_category'] ) ) { - $type = $this->options['aioseop_opengraph_settings_category']; - } - if ( isset( $metabox['aioseop_opengraph_settings_category'] ) ) { - $type = $metabox['aioseop_opengraph_settings_category']; - } - if ( $type == 'article' ) { - if ( ! empty( $metabox['aioseop_opengraph_settings_section'] ) ) { - $section = $metabox['aioseop_opengraph_settings_section']; - } - if ( ! empty( $metabox['aioseop_opengraph_settings_tag'] ) ) { - $tag = $metabox['aioseop_opengraph_settings_tag']; - } - if ( ! empty( $this->options['aiosp_opengraph_facebook_publisher'] ) ) { - $publisher = $this->options['aiosp_opengraph_facebook_publisher']; - } - } - if ( ! empty( $this->options['aiosp_opengraph_twitter_domain'] ) ) { - $domain = $this->options['aiosp_opengraph_twitter_domain']; - } - if ( $type == 'article' && ! empty( $post ) ) { - if ( isset( $post->post_author ) && ! empty( $this->options['aiosp_opengraph_facebook_author'] ) ) { - $author = get_the_author_meta( 'facebook', $post->post_author ); - } - - if ( isset( $post->post_date_gmt ) ) { - $published_time = date( 'Y-m-d\TH:i:s\Z', mysql2date( 'U', $post->post_date_gmt ) ); - } - if ( isset( $post->post_modified_gmt ) ) { - $modified_time = date( 'Y-m-d\TH:i:s\Z', mysql2date( 'U', $post->post_modified_gmt ) ); - } - } - $image = $metabox['aioseop_opengraph_settings_image']; - $video = $metabox['aioseop_opengraph_settings_video']; - $title = $metabox['aioseop_opengraph_settings_title']; - $description = $metabox['aioseop_opengraph_settings_desc']; - /* Add AIOSEO variables if Site Title and Desc from AIOSEOP not selected */ - global $aiosp; - if ( empty( $title ) ) { - $title = $aiosp->wp_title(); - } - if ( empty( $description ) ) { - $term_id = isset( $_GET['tag_ID'] ) ? (int) $_GET['tag_ID'] : 0; - $term_id = $term_id ? $term_id : get_queried_object()->term_id; - $description = trim( strip_tags( get_term_meta( $term_id, '_aioseop_description', true ) ) ); - } - // Add default title - if ( empty( $title ) ) { - $title = get_the_title(); - } - // Add default description. - if ( empty( $description ) && ! post_password_required( $post ) ) { - $description = get_queried_object()->description; - } - if ( empty( $type ) ) { - // https://github.com/semperfiwebdesign/aioseop-pro/issues/321 - if ( AIOSEOPPRO && ( is_category() || is_tag() || is_tax() ) ) { - $og_options = $aioseop_options['modules'][ $this->prefix . 'options' ]; - $current_post_type = get_post_type(); - // check if the post type's object type is set. - if ( isset( $og_options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ] ) ) { - $type = $og_options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ]; - } elseif ( in_array( $current_post_type, array( 'post', 'page' ) ) ) { - $type = 'article'; - } - } else { - $type = 'website'; - } - } - } elseif ( is_home() && ! is_front_page() ) { - // This is the blog page but not the homepage. - global $aiosp; - $image = $metabox['aioseop_opengraph_settings_image']; - $video = $metabox['aioseop_opengraph_settings_video']; - $title = $metabox['aioseop_opengraph_settings_title']; - $description = $metabox['aioseop_opengraph_settings_desc']; - - if ( empty( $description ) ) { - // If there's not social description, fall back to the SEO description. - $description = trim( strip_tags( get_post_meta( get_option( 'page_for_posts' ), '_aioseop_description', true ) ) ); - } - if ( empty( $title ) ) { - $title = $aiosp->wp_title(); - } - } else { - return; - } - - if ( $type === 'article' && ! empty( $post ) && is_singular() ) { - if ( ! empty( $this->options['aiosp_opengraph_gen_tags'] ) ) { - if ( ! empty( $this->options['aiosp_opengraph_gen_keywords'] ) ) { - $keywords = $aiosp->get_main_keywords(); - $keywords = $this->apply_cf_fields( $keywords ); - $keywords = apply_filters( 'aioseop_keywords', $keywords ); - if ( ! empty( $keywords ) && ! empty( $tag ) ) { - $tag .= ',' . $keywords; - } elseif ( empty( $tag ) ) { - $tag = $keywords; - } - } - $tag = $aiosp->keyword_string_to_list( $tag ); - if ( ! empty( $this->options['aiosp_opengraph_gen_categories'] ) ) { - $tag = array_merge( $tag, $aiosp->get_all_categories( $post->ID ) ); - } - if ( ! empty( $this->options['aiosp_opengraph_gen_post_tags'] ) ) { - $tag = array_merge( $tag, $aiosp->get_all_tags( $post->ID ) ); - } - } - if ( ! empty( $tag ) ) { - $tag = $aiosp->clean_keyword_list( $tag ); - } - } - - if ( ! empty( $this->options['aiosp_opengraph_title_shortcodes'] ) ) { - $title = do_shortcode( $title ); - } - if ( ! empty( $description ) ) { - $description = $aiosp->internationalize( preg_replace( '/\s+/', ' ', $description ) ); - if ( ! empty( $this->options['aiosp_opengraph_description_shortcodes'] ) ) { - $description = do_shortcode( $description ); - } - if ( ! empty( $this->options['aiosp_opengraph_generate_descriptions'] ) && $this->options['aiosp_opengraph_generate_descriptions'] ) { - $description = $aiosp->trim_excerpt_without_filters( $description, 200 ); - } else { - // User input still needs to be run through this function to strip tags. - $description = $aiosp->trim_excerpt_without_filters( $description, 99999 ); - } - } - - $title = $this->apply_cf_fields( $title ); - $description = $this->apply_cf_fields( $description ); - - /* Data Validation */ - $title = strip_tags( esc_attr( $title ) ); - $sitename = strip_tags( esc_attr( $sitename ) ); - $description = strip_tags( esc_attr( $description ) ); - - if ( empty( $thumbnail ) && ! empty( $image ) ) { - $thumbnail = $image; - } - - // Add user supplied default image. - if ( empty( $thumbnail ) ) { - if ( empty( $this->options['aiosp_opengraph_defimg'] ) ) { - $thumbnail = $this->options['aiosp_opengraph_dimg']; - } else { - $img_type = $this->options['aiosp_opengraph_defimg']; - if ( ! empty( $post ) ) { - // Customize the type of image per post/post_type. - $img_type = apply_filters( $this->prefix . 'default_image_type', $img_type, $post, $type ); - } - switch ( $img_type ) { - case 'featured': - $thumbnail = $this->get_the_image_by_post_thumbnail(); - break; - case 'attach': - $thumbnail = $this->get_the_image_by_attachment(); - break; - case 'content': - $thumbnail = $this->get_the_image_by_scan(); - break; - case 'custom': - $meta_key = $this->options['aiosp_opengraph_meta_key']; - if ( ! empty( $meta_key ) && ! empty( $post ) ) { - $meta_key = explode( ',', $meta_key ); - $thumbnail = $this->get_the_image_by_meta_key( - array( - 'post_id' => $post->ID, - 'meta_key' => $meta_key, - ) - ); - } - break; - case 'auto': - $thumbnail = $this->get_the_image(); - break; - case 'author': - $thumbnail = $this->get_the_image_by_author(); - break; - default: - $thumbnail = $this->options['aiosp_opengraph_dimg']; - } - } - } - - if ( empty( $thumbnail ) && ! empty( $this->options['aiosp_opengraph_fallback'] ) ) { - $thumbnail = $this->options['aiosp_opengraph_dimg']; - if ( ! empty( $post ) ) { - // Customize the default image per post/post_type. - $thumbnail = apply_filters( $this->prefix . 'default_image', $thumbnail, $post, $type ); - } - } - - if ( ! empty( $thumbnail ) ) { - $thumbnail = esc_url( $thumbnail ); - $thumbnail = set_url_scheme( $thumbnail ); - } - - $width = $height = ''; - if ( ! empty( $thumbnail ) ) { - if ( ! empty( $metabox['aioseop_opengraph_settings_imagewidth'] ) ) { - $width = $metabox['aioseop_opengraph_settings_imagewidth']; - } - if ( ! empty( $metabox['aioseop_opengraph_settings_imageheight'] ) ) { - $height = $metabox['aioseop_opengraph_settings_imageheight']; - } - if ( empty( $width ) && ! empty( $this->options['aiosp_opengraph_dimgwidth'] ) ) { - $width = $this->options['aiosp_opengraph_dimgwidth']; - } - if ( empty( $height ) && ! empty( $this->options['aiosp_opengraph_dimgheight'] ) ) { - $height = $this->options['aiosp_opengraph_dimgheight']; - } - } - - if ( ! empty( $video ) ) { - if ( ! empty( $metabox['aioseop_opengraph_settings_videowidth'] ) ) { - $videowidth = $metabox['aioseop_opengraph_settings_videowidth']; - } - if ( ! empty( $metabox['aioseop_opengraph_settings_videoheight'] ) ) { - $videoheight = $metabox['aioseop_opengraph_settings_videoheight']; - } - } - - $card = 'summary'; - if ( ! empty( $this->options['aiosp_opengraph_defcard'] ) ) { - $card = $this->options['aiosp_opengraph_defcard']; - } - - if ( ! empty( $metabox['aioseop_opengraph_settings_setcard'] ) ) { - $card = $metabox['aioseop_opengraph_settings_setcard']; - } - - // support for changing legacy twitter cardtype-photo to summary large image - if ( $card == 'photo' ) { - $card = 'summary_large_image'; - } - - $site = $domain = $creator = ''; - - if ( ! empty( $this->options['aiosp_opengraph_twitter_site'] ) ) { - $site = $this->options['aiosp_opengraph_twitter_site']; - $site = AIOSEOP_Opengraph_Public::prepare_twitter_username( $site ); - } - - if ( ! empty( $this->options['aiosp_opengraph_twitter_domain'] ) ) { - $domain = $this->options['aiosp_opengraph_twitter_domain']; - } - - if ( ! empty( $post ) && isset( $post->post_author ) && ! empty( $this->options['aiosp_opengraph_twitter_creator'] ) ) { - $creator = get_the_author_meta( 'twitter', $post->post_author ); - $creator = AIOSEOP_Opengraph_Public::prepare_twitter_username( $creator ); - } - - if ( ! empty( $thumbnail ) ) { - $twitter_thumbnail = $thumbnail; // Default Twitter image if custom isn't set. - } - - if ( isset( $metabox['aioseop_opengraph_settings_customimg_twitter'] ) && ! empty( $metabox['aioseop_opengraph_settings_customimg_twitter'] ) ) { - // Set Twitter image from custom. - $twitter_thumbnail = set_url_scheme( $metabox['aioseop_opengraph_settings_customimg_twitter'] ); - } - - // Apply last filters. - $description = apply_filters( 'aioseop_description', $description ); - - $meta = array( - 'facebook' => array( - 'title' => 'og:title', - 'type' => 'og:type', - 'url' => 'og:url', - 'thumbnail' => 'og:image', - 'width' => 'og:image:width', - 'height' => 'og:image:height', - 'video' => 'og:video', - 'videowidth' => 'og:video:width', - 'videoheight' => 'og:video:height', - 'sitename' => 'og:site_name', - 'key' => 'fb:admins', - 'appid' => 'fb:app_id', - 'description' => 'og:description', - 'section' => 'article:section', - 'tag' => 'article:tag', - 'publisher' => 'article:publisher', - 'author' => 'article:author', - 'published_time' => 'article:published_time', - 'modified_time' => 'article:modified_time', - ), - 'twitter' => array( - 'card' => 'twitter:card', - 'site' => 'twitter:site', - 'creator' => 'twitter:creator', - 'domain' => 'twitter:domain', - 'title' => 'twitter:title', - 'description' => 'twitter:description', - 'twitter_thumbnail' => 'twitter:image', - ), - ); - - // https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/1848 - if ( is_ssl() ) { - $meta['facebook'] += array( 'thumbnail_1' => 'og:image:secure_url' ); - $thumbnail_1 = $thumbnail; - } - - $tags = array( - 'facebook' => array( 'name' => 'property', 'value' => 'content' ), - 'twitter' => array( 'name' => 'name', 'value' => 'content' ), - ); - - foreach ( $meta as $t => $data ) { - foreach ( $data as $k => $v ) { - if ( empty( $$k ) ) { - $$k = ''; - } - $filtered_value = $$k; - - /** - * Process meta tags for their idiosyncracies. - * - * @since 3.0 - * - * @param string $filtered_value The value that is proposed to be shown in the tag. - * @param string $t The social network. - * @param string $k The meta tag without the network name prefixed. - * @param string $v The meta tag with the network name prefixed. This is not always $network:$meta_tag. - * @param array $extra_params Extra parameters that might be required to process the meta tag. - */ - $filtered_value = apply_filters( $this->prefix . 'meta', $filtered_value, $t, $k, $v, $extra_params ); - if ( ! empty( $filtered_value ) ) { - if ( ! is_array( $filtered_value ) ) { - $filtered_value = array( $filtered_value ); - } - - /** - * This is to accomodate multiple fb:admins on separate lines. - * @TODO Eventually we'll want to put this in its own function so things like images work too. - */ - if ( 'key' === $k ) { - $fbadmins = explode( ',', str_replace( ' ', '', $filtered_value[0] ) ); // Trim spaces then turn comma-separated values into an array. - foreach ( $fbadmins as $fbadmin ) { - echo '' . "\n"; - } - } else { - // For everything else. - foreach ( $filtered_value as $f ) { - // #1363: use esc_attr( $f ) instead of htmlspecialchars_decode( $f, ENT_QUOTES ) - echo '' . "\n"; - } - } - } - } - } - $social_link_schema = ''; - if ( ! empty( $social_links ) ) { - $home_url = esc_url( get_home_url() ); - $social_links = explode( "\n", $social_links ); - foreach ( $social_links as $k => $v ) { - $v = trim( $v ); - if ( empty( $v ) ) { - unset( $social_links[ $k ] ); - } else { - $v = esc_url( $v ); - $social_links[ $k ] = $v; - } - } - $social_links = join( '","', $social_links ); - $social_link_schema = << -{ "@context" : "https://schema.org", - "@type" : "{$social_type}", - "name" : "{$social_name}", - "url" : "{$home_url}", - "sameAs" : ["{$social_links}"] -} - - -END; - } - - // Only show if "use schema.org markup is checked". - if ( ! empty( $aioseop_options['aiosp_schema_markup'] ) ) { - echo apply_filters( 'aiosp_opengraph_social_link_schema', $social_link_schema ); - } - } - - /** - * Do / adds opengraph properties to meta. - * @since 2.3.11 - * - * @global array $aioseop_options AIOSEOP plugin options. - */ - public function do_opengraph() { - global $aioseop_options; - if ( ! empty( $aioseop_options ) - && ! empty( $aioseop_options['aiosp_schema_markup'] ) - ) { - add_filter( 'language_attributes', array( &$this, 'add_attributes' ) ); - } - if ( ! defined( 'DOING_AJAX' ) ) { - add_action( 'aioseop_modules_wp_head', array( &$this, 'add_meta' ), 5 ); - // Add social meta to AMP plugin. - if ( apply_filters( 'aioseop_enable_amp_social_meta', true ) === true ) { - add_action( 'amp_post_template_head', array( &$this, 'add_meta' ), 12 ); - } - } - } - - /** - * Set up types. - * - * @since ? - * @since 2.3.15 Change to website for homepage and blog post index page, default to object. - */ - function type_setup() { - $this->type = 'object'; // Default to type object if we don't have some other rule. - - if ( is_home() || is_front_page() ) { - $this->type = 'website'; // Home page and blog page should be website. - } elseif ( is_singular() && $this->option_isset( 'types' ) ) { - $metabox = $this->get_current_options( array(), 'settings' ); - $current_post_type = get_post_type(); - if ( ! empty( $metabox['aioseop_opengraph_settings_category'] ) ) { - $this->type = $metabox['aioseop_opengraph_settings_category']; - } elseif ( isset( $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ] ) ) { - $this->type = $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ]; - } - } - } - - /** - * Inits hooks and others for admin init. - * action:admin_init. - * - * @since 2.3.11 - * @since 2.4.14 Refactored function name, and new filter added for defaults and missing term metabox. - */ - function admin_init() { - add_filter( $this->prefix . 'display_settings', array( &$this, 'filter_settings' ), 10, 3 ); - add_filter( $this->prefix . 'override_options', array( &$this, 'override_options' ), 10, 3 ); - add_filter( - $this->get_prefix( 'settings' ) . 'default_options', array( - &$this, - 'filter_default_options', - ), 10, 2 - ); - add_filter( - $this->get_prefix( 'settings' ) . 'filter_metabox_options', array( - &$this, - 'filter_metabox_options', - ), 10, 3 - ); - add_filter( - $this->get_prefix( 'settings' ) . 'filter_term_metabox_options', array( - &$this, - 'filter_metabox_options', - ), 10, 3 - ); - $post_types = $this->get_post_type_titles(); - $rempost = array( - 'revision' => 1, - 'nav_menu_item' => 1, - 'custom_css' => 1, - 'customize_changeset' => 1, - ); - $post_types = array_diff_key( $post_types, $rempost ); - $this->default_options['types']['initial_options'] = $post_types; - foreach ( $post_types as $slug => $name ) { - $field = $slug . '_fb_object_type'; - $this->default_options[ $field ] = array( - 'name' => "$name " . __( 'Object Type', 'all-in-one-seo-pack' ) . "
                      ($slug)", - 'type' => 'select', - 'style' => '', - 'initial_options' => $this->fb_object_types, - 'default' => 'article', - 'condshow' => array( 'aiosp_opengraph_types\[\]' => $slug ), - ); - $this->locations['opengraph']['options'][] = $field; - $this->layout['facebook']['options'][] = $field; - } - $this->setting_options(); - } - - function get_all_images( $options = null, $p = null ) { - static $img = array(); - if ( ! is_array( $options ) ) { - $options = array(); - } - if ( ! empty( $this->options['aiosp_opengraph_meta_key'] ) ) { - $options['meta_key'] = $this->options['aiosp_opengraph_meta_key']; - } - if ( empty( $img ) ) { - $size = apply_filters( 'post_thumbnail_size', 'large' ); - $default = $this->get_the_image_by_default(); - if ( ! empty( $default ) ) { - $default = set_url_scheme( $default ); - $img[ $default ] = 0; - } - $img = array_merge( $img, parent::get_all_images( $options, null ) ); - } - - if ( ! empty( $options ) && ! empty( $options['aioseop_opengraph_settings_customimg'] ) ) { - $img[ $options['aioseop_opengraph_settings_customimg'] ] = 'customimg'; - } - - if ( ! empty( $options ) && ! empty( $options['aioseop_opengraph_settings_customimg'] ) ) { - $img[ $options['aioseop_opengraph_settings_customimg'] ] = 'customimg'; - $img[ $options['aioseop_opengraph_settings_customimg_twitter'] ] = 'customimg_twitter'; - } - - if ( $author_img = $this->get_the_image_by_author( $p ) ) { - $image['author'] = $author_img; - } - $image = array_flip( $img ); - $images = array(); - if ( ! empty( $image ) ) { - foreach ( $image as $k => $v ) { - $images[ $v ] = ''; - } - } - - return array( $image, $images ); - } - - function get_the_image_by_author( $options = null, $p = null ) { - if ( $p === null ) { - global $post; - } else { - $post = $p; - } - if ( ! empty( $post ) && ! empty( $post->post_author ) ) { - $matches = array(); - $get_avatar = get_avatar( $post->post_author, 300 ); - if ( preg_match( "/src='(.*?)'/i", $get_avatar, $matches ) ) { - return $matches[1]; - } - } - - return false; - } - - function get_the_image( $options = null, $p = null ) { - $meta_key = $this->options['aiosp_opengraph_meta_key']; - - return parent::get_the_image( array( 'meta_key' => $meta_key ), $p ); - } - - function get_the_image_by_default( $args = array() ) { - return $this->options['aiosp_opengraph_dimg']; - } - - function settings_update() { - - } - - /** - * Admin Enqueue Scripts - * - * Add hook in \All_in_One_SEO_Pack_Module::enqueue_metabox_scripts - Bails adding hook if not on target valid screen. - * Add hook in \All_in_One_SEO_Pack_Module::add_page_hooks - Function itself is hooked based on the screen_id/page. - * - * @since 2.9.2 - * - * @see 'admin_enqueue_scripts' hook - * @link https://developer.wordpress.org/reference/hooks/admin_enqueue_scripts/ - * - * @param string $hook_suffix - */ - public function admin_enqueue_scripts( $hook_suffix ) { - wp_enqueue_script( - 'aioseop-opengraph-script', - AIOSEOP_PLUGIN_URL . 'js/modules/aioseop_opengraph.js', - array(), - AIOSEOP_VERSION - ); - - wp_enqueue_script( - 'aioseop-post-edit-script', - AIOSEOP_PLUGIN_URL . 'js/count-chars.js', - array(), - AIOSEOP_VERSION - ); - - $localize_post_edit = array( - 'aiosp_title_extra' => 0, - ); - wp_localize_script( 'aioseop-post-edit-script', 'aioseop_count_chars', $localize_post_edit ); - - // Dev note: If certain JS files need to be restricted to select screens, then follow concept - // used in `All_in_One_SEO_Pack::admin_enqueue_scripts()` (v2.9.1); which uses the `$hook_suffix` - // and a switch-case. This also helps prevent unnessecarily processing localized data when it isn't needed. - parent::admin_enqueue_scripts( $hook_suffix ); - } - - /** - * Enqueue our file upload scripts and styles. - * @param $hook - */ - function og_admin_enqueue_scripts( $hook ) { - - if ( 'all-in-one-seo_page_aiosp_opengraph' != $hook && 'term.php' != $hook ) { - // Only enqueue if we're on the social module settings page. - return; - } - - wp_enqueue_script( 'media-upload' ); - wp_enqueue_script( 'thickbox' ); - wp_enqueue_style( 'thickbox' ); - wp_enqueue_media(); - } - - function save_tax_data( $term_id, $tt_id, $taxonomy ) { - static $update = false; - if ( $update ) { - return; - } - if ( $this->locations !== null ) { - foreach ( $this->locations as $k => $v ) { - if ( isset( $v['type'] ) && ( $v['type'] === 'metabox' ) ) { - $opts = $this->default_options( $k ); - $options = array(); - $update = false; - foreach ( $opts as $l => $o ) { - if ( isset( $_POST[ $l ] ) ) { - $options[ $l ] = stripslashes_deep( $_POST[ $l ] ); - $options[ $l ] = esc_attr( $options[ $l ] ); - $update = true; - } - } - if ( $update ) { - $prefix = $this->get_prefix( $k ); - $options = apply_filters( $prefix . 'filter_term_metabox_options', $options, $k, $term_id ); - update_term_meta( $term_id, '_' . $prefix . $k, $options ); - } - } - } - } - } - - /** - * Returns the placeholder filtered and ready for DOM display. - * filter:aioseop_opengraph_placeholder - * @since 2.4.14 - * - * @param mixed $placeholder Placeholder to be filtered. - * @param string $type Type of the value to be filtered. - * - * @return string - */ - public function filter_placeholder( $placeholder, $type = 'text' ) { - return strip_tags( trim( $placeholder ) ); - } - - /** - * Returns filtered default options. - * filter:{prefix}default_options - * @since 2.4.13 - * - * @param array $options Default options. - * @param string $location Location. - * - * @return array - */ - public function filter_default_options( $options, $location ) { - if ( $location === 'settings' ) { - $prefix = $this->get_prefix( $location ) . $location . '_'; - // Add image checker as default - $options[ $prefix . 'customimg_checker' ] = 0; - } - return $options; - } - } -} +name = __( 'Social Meta', 'all-in-one-seo-pack' ); // Human-readable name of the plugin + $this->prefix = 'aiosp_opengraph_'; // option prefix + $this->file = __FILE__; // the current file + $this->fb_object_types = array( + 'Activities' => array( + 'activity' => __( 'Activity', 'all-in-one-seo-pack' ), + 'sport' => __( 'Sport', 'all-in-one-seo-pack' ), + ), + 'Businesses' => array( + 'bar' => __( 'Bar', 'all-in-one-seo-pack' ), + 'company' => __( 'Company', 'all-in-one-seo-pack' ), + 'cafe' => __( 'Cafe', 'all-in-one-seo-pack' ), + 'hotel' => __( 'Hotel', 'all-in-one-seo-pack' ), + 'restaurant' => __( 'Restaurant', 'all-in-one-seo-pack' ), + ), + 'Groups' => array( + 'cause' => __( 'Cause', 'all-in-one-seo-pack' ), + 'sports_league' => __( 'Sports League', 'all-in-one-seo-pack' ), + 'sports_team' => __( 'Sports Team', 'all-in-one-seo-pack' ), + ), + 'Organizations' => array( + 'band' => __( 'Band', 'all-in-one-seo-pack' ), + 'government' => __( 'Government', 'all-in-one-seo-pack' ), + 'non_profit' => __( 'Non Profit', 'all-in-one-seo-pack' ), + 'school' => __( 'School', 'all-in-one-seo-pack' ), + 'university' => __( 'University', 'all-in-one-seo-pack' ), + ), + 'People' => array( + 'actor' => __( 'Actor', 'all-in-one-seo-pack' ), + 'athlete' => __( 'Athlete', 'all-in-one-seo-pack' ), + 'author' => __( 'Author', 'all-in-one-seo-pack' ), + 'director' => __( 'Director', 'all-in-one-seo-pack' ), + 'musician' => __( 'Musician', 'all-in-one-seo-pack' ), + 'politician' => __( 'Politician', 'all-in-one-seo-pack' ), + 'profile' => __( 'Profile', 'all-in-one-seo-pack' ), + 'public_figure' => __( 'Public Figure', 'all-in-one-seo-pack' ), + ), + 'Places' => array( + 'city' => __( 'City', 'all-in-one-seo-pack' ), + 'country' => __( 'Country', 'all-in-one-seo-pack' ), + 'landmark' => __( 'Landmark', 'all-in-one-seo-pack' ), + 'state_province' => __( 'State Province', 'all-in-one-seo-pack' ), + ), + 'Products and Entertainment' => array( + 'album' => __( 'Album', 'all-in-one-seo-pack' ), + 'book' => __( 'Book', 'all-in-one-seo-pack' ), + 'drink' => __( 'Drink', 'all-in-one-seo-pack' ), + 'food' => __( 'Food', 'all-in-one-seo-pack' ), + 'game' => __( 'Game', 'all-in-one-seo-pack' ), + 'movie' => __( 'Movie', 'all-in-one-seo-pack' ), + 'product' => __( 'Product', 'all-in-one-seo-pack' ), + 'song' => __( 'Song', 'all-in-one-seo-pack' ), + 'tv_show' => __( 'TV Show', 'all-in-one-seo-pack' ), + 'episode' => __( 'Episode', 'all-in-one-seo-pack' ), + ), + 'Websites' => array( + 'article' => __( 'Article', 'all-in-one-seo-pack' ), + 'website' => __( 'Website', 'all-in-one-seo-pack' ), + ), + ); + parent::__construct(); + + if ( is_admin() ) { + add_action( 'admin_init', array( $this, 'admin_init' ), 5 ); + } else { + add_action( 'wp', array( $this, 'type_setup' ) ); + } + + if ( ! is_admin() || defined( 'DOING_AJAX' ) || defined( 'AIOSEOP_UNIT_TESTING' ) ) { + $this->do_opengraph(); + } + // Set variables after WordPress load. + add_action( 'init', array( &$this, 'init' ), 999999 ); + add_filter( 'jetpack_enable_open_graph', '__return_false' ); // Avoid having duplicate meta tags + add_filter( $this->prefix . 'meta', array( $this, 'handle_meta_tag' ), 10, 5 ); + // Force refresh of Facebook cache. + add_action( 'post_updated', array( &$this, 'force_fb_refresh_update' ), 10, 3 ); + add_action( 'transition_post_status', array( &$this, 'force_fb_refresh_transition' ), 10, 3 ); + add_action( 'edited_term', array( &$this, 'save_tax_data' ), 10, 3 ); + // Adds special filters + add_filter( 'aioseop_opengraph_placeholder', array( &$this, 'filter_placeholder' ) ); + add_action( 'aiosp_activate_opengraph', array( $this, 'activate_module' ) ); + add_action( 'created_term', array( $this, 'created_term' ), 10, 3 ); + // Call to init to generate menus + $this->init(); + } + + /** + * Process meta tags for specific idiosyncrasies. + * + * @since 3.0 + * + * @param string $value The value that is proposed to be shown in the tag. + * @param string $network The social network. + * @param string $meta_tag The meta tag without the network name prefixed. + * @param string $network_meta_tag The meta tag with the network name prefixed. This is not always $network:$meta_tag. + * @param array $extra_params Extra parameters that might be required to process the meta tag. + * + * @return string The final value that will be shown. + */ + function handle_meta_tag( $value, $network, $meta_tag, $network_meta_tag, $extra_params ) { + switch ( $meta_tag ) { + case 'type': + // https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/1013 + if ( 'blog' === $value ) { + $value = 'website'; + } + break; + } + + /** + * Disables truncation of meta tags. Return true to shortcircuit and disable truncation. + * + * @since 3.0 + * + * @issue https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/808 + * @issue https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/2296 + * + * @param bool The value that is proposed to be shown in the tag. + * @param string $network The social network. + * @param string $meta_tag The meta tag without the network name prefixed. + * @param string $network_meta_tag The meta tag with the network name prefixed. This is not always $network:$meta_tag. + * @param array $extra_params Extra parameters that might be required to process the meta tag. + */ + if ( true === apply_filters( $this->prefix . 'disable_meta_tag_truncation', false, $network, $meta_tag, $network_meta_tag ) ) { + return $value; + } + + if ( isset( $extra_params['auto_generate_desc'] ) && $extra_params['auto_generate_desc'] ) { + switch ( $network_meta_tag ) { + case 'twitter:title': + // https://developer.twitter.com/en/docs/tweets/optimize-with-cards/overview/markup.html + $value = trim( $this->substr( $value, 0, 70 ) ); + break; + case 'og:description': + case 'twitter:description': + $value = trim( $this->substr( $value, 0, 200 ) ); + break; + } + } + return $value; + } + + /** + * Sets the terms defaults after a new term is created. + * + * @param int $term_id Term ID. + * @param int $tt_id Term taxonomy ID. + * @param string $taxonomy Taxonomy slug. + */ + function created_term( $term_id, $tt_id, $taxonomy_name ) { + $k = 'settings'; + $prefix = $this->get_prefix( $k ); + $tax = get_taxonomy( $taxonomy_name ); + $this->set_object_type_for_taxonomy( $prefix, $k, $taxonomy_name, $tax, false, array( $term_id ) ); + } + + /** + * Sets the defaults for a taxonomy. + * + * @param string $prefix The prefix of this module. + * @param string $k The key against which the options will be determined/set. + * @param string $taxonomy_name The name of the taxonomy. + * @param Object $tax The taxonomy object. + * @param bool $bail_if_no_terms Bail if the taxonomy has no terms. + * @param array $terms The terms in the taxonomy. + */ + private function set_object_type_for_taxonomy( $prefix, $k, $taxonomy_name, $tax, $bail_if_no_terms = false, $terms = null ) { + $object_type = null; + if ( ! $terms ) { + $terms = get_terms( + $taxonomy_name, array( + 'meta_query' => array( + array( + 'key' => '_' . $prefix . $k, + 'compare' => 'NOT EXISTS', + ), + ), + 'number' => PHP_INT_MAX, + 'fields' => 'ids', + 'hide_empty' => false, + ) + ); + } + + if ( empty( $terms ) && $bail_if_no_terms ) { + return false; + } + + if ( true === $tax->_builtin ) { + $object_type = 'article'; + } else { + // custom taxonomy. Let's get a post against this to determine its post type. + $posts = get_posts( + array( + 'numberposts' => 1, + 'post_type' => 'any', + 'tax_query' => array( + array( + 'taxonomy' => $taxonomy_name, + 'field' => 'term_id', + 'terms' => $terms, + ), + ), + ) + ); + if ( $posts ) { + global $aioseop_options; + $post_type = $posts[0]->post_type; + if ( isset( $aioseop_options['modules'] ) && isset( $aioseop_options['modules'][ $this->prefix . 'options' ] ) ) { + $og_options = $aioseop_options['modules'][ $this->prefix . 'options' ]; + + // now let's see what default object type is set for this post type. + $object_type_set = $og_options[ $this->prefix . $post_type . '_fb_object_type' ]; + if ( ! empty( $object_type_set ) ) { + $object_type = $object_type_set; + } + } + } + } + + if ( $object_type ) { + $opts[ $prefix . $k . '_category' ] = $object_type; + foreach ( $terms as $term_id ) { + update_term_meta( $term_id, '_' . $prefix . $k, $opts ); + } + } + + return true; + } + + /** + * Called when this module is activated. + */ + public function activate_module() { + if ( $this->locations !== null ) { + foreach ( $this->locations as $k => $v ) { + if ( ! isset( $v['type'] ) || 'metabox' !== $v['type'] ) { + continue; + } + $this->set_virgin_tax_terms( $k ); + } + } + } + /** + * This iterates over all taxonomies that do not have a opengraph setting defined and sets the defaults. + * + * @param string $k The key against which the options will be determined/set. + */ + private function set_virgin_tax_terms( $k ) { + $prefix = $this->get_prefix( $k ); + $opts = $this->default_options( $k ); + $taxonomies = get_taxonomies( array( 'public' => true ), 'object' ); + if ( ! $taxonomies ) { + return; + } + foreach ( $taxonomies as $name => $tax ) { + $this->set_object_type_for_taxonomy( $prefix, $k, $name, $tax, true, null ); + + } + } + + /** + * Hook called after WordPress has been loaded. + * + * @since 2.4.14 + */ + public function init() { + $count_desc = __( ' characters. We recommend a maximum of %1$s chars for the %2$s.', 'all-in-one-seo-pack' ); + // Create default options + $this->default_options = array( + 'scan_header' => array( + 'name' => __( 'Scan Header', 'all-in-one-seo-pack' ), + 'type' => 'custom', + 'save' => true, + ), + 'setmeta' => array( + 'name' => __( 'Use AIOSEO Title and Description', 'all-in-one-seo-pack' ), + 'type' => 'checkbox', + ), + 'key' => array( + 'name' => __( 'Facebook Admin ID', 'all-in-one-seo-pack' ), + 'default' => '', + 'type' => 'text', + ), + 'appid' => array( + 'name' => __( 'Facebook App ID', 'all-in-one-seo-pack' ), + 'default' => '', + 'type' => 'text', + ), + 'title_shortcodes' => array( + 'name' => __( 'Run Shortcodes In Title', 'all-in-one-seo-pack' ), + ), + 'description_shortcodes' => array( + 'name' => __( 'Run Shortcodes In Description', 'all-in-one-seo-pack' ), + ), + 'sitename' => array( + 'name' => __( 'Site Name', 'all-in-one-seo-pack' ), + 'default' => get_bloginfo( 'name' ), + 'type' => 'text', + ), + 'hometitle' => array( + 'name' => __( 'Home Title', 'all-in-one-seo-pack' ), + 'default' => '', + 'type' => 'text', + 'class' => 'aioseop_count_chars', + 'count' => true, + 'count_desc' => $count_desc, + 'size' => 95, + 'condshow' => array( + 'aiosp_opengraph_setmeta' => array( + 'lhs' => 'aiosp_opengraph_setmeta', + 'op' => '!=', + 'rhs' => 'on', + ), + ), + ), + 'description' => array( + 'name' => __( 'Home Description', 'all-in-one-seo-pack' ), + 'default' => '', + 'type' => 'textarea', + 'class' => 'aioseop_count_chars', + 'count' => true, + 'count_desc' => $count_desc, + 'size' => 200, + 'condshow' => array( + 'aiosp_opengraph_setmeta' => array( + 'lhs' => 'aiosp_opengraph_setmeta', + 'op' => '!=', + 'rhs' => 'on', + ), + ), + ), + 'homeimage' => array( + 'name' => __( 'Home Image', 'all-in-one-seo-pack' ), + 'type' => 'image', + ), + 'generate_descriptions' => array( + 'name' => __( 'Use Content For Autogenerated OG Descriptions', 'all-in-one-seo-pack' ), + 'default' => 0, + ), + 'defimg' => array( + 'name' => __( 'Select OG:Image Source', 'all-in-one-seo-pack' ), + 'type' => 'select', + 'initial_options' => array( + '' => __( 'Default Image' ), + 'featured' => __( 'Featured Image' ), + 'attach' => __( 'First Attached Image' ), + 'content' => __( 'First Image In Content' ), + 'custom' => __( 'Image From Custom Field' ), + 'author' => __( 'Post Author Image' ), + 'auto' => __( 'First Available Image' ), + ), + ), + 'fallback' => array( + 'name' => __( 'Use Default If No Image Found', 'all-in-one-seo-pack' ), + 'type' => 'checkbox', + ), + 'dimg' => array( + 'name' => __( 'Default OG:Image', 'all-in-one-seo-pack' ), + 'default' => AIOSEOP_PLUGIN_IMAGES_URL . 'default-user-image.png', + 'type' => 'image', + ), + 'dimgwidth' => array( + 'name' => __( 'Default Image Width', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + ), + 'dimgheight' => array( + 'name' => __( 'Default Image Height', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + ), + 'meta_key' => array( + 'name' => __( 'Use Custom Field For Image', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + ), + 'image' => array( + 'name' => __( 'Image', 'all-in-one-seo-pack' ), + 'type' => 'radio', + 'initial_options' => array( + 0 => '', + ), + ), + 'customimg' => array( + 'name' => __( 'Custom Image', 'all-in-one-seo-pack' ), + 'type' => 'image', + ), + 'imagewidth' => array( + 'name' => __( 'Specify Image Width', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + ), + 'imageheight' => array( + 'name' => __( 'Specify Image Height', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + ), + 'video' => array( + 'name' => __( 'Custom Video', 'all-in-one-seo-pack' ), + 'type' => 'text', + ), + 'videowidth' => array( + 'name' => __( 'Specify Video Width', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + 'condshow' => array( + 'aioseop_opengraph_settings_video' => array( + 'lhs' => 'aioseop_opengraph_settings_video', + 'op' => '!=', + 'rhs' => '', + ), + ), + ), + 'videoheight' => array( + 'name' => __( 'Specify Video Height', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + 'condshow' => array( + 'aioseop_opengraph_settings_video' => array( + 'lhs' => 'aioseop_opengraph_settings_video', + 'op' => '!=', + 'rhs' => '', + ), + ), + ), + 'defcard' => array( + 'name' => __( 'Default Twitter Card', 'all-in-one-seo-pack' ), + 'type' => 'select', + 'default' => 'summary', + 'initial_options' => array( + 'summary' => __( 'Summary', 'all-in-one-seo-pack' ), + 'summary_large_image' => __( 'Summary Large Image', 'all-in-one-seo-pack' ), + + /* + REMOVING THIS TWITTER CARD TYPE FROM SOCIAL META MODULE + 'photo' => __( 'Photo', 'all-in-one-seo-pack' ) + */ + ), + ), + 'setcard' => array( + 'name' => __( 'Twitter Card Type', 'all-in-one-seo-pack' ), + 'type' => 'select', + 'initial_options' => array( + 'summary_large_image' => __( 'Summary Large Image', 'all-in-one-seo-pack' ), + 'summary' => __( 'Summary', 'all-in-one-seo-pack' ), + + /* + REMOVING THIS TWITTER CARD TYPE FROM SOCIAL META MODULE + 'photo' => __( 'Photo', 'all-in-one-seo-pack' ) + */ + ), + ), + 'twitter_site' => array( + 'name' => __( 'Twitter Site', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + ), + 'twitter_creator' => array( + 'name' => __( 'Show Twitter Author', 'all-in-one-seo-pack' ), + ), + 'twitter_domain' => array( + 'name' => __( 'Twitter Domain', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + ), + 'customimg_twitter' => array( + 'name' => __( 'Custom Twitter Image', 'all-in-one-seo-pack' ), + 'type' => 'image', + ), + 'gen_tags' => array( + 'name' => __( 'Automatically Generate Article Tags', 'all-in-one-seo-pack' ), + ), + 'gen_keywords' => array( + 'name' => __( 'Use Keywords In Article Tags', 'all-in-one-seo-pack' ), + 'default' => 'on', + 'condshow' => array( 'aiosp_opengraph_gen_tags' => 'on' ), + ), + 'gen_categories' => array( + 'name' => __( 'Use Categories In Article Tags', 'all-in-one-seo-pack' ), + 'default' => 'on', + 'condshow' => array( 'aiosp_opengraph_gen_tags' => 'on' ), + ), + 'gen_post_tags' => array( + 'name' => __( 'Use Post Tags In Article Tags', 'all-in-one-seo-pack' ), + 'default' => 'on', + 'condshow' => array( 'aiosp_opengraph_gen_tags' => 'on' ), + ), + 'types' => array( + 'name' => __( 'Enable Facebook Meta for Post Types', 'all-in-one-seo-pack' ), + 'type' => 'multicheckbox', + 'default' => array( 'post' => 'post', 'page' => 'page' ), + 'initial_options' => $this->get_post_type_titles( array( '_builtin' => false ) ), + ), + 'title' => array( + 'name' => __( 'Title', 'all-in-one-seo-pack' ), + 'default' => '', + 'type' => 'text', + 'size' => 95, + 'count' => 1, + 'count_desc' => $count_desc, + ), + 'desc' => array( + 'name' => __( 'Description', 'all-in-one-seo-pack' ), + 'default' => '', + 'type' => 'textarea', + 'cols' => 50, + 'rows' => 4, + 'count' => 1, + 'count_desc' => $count_desc, + ), + 'category' => array( + 'name' => __( 'Facebook Object Type', 'all-in-one-seo-pack' ), + 'type' => 'select', + 'style' => '', + 'default' => '', + 'initial_options' => $this->fb_object_types, + ), + 'facebook_debug' => array( + 'name' => __( 'Facebook Debug', 'all-in-one-seo-pack' ), + 'type' => 'html', + 'save' => false, + 'default' => '' . __( 'Debug This Post', 'all-in-one-seo-pack' ) . '', + ), + 'section' => array( + 'name' => __( 'Article Section', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + 'condshow' => array( 'aioseop_opengraph_settings_category' => 'article' ), + ), + 'tag' => array( + 'name' => __( 'Article Tags', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + 'condshow' => array( 'aioseop_opengraph_settings_category' => 'article' ), + ), + 'facebook_publisher' => array( + 'name' => __( 'Show Facebook Publisher on Articles', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + ), + 'facebook_author' => array( + 'name' => __( 'Show Facebook Author on Articles', 'all-in-one-seo-pack' ), + ), + 'profile_links' => array( + 'name' => __( 'Social Profile Links', 'all-in-one-seo-pack' ), + 'type' => 'textarea', + 'cols' => 60, + 'rows' => 5, + ), + 'person_or_org' => array( + 'name' => __( 'Person or Organization?', 'all-in-one-seo-pack' ), + 'type' => 'radio', + 'initial_options' => array( + 'person' => __( 'Person', 'all-in-one-seo-pack' ), + 'org' => __( 'Organization', 'all-in-one-seo-pack' ), + ), + ), + 'social_name' => array( + 'name' => __( 'Associated Name', 'all-in-one-seo-pack' ), + 'type' => 'text', + 'default' => '', + ), + ); + // load initial options / set defaults + $this->update_options(); + $display = array(); + if ( isset( $this->options['aiosp_opengraph_types'] ) && ! empty( $this->options['aiosp_opengraph_types'] ) ) { + $display = $this->options['aiosp_opengraph_types']; + } + $this->locations = array( + 'opengraph' => array( + 'name' => $this->name, + 'prefix' => 'aiosp_', + 'type' => 'settings', + 'options' => array( + 'scan_header', + 'setmeta', + 'key', + 'appid', + 'sitename', + 'title_shortcodes', + 'description_shortcodes', + 'hometitle', + 'description', + 'homeimage', + 'generate_descriptions', + 'defimg', + 'fallback', + 'dimg', + 'dimgwidth', + 'dimgheight', + 'meta_key', + 'defcard', + 'profile_links', + 'person_or_org', + 'social_name', + 'twitter_site', + 'twitter_creator', + 'twitter_domain', + 'gen_tags', + 'gen_keywords', + 'gen_categories', + 'gen_post_tags', + 'types', + 'facebook_publisher', + 'facebook_author', + ), + ), + 'settings' => array( + 'name' => __( 'Social Settings', 'all-in-one-seo-pack' ), + 'type' => 'metabox', + 'help_link' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/', + 'options' => array( + 'title', + 'desc', + 'image', + 'customimg', + 'imagewidth', + 'imageheight', + 'video', + 'videowidth', + 'videoheight', + 'category', + 'facebook_debug', + 'section', + 'tag', + 'setcard', + 'customimg_twitter', + ), + 'display' => apply_filters( 'aioseop_opengraph_display', $display ), + 'prefix' => 'aioseop_opengraph_', + ), + ); + $this->layout = array( + 'home' => array( + 'name' => __( 'Home Page Settings', 'all-in-one-seo-pack' ), + 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#use-aioseo-title-and-description', + 'options' => array( 'setmeta', 'sitename', 'hometitle', 'description', 'homeimage' ), + ), + 'image' => array( + 'name' => __( 'Image Settings', 'all-in-one-seo-pack' ), + 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#select-og-image-source', + 'options' => array( 'defimg', 'fallback', 'dimg', 'dimgwidth', 'dimgheight', 'meta_key' ), + ), + 'links' => array( + 'name' => __( 'Social Profile Links', 'all-in-one-seo-pack' ), + 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#social-profile-links', + 'options' => array( 'profile_links', 'person_or_org', 'social_name' ), + ), + 'facebook' => array( + 'name' => __( 'Facebook Settings', 'all-in-one-seo-pack' ), + 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#facebook-settings', + 'options' => array( + 'key', + 'appid', + 'types', + 'gen_tags', + 'gen_keywords', + 'gen_categories', + 'gen_post_tags', + 'facebook_publisher', + 'facebook_author', + ), + ), + 'twitter' => array( + 'name' => __( 'Twitter Settings', 'all-in-one-seo-pack' ), + 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#default-twitter-card', + 'options' => array( 'defcard', 'setcard', 'twitter_site', 'twitter_creator', 'twitter_domain' ), + ), + 'default' => array( + 'name' => __( 'Advanced Settings', 'all-in-one-seo-pack' ), + 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/', + 'options' => array(), // this is set below, to the remaining options -- pdb + ), + 'scan_meta' => array( + 'name' => __( 'Scan Social Meta', 'all-in-one-seo-pack' ), + 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#scan_meta', + 'options' => array( 'scan_header' ), + ), + ); + $other_options = array(); + foreach ( $this->layout as $k => $v ) { + $other_options = array_merge( $other_options, $v['options'] ); + } + + $this->layout['default']['options'] = array_diff( array_keys( $this->default_options ), $other_options ); + } + + /** + * Forces FaceBook OpenGraph to refresh its cache when a post is changed to + * + * @param $new_status + * @param $old_status + * @param $post + * + * @todo this and force_fb_refresh_update can probably have the remote POST extracted out. + * + * @see https://developers.facebook.com/docs/sharing/opengraph/using-objects#update + * @since 2.3.11 + */ + function force_fb_refresh_transition( $new_status, $old_status, $post ) { + if ( 'publish' !== $new_status ) { + return; + } + if ( 'future' !== $old_status ) { + return; + } + + $current_post_type = get_post_type(); + + // Only ping Facebook if Social SEO is enabled on this post type. + if ( $this->option_isset( 'types' ) && is_array( $this->options['aiosp_opengraph_types'] ) && in_array( $current_post_type, $this->options['aiosp_opengraph_types'] ) ) { + $post_url = aioseop_get_permalink( $post->ID ); + $endpoint = sprintf( + 'https://graph.facebook.com/?%s', http_build_query( + array( + 'id' => $post_url, + 'scrape' => true, + ) + ) + ); + wp_remote_post( $endpoint, array( 'blocking' => false ) ); + } + } + + /** + * Forces FaceBook OpenGraph refresh on update. + * + * @param $post_id + * @param $post_after + * + * @see https://developers.facebook.com/docs/sharing/opengraph/using-objects#update + * @since 2.3.11 + */ + function force_fb_refresh_update( $post_id, $post_after ) { + + $current_post_type = get_post_type(); + + // Only ping Facebook if Social SEO is enabled on this post type. + if ( 'publish' === $post_after->post_status && $this->option_isset( 'types' ) && is_array( $this->options['aiosp_opengraph_types'] ) && in_array( $current_post_type, $this->options['aiosp_opengraph_types'] ) ) { + $post_url = aioseop_get_permalink( $post_id ); + $endpoint = sprintf( + 'https://graph.facebook.com/?%s', http_build_query( + array( + 'id' => $post_url, + 'scrape' => true, + ) + ) + ); + wp_remote_post( $endpoint, array( 'blocking' => false ) ); + } + } + + function settings_page_init() { + add_filter( 'aiosp_output_option', array( $this, 'display_custom_options' ), 10, 2 ); + } + + function filter_options( $options, $location ) { + if ( $location == 'settings' ) { + $prefix = $this->get_prefix( $location ) . $location . '_'; + list( $legacy, $images ) = $this->get_all_images( $options ); + if ( isset( $options ) && isset( $options[ "{$prefix}image" ] ) ) { + $thumbnail = $options[ "{$prefix}image" ]; + if ( ctype_digit( (string) $thumbnail ) || ( $thumbnail == 'post' ) ) { + if ( $thumbnail == 'post' ) { + $thumbnail = $images['post1']; + } elseif ( ! empty( $legacy[ $thumbnail ] ) ) { + $thumbnail = $legacy[ $thumbnail ]; + } + } + $options[ "{$prefix}image" ] = $thumbnail; + } + if ( empty( $options[ $prefix . 'image' ] ) ) { + $img = array_keys( $images ); + if ( ! empty( $img ) && ! empty( $img[1] ) ) { + $options[ $prefix . 'image' ] = $img[1]; + } + } + } + + return $options; + } + + /** + * Applies filter to module settings. + * + * @since 2.3.11 + * @since 2.4.14 Added filter for description and title placeholders. + * @since 2.3.15 do_shortcode on description. + * + * @see [plugin]\admin\aioseop_module_class.php > display_options() + */ + function filter_settings( $settings, $location, $current ) { + global $aiosp, $post; + if ( $location == 'opengraph' || $location == 'settings' ) { + $prefix = $this->get_prefix( $location ) . $location . '_'; + if ( $location == 'opengraph' ) { + return $settings; + } + if ( $location == 'settings' ) { + list( $legacy, $settings[ $prefix . 'image' ]['initial_options'] ) = $this->get_all_images( $current ); + $opts = array( 'title', 'desc' ); + $current_post_type = get_post_type(); + if ( isset( $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ] ) ) { + $flat_type_list = array(); + foreach ( $this->fb_object_types as $k => $v ) { + if ( is_array( $v ) ) { + $flat_type_list = array_merge( $flat_type_list, $v ); + } else { + $flat_type_list[ $k ] = $v; + } + } + $default_fb_type = $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ]; + // https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/1013 + // if 'blog' is the selected type but because it is no longer a schema type, we use 'website' instead. + if ( 'blog' === $default_fb_type ) { + $default_fb_type = 'website'; + } + if ( isset( $flat_type_list[ $default_fb_type ] ) ) { + $default_fb_type = $flat_type_list[ $default_fb_type ]; + } + $settings[ $prefix . 'category' ]['initial_options'] = array_merge( + array( + $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ] => __( 'Default ', 'all-in-one-seo-pack' ) . ' - ' . $default_fb_type, + ), + $settings[ $prefix . 'category' ]['initial_options'] + ); + } + if ( isset( $this->options['aiosp_opengraph_defcard'] ) ) { + $settings[ $prefix . 'setcard' ]['default'] = $this->options['aiosp_opengraph_defcard']; + } + $info = $aiosp->get_page_snippet_info(); + $title = $info['title']; + $description = $info['description']; + + // Description options + if ( is_object( $post ) ) { + // Always show excerpt + $description = empty( $this->options['aiosp_opengraph_generate_descriptions'] ) + ? $aiosp->trim_excerpt_without_filters( + $aiosp->internationalize( preg_replace( '/\s+/', ' ', $post->post_excerpt ) ), + 200 + ) + : $aiosp->trim_excerpt_without_filters( + $aiosp->internationalize( preg_replace( '/\s+/', ' ', $post->post_content ) ), + 200 + ); + } + + // #1308 - we want to make sure we are ignoring php version only in the admin area while editing the post, so that it does not impact #932. + $screen = get_current_screen(); + $ignore_php_version = is_admin() && isset( $screen->id ) && 'post' == $screen->id; + + // Add filters + $description = apply_filters( 'aioseop_description', $description, false, $ignore_php_version ); + // Add placholders + $settings[ "{$prefix}title" ]['placeholder'] = apply_filters( 'aioseop_opengraph_placeholder', $title ); + $settings[ "{$prefix}desc" ]['placeholder'] = apply_filters( 'aioseop_opengraph_placeholder', $description ); + } + if ( isset( $current[ $prefix . 'setmeta' ] ) && $current[ $prefix . 'setmeta' ] ) { + foreach ( $opts as $opt ) { + if ( isset( $settings[ $prefix . $opt ] ) ) { + $settings[ $prefix . $opt ]['type'] = 'hidden'; + $settings[ $prefix . $opt ]['label'] = 'none'; + unset( $settings[ $prefix . $opt ]['count'] ); + } + } + } + } + + return $settings; + } + + /** + * Applies filter to module options. + * These will display in the "Social Settings" object tab. + * filter:{prefix}override_options + * + * @since 2.3.11 + * @since 2.4.14 Overrides empty og:type values. + * + * @see [plugin]\admin\aioseop_module_class.php > display_options() + * + * @global array $aioseop_options Plugin options. + * + * @param array $options Current options. + * @param string $location Location where filter is called. + * @param array $settings Settings. + * + * @return array + */ + function override_options( $options, $location, $settings ) { + global $aioseop_options; + // Prepare default and prefix + $prefix = $this->get_prefix( $location ) . $location . '_'; + $opts = array(); + + foreach ( $settings as $k => $v ) { + if ( $v['save'] ) { + $opts[ $k ] = $v['default']; + } + } + foreach ( $options as $k => $v ) { + switch ( $k ) { + case $prefix . 'category': + if ( empty( $v ) ) { + // Get post type + $type = isset( get_current_screen()->post_type ) + ? get_current_screen()->post_type + : null; + // Assign default from plugin options + if ( ! empty( $type ) + && isset( $aioseop_options['modules'] ) + && isset( $aioseop_options['modules']['aiosp_opengraph_options'] ) + && isset( $aioseop_options['modules']['aiosp_opengraph_options'][ 'aiosp_opengraph_' . $type . '_fb_object_type' ] ) + ) { + $options[ $prefix . 'category' ] = + $aioseop_options['modules']['aiosp_opengraph_options'][ 'aiosp_opengraph_' . $type . '_fb_object_type' ]; + } + } + break; + } + if ( $v === null ) { + unset( $options[ $k ] ); + } + } + $options = wp_parse_args( $options, $opts ); + + // https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/1013 + $post_types = $this->get_post_type_titles(); + foreach ( $post_types as $slug => $name ) { + $field = 'aiosp_opengraph_' . $slug . '_fb_object_type'; + if ( isset( $options[ $field ] ) && 'blog' === $options[ $field ] ) { + $options[ $field ] = 'website'; + } + } + + return $options; + } + + /** + * Applies filter to metabox settings before they are saved. + * Sets custom as default if a custom image is uploaded. + * filter:{prefix}filter_metabox_options + * filter:{prefix}filter_term_metabox_options + * + * @since 2.3.11 + * @since 2.4.14 Fixes for aioseop-pro #67 and other bugs found. + * + * @see [plugin]\admin\aioseop_module_class.php > save_post_data() + * @see [this file] > save_tax_data() + * + * @param array $options List of current options. + * @param string $location Location where filter is called. + * @param int $id Either post_id or term_id. + * + * @return array + */ + function filter_metabox_options( $options, $location, $post_id ) { + if ( $location == 'settings' ) { + $prefix = $this->get_prefix( $location ) . $location . '_'; + if ( isset( $options[ $prefix . 'customimg_checker' ] ) + && $options[ $prefix . 'customimg_checker' ] + ) { + $options[ $prefix . 'image' ] = $options[ $prefix . 'customimg' ]; + } + } + return $options; + } + + /** Custom settings **/ + function display_custom_options( $buf, $args ) { + if ( $args['name'] == 'aiosp_opengraph_scan_header' ) { + $buf .= '
                      '; + $args['options']['type'] = 'submit'; + $args['attr'] = " class='button-primary' "; + $args['value'] = $args['options']['default'] = __( 'Scan Now', 'all-in-one-seo-pack' ); + $buf .= __( 'Scan your site for duplicate social meta tags.', 'all-in-one-seo-pack' ); + $buf .= '

                      ' . $this->get_option_html( $args ); + $buf .= '
                      '; + } + + return $buf; + } + + function add_attributes( $output ) { + // avoid having duplicate meta tags + $type = $this->type; + if ( empty( $type ) ) { + $type = 'website'; + } + $schema_types = array( + 'album' => 'MusicAlbum', + 'article' => 'Article', + 'bar' => 'BarOrPub', + 'blog' => 'Blog', + 'book' => 'Book', + 'cafe' => 'CafeOrCoffeeShop', + 'city' => 'City', + 'country' => 'Country', + 'episode' => 'Episode', + 'food' => 'FoodEvent', + 'game' => 'Game', + 'hotel' => 'Hotel', + 'landmark' => 'LandmarksOrHistoricalBuildings', + 'movie' => 'Movie', + 'product' => 'Product', + 'profile' => 'ProfilePage', + 'restaurant' => 'Restaurant', + 'school' => 'School', + 'sport' => 'SportsEvent', + 'website' => 'WebSite', + ); + + if ( ! empty( $schema_types[ $type ] ) ) { + $type = $schema_types[ $type ]; + } else { + $type = 'WebSite'; + } + + $attributes = apply_filters( + $this->prefix . 'attributes', array( + 'prefix="og: http://ogp.me/ns#"', + ) + ); + + foreach ( $attributes as $attr ) { + if ( strpos( $output, $attr ) === false ) { + $output .= "\n\t$attr "; + } + } + + return $output; + } + + /** + * Add our social meta. + * + * @since 1.0.0 + * @since 2.3.11.5 Support for multiple fb_admins. + * @since 2.3.13 Adds filter:aioseop_description on description. + * @since 2.4.14 Fixes for aioseop-pro #67. + * @since 2.3.15 Always do_shortcode on descriptions, removed for titles. + * + * @global object $post Current WP_Post object. + * @global object $aiosp All in one seo plugin object. + * @global array $aioseop_options All in one seo plugin options. + * @global object $wp_query WP_Query global instance. + */ + function add_meta() { + global $post, $aiosp, $aioseop_options, $wp_query; + $metabox = $this->get_current_options( array(), 'settings' ); + $key = $this->options['aiosp_opengraph_key']; + $key = $this->options['aiosp_opengraph_key']; + $dimg = $this->options['aiosp_opengraph_dimg']; + $current_post_type = get_post_type(); + $title = $description = $image = $video = ''; + $type = $this->type; + $sitename = $this->options['aiosp_opengraph_sitename']; + $tag = ''; + + // for some reason, options is not populated correctly during unit tests. + if ( defined( 'AIOSEOP_UNIT_TESTING' ) ) { + $this->options = $aioseop_options['modules'][ $this->prefix . 'options' ]; + } + + $appid = isset( $this->options['aiosp_opengraph_appid'] ) ? $this->options['aiosp_opengraph_appid'] : ''; + + if ( ! empty( $aioseop_options['aiosp_hide_paginated_descriptions'] ) ) { + $first_page = false; + if ( $aiosp->get_page_number() < 2 ) { + $first_page = true; + } + } else { + $first_page = true; + } + $url = $aiosp->aiosp_mrt_get_url( $wp_query ); + $url = apply_filters( 'aioseop_canonical_url', $url ); + + // this will collect the extra values that are required outside the below IF block. + $extra_params = array(); + + $setmeta = $this->options['aiosp_opengraph_setmeta']; + $social_links = ''; + if ( is_front_page() ) { + $title = $this->options['aiosp_opengraph_hometitle']; + if ( $first_page ) { + $description = $this->options['aiosp_opengraph_description']; + if ( empty( $description ) ) { + $description = get_bloginfo( 'description' ); + } + } + if ( ! empty( $this->options['aiosp_opengraph_homeimage'] ) ) { + $thumbnail = $this->options['aiosp_opengraph_homeimage']; + } else { + $thumbnail = $this->options['aiosp_opengraph_dimg']; + } + + /* If Use AIOSEO Title and Desc Selected */ + if ( $setmeta ) { + $title = $aiosp->wp_title(); + if ( $first_page ) { + $description = $aiosp->get_aioseop_description( $post ); + } + } + + /* Add some defaults */ + if ( empty( $title ) ) { + $title = get_bloginfo( 'name' ); + } + if ( empty( $sitename ) ) { + $sitename = get_bloginfo( 'name' ); + } + + if ( empty( $description ) && $first_page && ! empty( $post ) && ! post_password_required( $post ) ) { + + if ( ! empty( $post->post_content ) || ! empty( $post->post_excerpt ) ) { + $description = $aiosp->trim_excerpt_without_filters( $aiosp->internationalize( preg_replace( '/\s+/', ' ', $post->post_excerpt ) ), 200 ); + + if ( ! empty( $this->options['aiosp_opengraph_generate_descriptions'] ) ) { + $description = $aiosp->trim_excerpt_without_filters( $aiosp->internationalize( preg_replace( '/\s+/', ' ', $post->post_content ) ), 200 ); + } + } + } + + if ( empty( $description ) && $first_page ) { + $description = get_bloginfo( 'description' ); + } + if ( ! empty( $this->options['aiosp_opengraph_profile_links'] ) ) { + $social_links = $this->options['aiosp_opengraph_profile_links']; + if ( ! empty( $this->options['aiosp_opengraph_social_name'] ) ) { + $social_name = $this->options['aiosp_opengraph_social_name']; + } else { + $social_name = ''; + } + if ( $this->options['aiosp_opengraph_person_or_org'] == 'person' ) { + $social_type = 'Person'; + } else { + $social_type = 'Organization'; + } + } + } elseif ( is_singular() && $this->option_isset( 'types' ) + && is_array( $this->options['aiosp_opengraph_types'] ) + && in_array( $current_post_type, $this->options['aiosp_opengraph_types'] ) + ) { + + if ( $type == 'article' ) { + if ( ! empty( $metabox['aioseop_opengraph_settings_section'] ) ) { + $section = $metabox['aioseop_opengraph_settings_section']; + } + if ( ! empty( $metabox['aioseop_opengraph_settings_tag'] ) ) { + $tag = $metabox['aioseop_opengraph_settings_tag']; + } + if ( ! empty( $this->options['aiosp_opengraph_facebook_publisher'] ) ) { + $publisher = $this->options['aiosp_opengraph_facebook_publisher']; + } + } + + if ( ! empty( $this->options['aiosp_opengraph_twitter_domain'] ) ) { + $domain = $this->options['aiosp_opengraph_twitter_domain']; + } + + if ( $type == 'article' && ! empty( $post ) ) { + if ( isset( $post->post_author ) && ! empty( $this->options['aiosp_opengraph_facebook_author'] ) ) { + $author = get_the_author_meta( 'facebook', $post->post_author ); + } + + if ( isset( $post->post_date_gmt ) ) { + $published_time = date( 'Y-m-d\TH:i:s\Z', mysql2date( 'U', $post->post_date_gmt ) ); + } + + if ( isset( $post->post_modified_gmt ) ) { + $modified_time = date( 'Y-m-d\TH:i:s\Z', mysql2date( 'U', $post->post_modified_gmt ) ); + } + } + + $image = $metabox['aioseop_opengraph_settings_image']; + $video = $metabox['aioseop_opengraph_settings_video']; + $title = $metabox['aioseop_opengraph_settings_title']; + $description = $metabox['aioseop_opengraph_settings_desc']; + + // Let's make a note of manually provided descriptions/titles as they might need special handling. + // @issue https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/808 + // @issue https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/2296 + $title_from_main_settings = trim( strip_tags( get_post_meta( $post->ID, '_aioseop_title', true ) ) ); + $desc_from_main_settings = trim( strip_tags( get_post_meta( $post->ID, '_aioseop_description', true ) ) ); + if ( empty( $title ) && empty( $title_from_main_settings ) ) { + $extra_params['auto_generate_title'] = true; + } + if ( empty( $description ) && empty( $desc_from_main_settings ) ) { + $extra_params['auto_generate_desc'] = true; + } + + /* Add AIOSEO variables if Site Title and Desc from AIOSEOP not selected */ + global $aiosp; + if ( empty( $title ) ) { + $title = $aiosp->wp_title(); + } + if ( empty( $description ) ) { + $description = trim( strip_tags( get_post_meta( $post->ID, '_aioseop_description', true ) ) ); + } + + /* Add default title */ + if ( empty( $title ) ) { + $title = get_the_title(); + } + + // Add default description. + if ( empty( $description ) && ! post_password_required( $post ) ) { + + $description = $post->post_excerpt; + + if ( $this->options['aiosp_opengraph_generate_descriptions'] || empty( $description ) ) { + if ( ! AIOSEOPPRO || ( AIOSEOPPRO && apply_filters( $this->prefix . 'generate_descriptions_from_content', true, $post ) ) ) { + $description = $post->post_content; + } else { + $description = $post->post_excerpt; + } + } + } + if ( empty( $type ) ) { + $type = 'article'; + } + } elseif ( AIOSEOPPRO && ( is_category() || is_tag() || is_tax() ) ) { + if ( isset( $this->options['aioseop_opengraph_settings_category'] ) ) { + $type = $this->options['aioseop_opengraph_settings_category']; + } + if ( isset( $metabox['aioseop_opengraph_settings_category'] ) ) { + $type = $metabox['aioseop_opengraph_settings_category']; + } + if ( $type == 'article' ) { + if ( ! empty( $metabox['aioseop_opengraph_settings_section'] ) ) { + $section = $metabox['aioseop_opengraph_settings_section']; + } + if ( ! empty( $metabox['aioseop_opengraph_settings_tag'] ) ) { + $tag = $metabox['aioseop_opengraph_settings_tag']; + } + if ( ! empty( $this->options['aiosp_opengraph_facebook_publisher'] ) ) { + $publisher = $this->options['aiosp_opengraph_facebook_publisher']; + } + } + if ( ! empty( $this->options['aiosp_opengraph_twitter_domain'] ) ) { + $domain = $this->options['aiosp_opengraph_twitter_domain']; + } + if ( $type == 'article' && ! empty( $post ) ) { + if ( isset( $post->post_author ) && ! empty( $this->options['aiosp_opengraph_facebook_author'] ) ) { + $author = get_the_author_meta( 'facebook', $post->post_author ); + } + + if ( isset( $post->post_date_gmt ) ) { + $published_time = date( 'Y-m-d\TH:i:s\Z', mysql2date( 'U', $post->post_date_gmt ) ); + } + if ( isset( $post->post_modified_gmt ) ) { + $modified_time = date( 'Y-m-d\TH:i:s\Z', mysql2date( 'U', $post->post_modified_gmt ) ); + } + } + $image = $metabox['aioseop_opengraph_settings_image']; + $video = $metabox['aioseop_opengraph_settings_video']; + $title = $metabox['aioseop_opengraph_settings_title']; + $description = $metabox['aioseop_opengraph_settings_desc']; + /* Add AIOSEO variables if Site Title and Desc from AIOSEOP not selected */ + global $aiosp; + if ( empty( $title ) ) { + $title = $aiosp->wp_title(); + } + if ( empty( $description ) ) { + $term_id = isset( $_GET['tag_ID'] ) ? (int) $_GET['tag_ID'] : 0; + $term_id = $term_id ? $term_id : get_queried_object()->term_id; + $description = trim( strip_tags( get_term_meta( $term_id, '_aioseop_description', true ) ) ); + } + // Add default title + if ( empty( $title ) ) { + $title = get_the_title(); + } + // Add default description. + if ( empty( $description ) && ! post_password_required( $post ) ) { + $description = get_queried_object()->description; + } + if ( empty( $type ) ) { + // https://github.com/semperfiwebdesign/aioseop-pro/issues/321 + if ( AIOSEOPPRO && ( is_category() || is_tag() || is_tax() ) ) { + $og_options = $aioseop_options['modules'][ $this->prefix . 'options' ]; + $current_post_type = get_post_type(); + // check if the post type's object type is set. + if ( isset( $og_options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ] ) ) { + $type = $og_options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ]; + } elseif ( in_array( $current_post_type, array( 'post', 'page' ) ) ) { + $type = 'article'; + } + } else { + $type = 'website'; + } + } + } elseif ( is_home() && ! is_front_page() ) { + // This is the blog page but not the homepage. + global $aiosp; + $image = $metabox['aioseop_opengraph_settings_image']; + $video = $metabox['aioseop_opengraph_settings_video']; + $title = $metabox['aioseop_opengraph_settings_title']; + $description = $metabox['aioseop_opengraph_settings_desc']; + + if ( empty( $description ) ) { + // If there's not social description, fall back to the SEO description. + $description = trim( strip_tags( get_post_meta( get_option( 'page_for_posts' ), '_aioseop_description', true ) ) ); + } + if ( empty( $title ) ) { + $title = $aiosp->wp_title(); + } + } else { + return; + } + + if ( $type === 'article' && ! empty( $post ) && is_singular() ) { + if ( ! empty( $this->options['aiosp_opengraph_gen_tags'] ) ) { + if ( ! empty( $this->options['aiosp_opengraph_gen_keywords'] ) ) { + $keywords = $aiosp->get_main_keywords(); + $keywords = $this->apply_cf_fields( $keywords ); + $keywords = apply_filters( 'aioseop_keywords', $keywords ); + if ( ! empty( $keywords ) && ! empty( $tag ) ) { + $tag .= ',' . $keywords; + } elseif ( empty( $tag ) ) { + $tag = $keywords; + } + } + $tag = $aiosp->keyword_string_to_list( $tag ); + if ( ! empty( $this->options['aiosp_opengraph_gen_categories'] ) ) { + $tag = array_merge( $tag, $aiosp->get_all_categories( $post->ID ) ); + } + if ( ! empty( $this->options['aiosp_opengraph_gen_post_tags'] ) ) { + $tag = array_merge( $tag, $aiosp->get_all_tags( $post->ID ) ); + } + } + if ( ! empty( $tag ) ) { + $tag = $aiosp->clean_keyword_list( $tag ); + } + } + + if ( ! empty( $this->options['aiosp_opengraph_title_shortcodes'] ) ) { + $title = aioseop_do_shortcodes( $title ); + } + if ( ! empty( $description ) ) { + $description = $aiosp->internationalize( preg_replace( '/\s+/', ' ', $description ) ); + if ( ! empty( $this->options['aiosp_opengraph_description_shortcodes'] ) ) { + $description = aioseop_do_shortcodes( $description ); + } + if ( ! empty( $this->options['aiosp_opengraph_generate_descriptions'] ) && $this->options['aiosp_opengraph_generate_descriptions'] ) { + $description = $aiosp->trim_excerpt_without_filters( $description, 200 ); + } else { + // User input still needs to be run through this function to strip tags. + $description = $aiosp->trim_excerpt_without_filters( $description, 99999 ); + } + } + + $title = $this->apply_cf_fields( $title ); + $description = $this->apply_cf_fields( $description ); + + /* Data Validation */ + $title = strip_tags( esc_attr( $title ) ); + $sitename = strip_tags( esc_attr( $sitename ) ); + $description = strip_tags( esc_attr( $description ) ); + + if ( empty( $thumbnail ) && ! empty( $image ) ) { + $thumbnail = $image; + } + + // Add user supplied default image. + if ( empty( $thumbnail ) ) { + if ( empty( $this->options['aiosp_opengraph_defimg'] ) ) { + $thumbnail = $this->options['aiosp_opengraph_dimg']; + } else { + $img_type = $this->options['aiosp_opengraph_defimg']; + if ( ! empty( $post ) ) { + // Customize the type of image per post/post_type. + $img_type = apply_filters( $this->prefix . 'default_image_type', $img_type, $post, $type ); + } + switch ( $img_type ) { + case 'featured': + $thumbnail = $this->get_the_image_by_post_thumbnail(); + break; + case 'attach': + $thumbnail = $this->get_the_image_by_attachment(); + break; + case 'content': + $thumbnail = $this->get_the_image_by_scan(); + break; + case 'custom': + $meta_key = $this->options['aiosp_opengraph_meta_key']; + if ( ! empty( $meta_key ) && ! empty( $post ) ) { + $meta_key = explode( ',', $meta_key ); + $thumbnail = $this->get_the_image_by_meta_key( + array( + 'post_id' => $post->ID, + 'meta_key' => $meta_key, + ) + ); + } + break; + case 'auto': + $thumbnail = $this->get_the_image(); + break; + case 'author': + $thumbnail = $this->get_the_image_by_author(); + break; + default: + $thumbnail = $this->options['aiosp_opengraph_dimg']; + } + } + } + + if ( empty( $thumbnail ) && ! empty( $this->options['aiosp_opengraph_fallback'] ) ) { + $thumbnail = $this->options['aiosp_opengraph_dimg']; + if ( ! empty( $post ) ) { + // Customize the default image per post/post_type. + $thumbnail = apply_filters( $this->prefix . 'default_image', $thumbnail, $post, $type ); + } + } + + if ( ! empty( $thumbnail ) ) { + $thumbnail = esc_url( $thumbnail ); + $thumbnail = set_url_scheme( $thumbnail ); + } + + $width = $height = ''; + if ( ! empty( $thumbnail ) ) { + if ( ! empty( $metabox['aioseop_opengraph_settings_imagewidth'] ) ) { + $width = $metabox['aioseop_opengraph_settings_imagewidth']; + } + if ( ! empty( $metabox['aioseop_opengraph_settings_imageheight'] ) ) { + $height = $metabox['aioseop_opengraph_settings_imageheight']; + } + if ( empty( $width ) && ! empty( $this->options['aiosp_opengraph_dimgwidth'] ) ) { + $width = $this->options['aiosp_opengraph_dimgwidth']; + } + if ( empty( $height ) && ! empty( $this->options['aiosp_opengraph_dimgheight'] ) ) { + $height = $this->options['aiosp_opengraph_dimgheight']; + } + } + + if ( ! empty( $video ) ) { + if ( ! empty( $metabox['aioseop_opengraph_settings_videowidth'] ) ) { + $videowidth = $metabox['aioseop_opengraph_settings_videowidth']; + } + if ( ! empty( $metabox['aioseop_opengraph_settings_videoheight'] ) ) { + $videoheight = $metabox['aioseop_opengraph_settings_videoheight']; + } + } + + $card = 'summary'; + if ( ! empty( $this->options['aiosp_opengraph_defcard'] ) ) { + $card = $this->options['aiosp_opengraph_defcard']; + } + + if ( ! empty( $metabox['aioseop_opengraph_settings_setcard'] ) ) { + $card = $metabox['aioseop_opengraph_settings_setcard']; + } + + // support for changing legacy twitter cardtype-photo to summary large image + if ( $card == 'photo' ) { + $card = 'summary_large_image'; + } + + $site = $domain = $creator = ''; + + if ( ! empty( $this->options['aiosp_opengraph_twitter_site'] ) ) { + $site = $this->options['aiosp_opengraph_twitter_site']; + $site = AIOSEOP_Opengraph_Public::prepare_twitter_username( $site ); + } + + if ( ! empty( $this->options['aiosp_opengraph_twitter_domain'] ) ) { + $domain = $this->options['aiosp_opengraph_twitter_domain']; + } + + if ( ! empty( $post ) && isset( $post->post_author ) && ! empty( $this->options['aiosp_opengraph_twitter_creator'] ) ) { + $creator = get_the_author_meta( 'twitter', $post->post_author ); + $creator = AIOSEOP_Opengraph_Public::prepare_twitter_username( $creator ); + } + + if ( ! empty( $thumbnail ) ) { + $twitter_thumbnail = $thumbnail; // Default Twitter image if custom isn't set. + } + + if ( isset( $metabox['aioseop_opengraph_settings_customimg_twitter'] ) && ! empty( $metabox['aioseop_opengraph_settings_customimg_twitter'] ) ) { + // Set Twitter image from custom. + $twitter_thumbnail = set_url_scheme( $metabox['aioseop_opengraph_settings_customimg_twitter'] ); + } + + // Apply last filters. + $description = apply_filters( 'aioseop_description', $description ); + + $meta = array( + 'facebook' => array( + 'title' => 'og:title', + 'type' => 'og:type', + 'url' => 'og:url', + 'thumbnail' => 'og:image', + 'width' => 'og:image:width', + 'height' => 'og:image:height', + 'video' => 'og:video', + 'videowidth' => 'og:video:width', + 'videoheight' => 'og:video:height', + 'sitename' => 'og:site_name', + 'key' => 'fb:admins', + 'appid' => 'fb:app_id', + 'description' => 'og:description', + 'section' => 'article:section', + 'tag' => 'article:tag', + 'publisher' => 'article:publisher', + 'author' => 'article:author', + 'published_time' => 'article:published_time', + 'modified_time' => 'article:modified_time', + ), + 'twitter' => array( + 'card' => 'twitter:card', + 'site' => 'twitter:site', + 'creator' => 'twitter:creator', + 'domain' => 'twitter:domain', + 'title' => 'twitter:title', + 'description' => 'twitter:description', + 'twitter_thumbnail' => 'twitter:image', + ), + ); + + // https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/1848 + if ( is_ssl() ) { + $meta['facebook'] += array( 'thumbnail_1' => 'og:image:secure_url' ); + $thumbnail_1 = $thumbnail; + } + + $tags = array( + 'facebook' => array( 'name' => 'property', 'value' => 'content' ), + 'twitter' => array( 'name' => 'name', 'value' => 'content' ), + ); + + foreach ( $meta as $t => $data ) { + foreach ( $data as $k => $v ) { + if ( empty( $$k ) ) { + $$k = ''; + } + $filtered_value = $$k; + + /** + * Process meta tags for their idiosyncracies. + * + * @since 3.0 + * + * @param string $filtered_value The value that is proposed to be shown in the tag. + * @param string $t The social network. + * @param string $k The meta tag without the network name prefixed. + * @param string $v The meta tag with the network name prefixed. This is not always $network:$meta_tag. + * @param array $extra_params Extra parameters that might be required to process the meta tag. + */ + $filtered_value = apply_filters( $this->prefix . 'meta', $filtered_value, $t, $k, $v, $extra_params ); + if ( ! empty( $filtered_value ) ) { + if ( ! is_array( $filtered_value ) ) { + $filtered_value = array( $filtered_value ); + } + + /** + * This is to accomodate multiple fb:admins on separate lines. + * @TODO Eventually we'll want to put this in its own function so things like images work too. + */ + if ( 'key' === $k ) { + $fbadmins = explode( ',', str_replace( ' ', '', $filtered_value[0] ) ); // Trim spaces then turn comma-separated values into an array. + foreach ( $fbadmins as $fbadmin ) { + echo '' . "\n"; + } + } else { + // For everything else. + foreach ( $filtered_value as $f ) { + // #1363: use esc_attr( $f ) instead of htmlspecialchars_decode( $f, ENT_QUOTES ) + echo '' . "\n"; + } + } + } + } + } + $social_link_schema = ''; + if ( ! empty( $social_links ) ) { + $home_url = esc_url( get_home_url() ); + $social_links = explode( "\n", $social_links ); + foreach ( $social_links as $k => $v ) { + $v = trim( $v ); + if ( empty( $v ) ) { + unset( $social_links[ $k ] ); + } else { + $v = esc_url( $v ); + $social_links[ $k ] = $v; + } + } + $social_links = join( '","', $social_links ); + $social_link_schema = << +{ "@context" : "https://schema.org", + "@type" : "{$social_type}", + "name" : "{$social_name}", + "url" : "{$home_url}", + "sameAs" : ["{$social_links}"] +} + + +END; + } + + // Only show if "use schema.org markup is checked". + if ( ! empty( $aioseop_options['aiosp_schema_markup'] ) ) { + echo apply_filters( 'aiosp_opengraph_social_link_schema', $social_link_schema ); + } + } + + /** + * Do / adds opengraph properties to meta. + * @since 2.3.11 + * + * @global array $aioseop_options AIOSEOP plugin options. + */ + public function do_opengraph() { + global $aioseop_options; + if ( ! empty( $aioseop_options ) + && ! empty( $aioseop_options['aiosp_schema_markup'] ) + ) { + add_filter( 'language_attributes', array( &$this, 'add_attributes' ) ); + } + if ( ! defined( 'DOING_AJAX' ) ) { + add_action( 'aioseop_modules_wp_head', array( &$this, 'add_meta' ), 5 ); + // Add social meta to AMP plugin. + if ( apply_filters( 'aioseop_enable_amp_social_meta', true ) === true ) { + add_action( 'amp_post_template_head', array( &$this, 'add_meta' ), 12 ); + } + } + } + + /** + * Set up types. + * + * @since ? + * @since 2.3.15 Change to website for homepage and blog post index page, default to object. + */ + function type_setup() { + $this->type = 'object'; // Default to type object if we don't have some other rule. + + if ( is_home() || is_front_page() ) { + $this->type = 'website'; // Home page and blog page should be website. + } elseif ( is_singular() && $this->option_isset( 'types' ) ) { + $metabox = $this->get_current_options( array(), 'settings' ); + $current_post_type = get_post_type(); + if ( ! empty( $metabox['aioseop_opengraph_settings_category'] ) ) { + $this->type = $metabox['aioseop_opengraph_settings_category']; + } elseif ( isset( $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ] ) ) { + $this->type = $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ]; + } + } + } + + /** + * Inits hooks and others for admin init. + * action:admin_init. + * + * @since 2.3.11 + * @since 2.4.14 Refactored function name, and new filter added for defaults and missing term metabox. + */ + function admin_init() { + add_filter( $this->prefix . 'display_settings', array( &$this, 'filter_settings' ), 10, 3 ); + add_filter( $this->prefix . 'override_options', array( &$this, 'override_options' ), 10, 3 ); + add_filter( + $this->get_prefix( 'settings' ) . 'default_options', array( + &$this, + 'filter_default_options', + ), 10, 2 + ); + add_filter( + $this->get_prefix( 'settings' ) . 'filter_metabox_options', array( + &$this, + 'filter_metabox_options', + ), 10, 3 + ); + add_filter( + $this->get_prefix( 'settings' ) . 'filter_term_metabox_options', array( + &$this, + 'filter_metabox_options', + ), 10, 3 + ); + $post_types = $this->get_post_type_titles(); + $rempost = array( + 'revision' => 1, + 'nav_menu_item' => 1, + 'custom_css' => 1, + 'customize_changeset' => 1, + ); + $post_types = array_diff_key( $post_types, $rempost ); + $this->default_options['types']['initial_options'] = $post_types; + foreach ( $post_types as $slug => $name ) { + $field = $slug . '_fb_object_type'; + $this->default_options[ $field ] = array( + 'name' => "$name " . __( 'Object Type', 'all-in-one-seo-pack' ) . "
                      ($slug)", + 'type' => 'select', + 'style' => '', + 'initial_options' => $this->fb_object_types, + 'default' => 'article', + 'condshow' => array( 'aiosp_opengraph_types\[\]' => $slug ), + ); + $this->locations['opengraph']['options'][] = $field; + $this->layout['facebook']['options'][] = $field; + } + $this->setting_options(); + } + + function get_all_images( $options = null, $p = null ) { + static $img = array(); + if ( ! is_array( $options ) ) { + $options = array(); + } + if ( ! empty( $this->options['aiosp_opengraph_meta_key'] ) ) { + $options['meta_key'] = $this->options['aiosp_opengraph_meta_key']; + } + if ( empty( $img ) ) { + $size = apply_filters( 'post_thumbnail_size', 'large' ); + $default = $this->get_the_image_by_default(); + if ( ! empty( $default ) ) { + $default = set_url_scheme( $default ); + $img[ $default ] = 0; + } + $img = array_merge( $img, parent::get_all_images( $options, null ) ); + } + + if ( ! empty( $options ) && ! empty( $options['aioseop_opengraph_settings_customimg'] ) ) { + $img[ $options['aioseop_opengraph_settings_customimg'] ] = 'customimg'; + } + + if ( ! empty( $options ) && ! empty( $options['aioseop_opengraph_settings_customimg'] ) ) { + $img[ $options['aioseop_opengraph_settings_customimg'] ] = 'customimg'; + $img[ $options['aioseop_opengraph_settings_customimg_twitter'] ] = 'customimg_twitter'; + } + + if ( $author_img = $this->get_the_image_by_author( $p ) ) { + $image['author'] = $author_img; + } + $image = array_flip( $img ); + $images = array(); + if ( ! empty( $image ) ) { + foreach ( $image as $k => $v ) { + $images[ $v ] = ''; + } + } + + return array( $image, $images ); + } + + function get_the_image_by_author( $options = null, $p = null ) { + if ( $p === null ) { + global $post; + } else { + $post = $p; + } + if ( ! empty( $post ) && ! empty( $post->post_author ) ) { + $matches = array(); + $get_avatar = get_avatar( $post->post_author, 300 ); + if ( preg_match( "/src='(.*?)'/i", $get_avatar, $matches ) ) { + return $matches[1]; + } + } + + return false; + } + + function get_the_image( $options = null, $p = null ) { + $meta_key = $this->options['aiosp_opengraph_meta_key']; + + return parent::get_the_image( array( 'meta_key' => $meta_key ), $p ); + } + + function get_the_image_by_default( $args = array() ) { + return $this->options['aiosp_opengraph_dimg']; + } + + function settings_update() { + + } + + /** + * Admin Enqueue Scripts + * + * Add hook in \All_in_One_SEO_Pack_Module::enqueue_metabox_scripts - Bails adding hook if not on target valid screen. + * Add hook in \All_in_One_SEO_Pack_Module::add_page_hooks - Function itself is hooked based on the screen_id/page. + * + * @since 2.9.2 + * + * @see 'admin_enqueue_scripts' hook + * @link https://developer.wordpress.org/reference/hooks/admin_enqueue_scripts/ + * + * @param string $hook_suffix + */ + public function admin_enqueue_scripts( $hook_suffix ) { + wp_enqueue_script( + 'aioseop-opengraph-script', + AIOSEOP_PLUGIN_URL . 'js/modules/aioseop_opengraph.js', + array(), + AIOSEOP_VERSION + ); + + wp_enqueue_script( + 'aioseop-post-edit-script', + AIOSEOP_PLUGIN_URL . 'js/count-chars.js', + array(), + AIOSEOP_VERSION + ); + + $localize_post_edit = array( + 'aiosp_title_extra' => 0, + ); + wp_localize_script( 'aioseop-post-edit-script', 'aioseop_count_chars', $localize_post_edit ); + + // Dev note: If certain JS files need to be restricted to select screens, then follow concept + // used in `All_in_One_SEO_Pack::admin_enqueue_scripts()` (v2.9.1); which uses the `$hook_suffix` + // and a switch-case. This also helps prevent unnessecarily processing localized data when it isn't needed. + parent::admin_enqueue_scripts( $hook_suffix ); + } + + /** + * Enqueue our file upload scripts and styles. + * @param $hook + */ + function og_admin_enqueue_scripts( $hook ) { + + if ( 'all-in-one-seo_page_aiosp_opengraph' != $hook && 'term.php' != $hook ) { + // Only enqueue if we're on the social module settings page. + return; + } + + wp_enqueue_script( 'media-upload' ); + wp_enqueue_script( 'thickbox' ); + wp_enqueue_style( 'thickbox' ); + wp_enqueue_media(); + } + + function save_tax_data( $term_id, $tt_id, $taxonomy ) { + static $update = false; + if ( $update ) { + return; + } + if ( $this->locations !== null ) { + foreach ( $this->locations as $k => $v ) { + if ( isset( $v['type'] ) && ( $v['type'] === 'metabox' ) ) { + $opts = $this->default_options( $k ); + $options = array(); + $update = false; + foreach ( $opts as $l => $o ) { + if ( isset( $_POST[ $l ] ) ) { + $options[ $l ] = stripslashes_deep( $_POST[ $l ] ); + $options[ $l ] = esc_attr( $options[ $l ] ); + $update = true; + } + } + if ( $update ) { + $prefix = $this->get_prefix( $k ); + $options = apply_filters( $prefix . 'filter_term_metabox_options', $options, $k, $term_id ); + update_term_meta( $term_id, '_' . $prefix . $k, $options ); + } + } + } + } + } + + /** + * Returns the placeholder filtered and ready for DOM display. + * filter:aioseop_opengraph_placeholder + * @since 2.4.14 + * + * @param mixed $placeholder Placeholder to be filtered. + * @param string $type Type of the value to be filtered. + * + * @return string + */ + public function filter_placeholder( $placeholder, $type = 'text' ) { + return strip_tags( trim( $placeholder ) ); + } + + /** + * Returns filtered default options. + * filter:{prefix}default_options + * @since 2.4.13 + * + * @param array $options Default options. + * @param string $location Location. + * + * @return array + */ + public function filter_default_options( $options, $location ) { + if ( $location === 'settings' ) { + $prefix = $this->get_prefix( $location ) . $location . '_'; + // Add image checker as default + $options[ $prefix . 'customimg_checker' ] = 0; + } + return $options; + } + } +} diff --git a/modules/aioseop_sitemap.php b/modules/aioseop_sitemap.php index c69f0fd6b..050c70132 100644 --- a/modules/aioseop_sitemap.php +++ b/modules/aioseop_sitemap.php @@ -3772,7 +3772,7 @@ private function get_content_from_galleries( $content ) { } $code .= ']'; - $gallery_content .= do_shortcode( $code ); + $gallery_content .= aioseop_do_shortcodes( $code ); } } diff --git a/tests/modules/general/test-shortcodes-in-description.php b/tests/modules/general/test-shortcodes-in-description.php new file mode 100644 index 000000000..7ae946c1f --- /dev/null +++ b/tests/modules/general/test-shortcodes-in-description.php @@ -0,0 +1,72 @@ + 'post', + 'post_title' => 'Example Title', + 'post_content' => $shortcode . $expected_description, + ); + $id = $this->factory->post->create( $args ); + + $link = get_permalink( $id ); + $meta_tags = $this->parse_html( $link, array ('meta') ); + $description = preg_replace( '(\[(.*?)\])', '', $meta_tags[0]['content'] ); + + $this->assertEquals( $description, $expected_description ); + } + + /** + * Conflicting shortcode provider. + * + * Provides conflicting shortcodes to test_conflicting_shortcodes(). + * This function should contain all conflicting shortcodes found in aioseop_contains_conflicting_shortcodes(). + * + * @since 3.0 + */ + public function conflictingShortcodeProvider() { + return [ + 'WooCommerce My Account' => ['[woocommerce_my_account]'], + ]; + } +} diff --git a/tests/modules/sitemap/test-sitemap.php b/tests/modules/sitemap/test-sitemap.php index f524e0202..7e3b98a6c 100644 --- a/tests/modules/sitemap/test-sitemap.php +++ b/tests/modules/sitemap/test-sitemap.php @@ -550,7 +550,7 @@ public function test_nextgen_gallery() { $nggdb->add_image( $gallery_id, 'x.png', 'x', 'x', 'eyJiYWNrdXAiOnsiZmlsZW5hbWUiOiJzYW1wbGUucG5nIiwid2lkdGgiOjI0OCwiaGVpZ2h0Ijo5OCwiZ2VuZXJhdGVkIjoiMC4wMjM3MzMwMCAxNTA3MDk1MTcwIn0sImFwZXJ0dXJlIjpmYWxzZSwiY3JlZGl0IjpmYWxzZSwiY2FtZXJhIjpmYWxzZSwiY2FwdGlvbiI6ZmFsc2UsImNyZWF0ZWRfdGltZXN0YW1wIjpmYWxzZSwiY29weXJpZ2h0IjpmYWxzZSwiZm9jYWxfbGVuZ3RoIjpmYWxzZSwiaXNvIjpmYWxzZSwic2h1dHRlcl9zcGVlZCI6ZmFsc2UsImZsYXNoIjpmYWxzZSwidGl0bGUiOmZhbHNlLCJrZXl3b3JkcyI6ZmFsc2UsIndpZHRoIjoyNDgsImhlaWdodCI6OTgsInNhdmVkIjp0cnVlLCJtZDUiOiI3ZWUyMjVjOTNkZmNhMTMyYjQzMTc5ZjJiMGYwZTc2NiIsImZ1bGwiOnsid2lkdGgiOjI0OCwiaGVpZ2h0Ijo5OCwibWQ1IjoiN2VlMjI1YzkzZGZjYTEzMmI0MzE3OWYyYjBmMGU3NjYifSwidGh1bWJuYWlsIjp7IndpZHRoIjoyNDAsImhlaWdodCI6OTgsImZpbGVuYW1lIjoidGh1bWJzX3NhbXBsZS5wbmciLCJnZW5lcmF0ZWQiOiIwLjMwNDUzNDAwIDE1MDcwOTUxNzAifSwibmdnMGR5bi0weDB4MTAwLTAwZjB3MDEwYzAxMHIxMTBmMTEwcjAxMHQwMTAiOnsid2lkdGgiOjI0OCwiaGVpZ2h0Ijo5OCwiZmlsZW5hbWUiOiJzYW1wbGUucG5nLW5nZ2lkMDE3LW5nZzBkeW4tMHgweDEwMC0wMGYwdzAxMGMwMTByMTEwZjExMHIwMTB0MDEwLnBuZyIsImdlbmVyYXRlZCI6IjAuMTgwMzI0MDAgMTUyMTAxMTI1NCJ9fQ==' ), ); $shortcode = '[ngg_images display_type="photocrati-nextgen_basic_thumbnails" image_ids="' . implode( ',', $images ) . '"]'; - $content = do_shortcode( $shortcode ); + $content = aioseop_do_shortcodes( $shortcode ); if ( 'We cannot display this gallery' === $content ) { $this->markTestSkipped( 'NextGen Gallery not working properly. Skipping.' ); } From cd9bd011f8a72139af43272978ca08d34ce32223 Mon Sep 17 00:00:00 2001 From: Michael Torbert Date: Thu, 30 May 2019 18:49:10 -0400 Subject: [PATCH 119/121] update changelog URL --- readme.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.txt b/readme.txt index 846825a64..b99626c8d 100644 --- a/readme.txt +++ b/readme.txt @@ -49,7 +49,7 @@ https://www.youtube.com/watch?v=46MR4FboMaA == Changelog == -All in One SEO Pack [Changelog](https://semperfiwebdesign.com/all-in-one-seo-pack-release-history/) +All in One SEO Pack [Changelog](https://semperplugins.com/all-in-one-seo-pack-changelog/) == Frequently Asked Questions == From 07af222fbe28dcda6bdc5ffe70e7e677bb0e0600 Mon Sep 17 00:00:00 2001 From: Michael Torbert Date: Thu, 30 May 2019 18:49:25 -0400 Subject: [PATCH 120/121] bump to 3.0 --- readme.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.txt b/readme.txt index b99626c8d..8077b4bf4 100644 --- a/readme.txt +++ b/readme.txt @@ -3,7 +3,7 @@ Contributors: hallsofmontezuma, semperplugins, wpsmort, arnaudbroes Tags: SEO, Google Search Console, XML Sitemap, meta description, meta title, noindex Requires at least: 4.7 Tested up to: 5.2 -Stable tag: 3.0-dev +Stable tag: 3.0 License: GPLv2 or later Requires PHP: 5.2.4 From 260a977e80df6776246607dbc8561a83d790ac8a Mon Sep 17 00:00:00 2001 From: Michael Torbert Date: Thu, 30 May 2019 18:49:48 -0400 Subject: [PATCH 121/121] bump to 3.0 --- all_in_one_seo_pack.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/all_in_one_seo_pack.php b/all_in_one_seo_pack.php index 8038743eb..4936af838 100644 --- a/all_in_one_seo_pack.php +++ b/all_in_one_seo_pack.php @@ -4,7 +4,7 @@ Plugin Name: All In One SEO Pack Plugin URI: https://semperplugins.com/all-in-one-seo-pack-pro-version/ Description: Out-of-the-box SEO for WordPress. Features like XML Sitemaps, SEO for custom post types, SEO for blogs or business sites, SEO for ecommerce sites, and much more. More than 50 million downloads since 2007. -Version: 3.0-dev +Version: 3.0 Author: Michael Torbert Author URI: https://semperplugins.com/all-in-one-seo-pack-pro-version/ Text Domain: all-in-one-seo-pack @@ -32,7 +32,7 @@ * The original WordPress SEO plugin. * * @package All-in-One-SEO-Pack - * @version 3.0-dev + * @version 3.0 */ if ( ! defined( 'AIOSEOPPRO' ) ) { @@ -42,7 +42,7 @@ define( 'AIOSEOP_PLUGIN_NAME', 'All in One SEO Pack' ); } if ( ! defined( 'AIOSEOP_VERSION' ) ) { - define( 'AIOSEOP_VERSION', '3.0-dev' ); + define( 'AIOSEOP_VERSION', '3.0' ); } /*