All in One SEO Pack - Version 2.8

Version Description

Download this release

Release Info

Developer hallsofmontezuma
Plugin Icon 128x128 All in One SEO Pack
Version 2.8
Comparing to
See all releases

Code changes from version 2.7.3 to 2.8

admin/aioseop_module_class.php CHANGED
@@ -2507,6 +2507,8 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Module' ) ) {
2507
  case 'filename':
2508
  $this->options[ $k ] = sanitize_file_name( $this->options[ $k ] );
2509
  break;
 
 
2510
  case 'text':
2511
  $this->options[ $k ] = wp_kses_post( $this->options[ $k ] );
2512
  // fall through.
2507
  case 'filename':
2508
  $this->options[ $k ] = sanitize_file_name( $this->options[ $k ] );
2509
  break;
2510
+ case 'url':
2511
+ // fall through.
2512
  case 'text':
2513
  $this->options[ $k ] = wp_kses_post( $this->options[ $k ] );
2514
  // fall through.
admin/display/credits-content.php CHANGED
@@ -62,6 +62,38 @@
62
  <a class="web" target="_blank" href="https://profiles.wordpress.org/yummy-wp/"><img alt="" class="gravatar" src="https://avatars0.githubusercontent.com/u/22232968?v=3&s=460">
63
  Stanislav Samoilenko</a>
64
  </li>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  </ul>
66
 
67
  <h3 class="wp-people-group dashicons-before dashicons-translation"><?php printf( _e( 'Translation contributors and translation editors', 'all-in-one-seo-pack' ), '1.2' ); ?></h3>
62
  <a class="web" target="_blank" href="https://profiles.wordpress.org/yummy-wp/"><img alt="" class="gravatar" src="https://avatars0.githubusercontent.com/u/22232968?v=3&s=460">
63
  Stanislav Samoilenko</a>
64
  </li>
65
+ <li class="wp-person" id="EkoJR">
66
+ <a class="web" target="_blank" href="https://profiles.wordpress.org/EkoJR/"><img alt="" class="gravatar" src="https://secure.gravatar.com/avatar/bb4c78fe944b58bd5f127d836500c30a?s=200&d=mm&r=g">
67
+ Stanislav Samoilenko</a>
68
+ </li>
69
+ <li class="wp-person" id="webaware">
70
+ <a class="web" target="_blank" href="https://profiles.wordpress.org/webaware/"><img alt="" class="gravatar" src="https://secure.gravatar.com/avatar/aee800bc3644d9ebfa33c1ed9df5d958?s=200&d=mm&r=g">
71
+ Ross McKay</a>
72
+ </li>
73
+ <li class="wp-person" id="adamsilverstein">
74
+ <a class="web" target="_blank" href="https://profiles.wordpress.org/adamsilverstein/"><img alt=""
75
+ class="gravatar"
76
+ src="https://secure.gravatar.com/avatar/fddbd6c3e1c3d971aa732b9346aeb433?s=200&d=mm&r=g">
77
+ Adam Silverstein</a>
78
+ </li>
79
+ <li class="wp-person" id="vschettino">
80
+ <a class="web" target="_blank" href="https://github.com/vschettino/"><img alt=""
81
+ class="gravatar"
82
+ src="https://avatars2.githubusercontent.com/u/7289698?s=460&v=4">
83
+ Vinicius Schettino</a>
84
+ </li>
85
+ <li class="wp-person" id="vschettino">
86
+ <a class="web" target="_blank" href="https://github.com/srdjan-jcc"><img alt=""
87
+ class="gravatar"
88
+ src="https://avatars2.githubusercontent.com/u/3109112?s=460&v=4">
89
+ Srdjan Jocic</a>
90
+ </li>
91
+ <li class="wp-person" id="vschettino">
92
+ <a class="web" target="_blank" href="https://profiles.wordpress.org/soulseekah/"><img alt=""
93
+ class="gravatar"
94
+ src="https://avatars0.githubusercontent.com/u/685880?s=460&v=4">
95
+ Gennady Kovshenin</a>
96
+ </li>
97
  </ul>
98
 
99
  <h3 class="wp-people-group dashicons-before dashicons-translation"><?php printf( _e( 'Translation contributors and translation editors', 'all-in-one-seo-pack' ), '1.2' ); ?></h3>
admin/display/dashboard_widget.php CHANGED
@@ -15,21 +15,18 @@ if ( ! class_exists( 'aioseop_dashboard_widget' ) ) {
15
  * Add the action to the constructor.
16
  */
17
  function __construct() {
18
- add_action( 'wp_dashboard_setup', array( $this, 'aioseop_add_dashboard_widget' ) );
19
  }
20
 
21
  /**
22
  * @since 2.3.10
23
  */
24
- function aioseop_add_dashboard_widget() {
25
-
26
  if ( current_user_can( 'install_plugins' ) && false !== $this->show_widget() ) {
27
- wp_add_dashboard_widget(
28
- 'semperplugins-rss-feed', __( 'SEO News', 'all-in-one-seo-pack' ), array(
29
- $this,
30
- 'aioseop_display_rss_dashboard_widget',
31
- )
32
- );
33
  }
34
 
35
  }
@@ -58,7 +55,13 @@ if ( ! class_exists( 'aioseop_dashboard_widget' ) ) {
58
  /**
59
  * @since 2.3.10
60
  */
61
- function aioseop_display_rss_dashboard_widget() {
 
 
 
 
 
 
62
 
63
  include_once( ABSPATH . WPINC . '/feed.php' );
64
 
15
  * Add the action to the constructor.
16
  */
17
  function __construct() {
18
+ add_action( 'wp_dashboard_setup', array( $this, 'add_dashboard_widget' ) );
19
  }
20
 
21
  /**
22
  * @since 2.3.10
23
  */
24
+ function add_dashboard_widget() {
 
25
  if ( current_user_can( 'install_plugins' ) && false !== $this->show_widget() ) {
26
+ wp_add_dashboard_widget( 'semperplugins-rss-feed', __( 'SEO News', 'all-in-one-seo-pack' ), array(
27
+ $this,
28
+ 'display_rss_dashboard_widget',
29
+ ) );
 
 
30
  }
31
 
32
  }
55
  /**
56
  * @since 2.3.10
57
  */
58
+ function display_rss_dashboard_widget() {
59
+ // check if the user has chosen not to display this widget through screen options.
60
+ $current_screen = get_current_screen();
61
+ $hidden_widgets = get_user_meta( get_current_user_id(), 'metaboxhidden_' . $current_screen->id );
62
+ if ( $hidden_widgets && count( $hidden_widgets ) > 0 && is_array( $hidden_widgets[0] ) && in_array( 'semperplugins-rss-feed', $hidden_widgets[0], true ) ) {
63
+ return;
64
+ }
65
 
66
  include_once( ABSPATH . WPINC . '/feed.php' );
67
 
admin/display/welcome-content.php CHANGED
@@ -1,16 +1,16 @@
1
- <div id="welcome-panel" class="">
2
  <div class="welcome-panel-content">
3
  <div class="welcome-panel-column-container">
4
  <div class="welcome-panel-column">
5
  <h3><?php echo esc_html( __( 'Support All in One SEO Pack', 'all-in-one-seo-pack' ) ); ?></h3>
6
- <p class="message"><?php echo esc_html( __( 'There are many ways you can help support All in One SEO Pack.', 'all-in-one-seo-pack' ) ); ?></p>
7
- <p class="message aioseop-message"><?php echo esc_html( __( 'Upgrade to All in One SEO Pack Pro to access priority support and premium features.', 'all-in-one-seo-pack' ) ); ?></p>
8
  <p class="call-to-action"><a
9
  href="https://semperplugins.com/all-in-one-seo-pack-pro-version/?loc=aio_welcome"
10
  target="_blank"
11
  class="button button-primary button-orange"><?php echo __( 'Upgrade', 'all-in-one-seo-pack' ); ?></a>
12
  </p>
13
- <p class="message aioseop-message"><?php echo esc_html( __( 'Help translate All in One SEO Pack into your language.', 'all-in-one-seo-pack' ) ); ?></p>
14
  <p class="call-to-action"><a
15
  href="https://translate.wordpress.org/projects/wp-plugins/all-in-one-seo-pack"
16
  class="button button-primary"
@@ -21,26 +21,34 @@
21
  <h3><?php echo esc_html( __( 'Get Started', 'all-in-one-seo-pack' ) ); ?></h3>
22
  <ul>
23
  <li><a href="https://semperplugins.com/documentation/quick-start-guide/"
24
- target="_blank"><?php echo __( 'Beginners Guide for All in One SEO Pack', 'all-in-one-seo-pack' ); ?></a>
 
 
25
  </li>
26
  <li><a href="https://semperplugins.com/documentation/beginners-guide-to-xml-sitemaps/"
27
- target="_blank"><?php echo __( 'Beginners Guide for XML Sitemap module', 'all-in-one-seo-pack' ); ?></a>
 
28
  </li>
29
  <li><a href="https://semperplugins.com/documentation/beginners-guide-to-social-meta/"
30
- target="_blank"><?php echo __( 'Beginners Guide for Social Meta module', 'all-in-one-seo-pack' ); ?></a>
 
31
  </li>
32
  <li><a href="https://semperplugins.com/documentation/top-tips-for-good-on-page-seo/"
33
- target="_blank"><?php echo __( 'Tips for good on-page SEO', 'all-in-one-seo-pack' ); ?></a>
 
34
  </li>
35
  <li>
36
  <a href="https://semperplugins.com/documentation/quality-guidelines-for-seo-titles-and-descriptions/"
37
- target="_blank"><?php echo __( 'Quality guidelines for SEO titles and descriptions', 'all-in-one-seo-pack' ); ?></a>
 
38
  </li>
39
  <li><a href="https://semperplugins.com/documentation/submitting-an-xml-sitemap-to-google/"
40
- target="_blank"><?php echo __( 'Submit an XML Sitemap to Google', 'all-in-one-seo-pack' ); ?></a>
 
41
  </li>
42
  <li><a href="https://semperplugins.com/documentation/setting-up-google-analytics/"
43
- target="_blank"><?php echo __( 'Set up Google Analytics', 'all-in-one-seo-pack' ); ?></a>
 
44
  </li>
45
  </ul>
46
  </div>
@@ -49,13 +57,17 @@
49
  <h3><?php echo esc_html( __( 'Did You Know?', 'all-in-one-seo-pack' ) ); ?></h3>
50
  <ul>
51
  <li><a href="https://semperplugins.com/documentation/"
52
- target="_blank"><?php echo __( 'We have complete documentation on every setting and feature', 'all-in-one-seo-pack' ); ?></a>
 
 
53
  </li>
54
  <li><a href="https://semperplugins.com/videos/"
55
- target="_blank"><?php echo __( 'Access to video tutorials about SEO with the Pro version', 'all-in-one-seo-pack' ); ?></a>
 
56
  </li>
57
  <li><a href="https://semperplugins.com/all-in-one-seo-pack-pro-version/?loc=aio_welcome"
58
- target="_blank"><?php echo __( 'Control SEO on categories, tags and custom taxonomies with the Pro version', 'all-in-one-seo-pack' ); ?></a>
 
59
  </li>
60
  </ul>
61
  </div>
1
+ <div class="welcome-panel">
2
  <div class="welcome-panel-content">
3
  <div class="welcome-panel-column-container">
4
  <div class="welcome-panel-column">
5
  <h3><?php echo esc_html( __( 'Support All in One SEO Pack', 'all-in-one-seo-pack' ) ); ?></h3>
6
+ <p class="message welcome-icon welcome-edit-page"><?php echo esc_html( __( 'There are many ways you can help support All in One SEO Pack.', 'all-in-one-seo-pack' ) ); ?></p>
7
+ <p class="message aioseop-message welcome-icon welcome-edit-page"><?php echo esc_html( __( 'Upgrade to All in One SEO Pack Pro to access priority support and premium features.', 'all-in-one-seo-pack' ) ); ?></p>
8
  <p class="call-to-action"><a
9
  href="https://semperplugins.com/all-in-one-seo-pack-pro-version/?loc=aio_welcome"
10
  target="_blank"
11
  class="button button-primary button-orange"><?php echo __( 'Upgrade', 'all-in-one-seo-pack' ); ?></a>
12
  </p>
13
+ <p class="message aioseop-message welcome-icon welcome-edit-page"><?php echo esc_html( __( 'Help translate All in One SEO Pack into your language.', 'all-in-one-seo-pack' ) ); ?></p>
14
  <p class="call-to-action"><a
15
  href="https://translate.wordpress.org/projects/wp-plugins/all-in-one-seo-pack"
16
  class="button button-primary"
21
  <h3><?php echo esc_html( __( 'Get Started', 'all-in-one-seo-pack' ) ); ?></h3>
22
  <ul>
23
  <li><a href="https://semperplugins.com/documentation/quick-start-guide/"
24
+ target="_blank"
25
+ class="welcome-icon welcome-add-page"><?php echo __( 'Beginners Guide for All in One SEO Pack', 'all-in-one-seo-pack' ); ?></a>
26
+
27
  </li>
28
  <li><a href="https://semperplugins.com/documentation/beginners-guide-to-xml-sitemaps/"
29
+ target="_blank"
30
+ class="welcome-icon welcome-add-page"><?php echo __( 'Beginners Guide for XML Sitemap module', 'all-in-one-seo-pack' ); ?></a>
31
  </li>
32
  <li><a href="https://semperplugins.com/documentation/beginners-guide-to-social-meta/"
33
+ target="_blank"
34
+ class="welcome-icon welcome-add-page"><?php echo __( 'Beginners Guide for Social Meta module', 'all-in-one-seo-pack' ); ?></a>
35
  </li>
36
  <li><a href="https://semperplugins.com/documentation/top-tips-for-good-on-page-seo/"
37
+ target="_blank"
38
+ class="welcome-icon welcome-add-page"><?php echo __( 'Tips for good on-page SEO', 'all-in-one-seo-pack' ); ?></a>
39
  </li>
40
  <li>
41
  <a href="https://semperplugins.com/documentation/quality-guidelines-for-seo-titles-and-descriptions/"
42
+ target="_blank"
43
+ class="welcome-icon welcome-add-page"><?php echo __( 'Quality guidelines for SEO titles and descriptions', 'all-in-one-seo-pack' ); ?></a>
44
  </li>
45
  <li><a href="https://semperplugins.com/documentation/submitting-an-xml-sitemap-to-google/"
46
+ target="_blank"
47
+ class="welcome-icon welcome-add-page"><?php echo __( 'Submit an XML Sitemap to Google', 'all-in-one-seo-pack' ); ?></a>
48
  </li>
49
  <li><a href="https://semperplugins.com/documentation/setting-up-google-analytics/"
50
+ target="_blank"
51
+ class="welcome-icon welcome-add-page"><?php echo __( 'Set up Google Analytics', 'all-in-one-seo-pack' ); ?></a>
52
  </li>
53
  </ul>
54
  </div>
57
  <h3><?php echo esc_html( __( 'Did You Know?', 'all-in-one-seo-pack' ) ); ?></h3>
58
  <ul>
59
  <li><a href="https://semperplugins.com/documentation/"
60
+ target="_blank"
61
+ class="welcome-icon welcome-learn-more"><?php echo __( 'We have complete documentation on every setting and feature', 'all-in-one-seo-pack' ); ?></a>
62
+
63
  </li>
64
  <li><a href="https://semperplugins.com/videos/"
65
+ target="_blank"
66
+ class="welcome-icon welcome-learn-more"><?php echo __( 'Access to video tutorials about SEO with the Pro version', 'all-in-one-seo-pack' ); ?></a>
67
  </li>
68
  <li><a href="https://semperplugins.com/all-in-one-seo-pack-pro-version/?loc=aio_welcome"
69
+ target="_blank"
70
+ class="welcome-icon welcome-learn-more"><?php echo __( 'Control SEO on categories, tags and custom taxonomies with the Pro version', 'all-in-one-seo-pack' ); ?></a>
71
  </li>
72
  </ul>
73
  </div>
admin/display/welcome.php CHANGED
@@ -32,8 +32,8 @@ if ( ! class_exists( 'aioseop_welcome' ) ) {
32
 
33
  if ( 'dashboard_page_aioseop-about' === $hook ) {
34
 
35
- wp_enqueue_style( 'aioseop_welcome_css', AIOSEOP_PLUGIN_URL . '/css/welcome.css', array(), AIOSEOP_VERSION );
36
- wp_enqueue_script( 'aioseop_welcome_js', AIOSEOP_PLUGIN_URL . '/js/welcome.js', array( 'jquery' ), AIOSEOP_VERSION, true );
37
  }
38
  }
39
 
32
 
33
  if ( 'dashboard_page_aioseop-about' === $hook ) {
34
 
35
+ wp_enqueue_style( 'aioseop_welcome_css', AIOSEOP_PLUGIN_URL . 'css/welcome.css', array(), AIOSEOP_VERSION );
36
+ wp_enqueue_script( 'aioseop_welcome_js', AIOSEOP_PLUGIN_URL . 'js/welcome.js', array( 'jquery' ), AIOSEOP_VERSION, true );
37
  }
38
  }
39
 
aioseop_class.php CHANGED
@@ -1453,7 +1453,7 @@ class All_in_One_SEO_Pack extends All_in_One_SEO_Pack_Module {
1453
  function get_queried_object() {
1454
  static $p = null;
1455
  global $wp_query, $post;
1456
- if ( null !== $p ) {
1457
  return $p;
1458
  }
1459
  if ( is_object( $post ) ) {
@@ -1589,11 +1589,13 @@ class All_in_One_SEO_Pack extends All_in_One_SEO_Pack_Module {
1589
  /**
1590
  * Gets the title that will be used by AIOSEOP for title rewrites or returns false.
1591
  *
1592
- * @param $post
 
 
1593
  *
1594
  * @return bool|string
1595
  */
1596
- function get_aioseop_title( $post ) {
1597
  global $aioseop_options;
1598
  // the_search_query() is not suitable, it cannot just return.
1599
  global $s, $STagging;
@@ -1739,14 +1741,14 @@ class All_in_One_SEO_Pack extends All_in_One_SEO_Pack_Module {
1739
  $title = $this->internationalize( get_post_meta( $post->ID, '_aioseop_title', true ) );
1740
  if ( ! $title ) {
1741
  $title = $this->internationalize( get_post_meta( $post->ID, 'title_tag', true ) );
1742
- if ( ! $title ) {
1743
  $title = $this->internationalize( $this->get_original_title( '', false ) );
1744
  }
1745
  }
1746
  if ( empty( $title ) ) {
1747
  $title = $post->post_title;
1748
  }
1749
- if ( ! empty( $title ) ) {
1750
  $title = $this->apply_post_title_format( $title, $category, $post );
1751
  }
1752
  $title = $this->paged_title( $title );
@@ -2488,6 +2490,10 @@ class All_in_One_SEO_Pack extends All_in_One_SEO_Pack_Module {
2488
  $description = $this->internationalize( $description );
2489
  }
2490
 
 
 
 
 
2491
  $truncate = false;
2492
  $aioseop_desc = '';
2493
  if ( ! empty( $post->ID ) ) {
@@ -2501,7 +2507,8 @@ class All_in_One_SEO_Pack extends All_in_One_SEO_Pack_Module {
2501
  $description = apply_filters(
2502
  'aioseop_description',
2503
  $description,
2504
- $truncate
 
2505
  );
2506
 
2507
  return $description;
@@ -3003,8 +3010,8 @@ class All_in_One_SEO_Pack extends All_in_One_SEO_Pack_Module {
3003
  function add_page_icon() {
3004
  wp_enqueue_script( 'wp-pointer', false, array( 'jquery' ) );
3005
  wp_enqueue_style( 'wp-pointer' );
3006
- // $this->add_admin_pointers();
3007
- wp_enqueue_style( 'aiosp_admin_style', AIOSEOP_PLUGIN_URL . 'css/aiosp_admin.css', array(), AIOSEOP_VERSION );
3008
  ?>
3009
  <script>
3010
  function aioseop_show_pointer(handle, value) {
@@ -3271,6 +3278,18 @@ class All_in_One_SEO_Pack extends All_in_One_SEO_Pack_Module {
3271
  add_filter( "{$this->prefix}submit_options", array( $this, 'filter_submit' ) );
3272
  }
3273
 
 
 
 
 
 
 
 
 
 
 
 
 
3274
  function enqueue_scripts() {
3275
  add_filter( "{$this->prefix}display_settings", array( $this, 'filter_settings' ), 10, 3 );
3276
  add_filter( "{$this->prefix}display_options", array( $this, 'filter_options' ), 10, 2 );
@@ -3657,6 +3676,7 @@ class All_in_One_SEO_Pack extends All_in_One_SEO_Pack_Module {
3657
  add_action( 'admin_menu', array( $this, 'admin_menu' ) );
3658
 
3659
  add_action( 'admin_head', array( $this, 'add_page_icon' ) );
 
3660
  add_action( 'admin_init', 'aioseop_addmycolumns', 1 );
3661
  add_action( 'admin_init', 'aioseop_handle_ignore_notice' );
3662
  if ( AIOSEOPPRO ) {
@@ -3682,7 +3702,7 @@ class All_in_One_SEO_Pack extends All_in_One_SEO_Pack_Module {
3682
  add_action( 'amp_post_template_head', array( $this, 'amp_head' ), 11 );
3683
  add_action( 'template_redirect', array( $this, 'template_redirect' ), 0 );
3684
  }
3685
- add_filter( 'aioseop_description', array( &$this, 'filter_description' ), 10, 2 );
3686
  add_filter( 'aioseop_title', array( &$this, 'filter_title' ) );
3687
  }
3688
 
@@ -3817,9 +3837,8 @@ class All_in_One_SEO_Pack extends All_in_One_SEO_Pack_Module {
3817
  global $aioseop_update_checker, $wp_query, $aioseop_options, $posts;
3818
  static $aioseop_dup_counter = 0;
3819
  $aioseop_dup_counter ++;
3820
-
3821
- if ( ! defined('AIOSEOP_UNIT_TESTING') && $aioseop_dup_counter > 1 ) {
3822
- echo "\n<!-- " . sprintf( __( 'Debug Warning: All in One SEO Pack meta data was included again from %s filter. Called %s times!', 'all-in-one-seo-pack' ), current_filter(), $aioseop_dup_counter ) . " -->\n";
3823
  if ( ! empty( $old_wp_query ) ) {
3824
  // Change the query back after we've finished.
3825
  $GLOBALS['wp_query'] = $old_wp_query;
@@ -3863,9 +3882,10 @@ class All_in_One_SEO_Pack extends All_in_One_SEO_Pack_Module {
3863
  }
3864
 
3865
  $posts = $save_posts;
3866
- $description = $this->get_main_description( $post ); // Get the description.
3867
  // Handle the description format.
3868
- if ( isset( $description ) && ( $this->strlen( $description ) > $this->minimum_description_length ) && ! ( is_front_page() && is_paged() ) ) {
 
 
3869
  $description = $this->trim_description( $description );
3870
  if ( ! isset( $meta_string ) ) {
3871
  $meta_string = '';
@@ -3877,7 +3897,9 @@ class All_in_One_SEO_Pack extends All_in_One_SEO_Pack_Module {
3877
  $desc_attr = '';
3878
  }
3879
  $desc_attr = apply_filters( 'aioseop_description_attributes', $desc_attr );
3880
- $meta_string .= sprintf( "<meta name=\"description\" %s content=\"%s\" />\n", $desc_attr, $description );
 
 
3881
  }
3882
  // Get the keywords.
3883
  $togglekeywords = 0;
@@ -4094,7 +4116,7 @@ class All_in_One_SEO_Pack extends All_in_One_SEO_Pack_Module {
4094
  $description = str_replace( '%wp_title%', $this->get_original_title(), $description );
4095
  }
4096
  if ( strpos( $description, '%post_title%' ) !== false ) {
4097
- $description = str_replace( '%post_title%', $this->get_aioseop_title( $post ), $description );
4098
  }
4099
  if ( strpos( $description, '%current_date%' ) !== false ) {
4100
  $description = str_replace( '%current_date%', date_i18n( get_option( 'date_format' ) ), $description );
@@ -4998,11 +5020,13 @@ EOF;
4998
  *
4999
  * @param string $value Value to filter.
5000
  * @param bool $truncate Flag that indicates if value should be truncated/cropped.
 
5001
  *
5002
  * @return string
5003
  */
5004
- public function filter_description( $value, $truncate = false ) {
5005
- if ( preg_match( '/5.2[\s\S]+/', PHP_VERSION ) ) {
 
5006
  $value = htmlspecialchars( wp_strip_all_tags( htmlspecialchars_decode( $value ) ) );
5007
  }
5008
  // Decode entities
1453
  function get_queried_object() {
1454
  static $p = null;
1455
  global $wp_query, $post;
1456
+ if ( null !== $p && ! defined( 'AIOSEOP_UNIT_TESTING' ) ) {
1457
  return $p;
1458
  }
1459
  if ( is_object( $post ) ) {
1589
  /**
1590
  * Gets the title that will be used by AIOSEOP for title rewrites or returns false.
1591
  *
1592
+ * @param WP_Post $post the post object
1593
+ * @param bool $use_original_title_format should the original title format be used viz. post_title | blog_title. This parameter was introduced
1594
+ * to resolve issue#986
1595
  *
1596
  * @return bool|string
1597
  */
1598
+ function get_aioseop_title( $post, $use_original_title_format = true ) {
1599
  global $aioseop_options;
1600
  // the_search_query() is not suitable, it cannot just return.
1601
  global $s, $STagging;
1741
  $title = $this->internationalize( get_post_meta( $post->ID, '_aioseop_title', true ) );
1742
  if ( ! $title ) {
1743
  $title = $this->internationalize( get_post_meta( $post->ID, 'title_tag', true ) );
1744
+ if ( ! $title && $use_original_title_format ) {
1745
  $title = $this->internationalize( $this->get_original_title( '', false ) );
1746
  }
1747
  }
1748
  if ( empty( $title ) ) {
1749
  $title = $post->post_title;
1750
  }
1751
+ if ( ! empty( $title ) && $use_original_title_format ) {
1752
  $title = $this->apply_post_title_format( $title, $category, $post );
1753
  }
1754
  $title = $this->paged_title( $title );
2490
  $description = $this->internationalize( $description );
2491
  }
2492
 
2493
+ // #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.
2494
+ $screen = is_admin() ? get_current_screen() : null;
2495
+ $ignore_php_version = $screen && isset( $screen->id ) && 'post' === $screen->id;
2496
+
2497
  $truncate = false;
2498
  $aioseop_desc = '';
2499
  if ( ! empty( $post->ID ) ) {
2507
  $description = apply_filters(
2508
  'aioseop_description',
2509
  $description,
2510
+ $truncate,
2511
+ $ignore_php_version
2512
  );
2513
 
2514
  return $description;
3010
  function add_page_icon() {
3011
  wp_enqueue_script( 'wp-pointer', false, array( 'jquery' ) );
3012
  wp_enqueue_style( 'wp-pointer' );
3013
+ //$this->add_admin_pointers();
3014
+
3015
  ?>
3016
  <script>
3017
  function aioseop_show_pointer(handle, value) {
3278
  add_filter( "{$this->prefix}submit_options", array( $this, 'filter_submit' ) );
3279
  }
3280
 
3281
+ /**
3282
+ * Admin Enqueue Scripts
3283
+ *
3284
+ * @since 2.5.0
3285
+ *
3286
+ * @uses All_in_One_SEO_Pack_Module::admin_enqueue_scripts();
3287
+ */
3288
+ function admin_enqueue_scripts() {
3289
+ wp_enqueue_style( 'aiosp_admin_style', AIOSEOP_PLUGIN_URL . 'css/aiosp_admin.css', array(), AIOSEOP_VERSION );
3290
+ parent::admin_enqueue_scripts();
3291
+ }
3292
+
3293
  function enqueue_scripts() {
3294
  add_filter( "{$this->prefix}display_settings", array( $this, 'filter_settings' ), 10, 3 );
3295
  add_filter( "{$this->prefix}display_options", array( $this, 'filter_options' ), 10, 2 );
3676
  add_action( 'admin_menu', array( $this, 'admin_menu' ) );
3677
 
3678
  add_action( 'admin_head', array( $this, 'add_page_icon' ) );
3679
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
3680
  add_action( 'admin_init', 'aioseop_addmycolumns', 1 );
3681
  add_action( 'admin_init', 'aioseop_handle_ignore_notice' );
3682
  if ( AIOSEOPPRO ) {
3702
  add_action( 'amp_post_template_head', array( $this, 'amp_head' ), 11 );
3703
  add_action( 'template_redirect', array( $this, 'template_redirect' ), 0 );
3704
  }
3705
+ add_filter( 'aioseop_description', array( &$this, 'filter_description' ), 10, 3 );
3706
  add_filter( 'aioseop_title', array( &$this, 'filter_title' ) );
3707
  }
3708
 
3837
  global $aioseop_update_checker, $wp_query, $aioseop_options, $posts;
3838
  static $aioseop_dup_counter = 0;
3839
  $aioseop_dup_counter ++;
3840
+ if ( ! defined( 'AIOSEOP_UNIT_TESTING' ) && $aioseop_dup_counter > 1 ) {
3841
+ echo "\n<!-- " . sprintf( __( 'Debug Warning: All in One SEO Pack meta data was included again from %1$s filter. Called %2$s times!', 'all-in-one-seo-pack' ), current_filter(), $aioseop_dup_counter ) . " -->\n";
 
3842
  if ( ! empty( $old_wp_query ) ) {
3843
  // Change the query back after we've finished.
3844
  $GLOBALS['wp_query'] = $old_wp_query;
3882
  }
3883
 
3884
  $posts = $save_posts;
 
3885
  // Handle the description format.
3886
+ // We are not going to mandate that post description needs to be present because the content could be derived from a custom field too.
3887
+ if ( ! ( is_front_page() && is_paged() ) ) {
3888
+ $description = $this->get_main_description( $post ); // Get the description.
3889
  $description = $this->trim_description( $description );
3890
  if ( ! isset( $meta_string ) ) {
3891
  $meta_string = '';
3897
  $desc_attr = '';
3898
  }
3899
  $desc_attr = apply_filters( 'aioseop_description_attributes', $desc_attr );
3900
+ if ( ! empty( $description ) ) {
3901
+ $meta_string .= sprintf( "<meta name=\"description\" %s content=\"%s\" />\n", $desc_attr, $description );
3902
+ }
3903
  }
3904
  // Get the keywords.
3905
  $togglekeywords = 0;
4116
  $description = str_replace( '%wp_title%', $this->get_original_title(), $description );
4117
  }
4118
  if ( strpos( $description, '%post_title%' ) !== false ) {
4119
+ $description = str_replace( '%post_title%', $this->get_aioseop_title( $post, false ), $description );
4120
  }
4121
  if ( strpos( $description, '%current_date%' ) !== false ) {
4122
  $description = str_replace( '%current_date%', date_i18n( get_option( 'date_format' ) ), $description );
5020
  *
5021
  * @param string $value Value to filter.
5022
  * @param bool $truncate Flag that indicates if value should be truncated/cropped.
5023
+ * @param bool $ignore_php_version Flag that indicates if the php version check should be ignored.
5024
  *
5025
  * @return string
5026
  */
5027
+ public function filter_description( $value, $truncate = false, $ignore_php_version = false ) {
5028
+ // TODO: change preg_match to version_compare someday when the reason for this condition is understood better.
5029
+ if ( $ignore_php_version || preg_match( '/5.2[\s\S]+/', PHP_VERSION ) ) {
5030
  $value = htmlspecialchars( wp_strip_all_tags( htmlspecialchars_decode( $value ) ) );
5031
  }
5032
  // Decode entities
all_in_one_seo_pack.php CHANGED
@@ -4,7 +4,7 @@
4
  Plugin Name: All In One SEO Pack
5
  Plugin URI: https://semperplugins.com/all-in-one-seo-pack-pro-version/
6
  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 30 million downloads since 2007.
7
- Version: 2.7.3
8
  Author: Michael Torbert
9
  Author URI: https://semperplugins.com/all-in-one-seo-pack-pro-version/
10
  Text Domain: all-in-one-seo-pack
@@ -32,14 +32,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
32
  * The original WordPress SEO plugin.
33
  *
34
  * @package All-in-One-SEO-Pack
35
- * @version 2.7.3
36
  */
37
 
38
  if ( ! defined( 'AIOSEOPPRO' ) ) {
39
  define( 'AIOSEOPPRO', false );
40
  }
41
  if ( ! defined( 'AIOSEOP_VERSION' ) ) {
42
- define( 'AIOSEOP_VERSION', '2.7.3' );
43
  }
44
  global $aioseop_plugin_name;
45
  $aioseop_plugin_name = 'All in One SEO Pack';
4
  Plugin Name: All In One SEO Pack
5
  Plugin URI: https://semperplugins.com/all-in-one-seo-pack-pro-version/
6
  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 30 million downloads since 2007.
7
+ Version: 2.8
8
  Author: Michael Torbert
9
  Author URI: https://semperplugins.com/all-in-one-seo-pack-pro-version/
10
  Text Domain: all-in-one-seo-pack
32
  * The original WordPress SEO plugin.
33
  *
34
  * @package All-in-One-SEO-Pack
35
+ * @version 2.8
36
  */
37
 
38
  if ( ! defined( 'AIOSEOPPRO' ) ) {
39
  define( 'AIOSEOPPRO', false );
40
  }
41
  if ( ! defined( 'AIOSEOP_VERSION' ) ) {
42
+ define( 'AIOSEOP_VERSION', '2.8' );
43
  }
44
  global $aioseop_plugin_name;
45
  $aioseop_plugin_name = 'All in One SEO Pack';
css/modules/aioseop_module.css CHANGED
@@ -157,7 +157,7 @@ div.aioseop_tip_icon:before {
157
  border: 1px solid #e1e1e1;
158
  }
159
 
160
- .aioseop input[type="text"] {
161
  color: #515151;
162
  height: 35px;
163
  padding: 10px 0 10px 10px;
157
  border: 1px solid #e1e1e1;
158
  }
159
 
160
+ .aioseop input[type="text"], .aioseop input[type="url"] {
161
  color: #515151;
162
  height: 35px;
163
  padding: 10px 0 10px 10px;
css/welcome.css CHANGED
@@ -53,34 +53,24 @@ section:first-child {
53
  .welcome-panel-close {
54
  z-index: 2;
55
  }
56
- .welcome-panel .welcome-widgets-menus:before,
57
- .welcome-panel .welcome-comments:before,
58
- .welcome-panel .welcome-learn-more:before{
59
- content: '';
60
- }
61
- .welcome-panel .welcome-widgets-menus {
62
- background: url(/path/to/icon) 0 50% no-repeat;
63
- }
64
- .welcome-panel .welcome-comments {
65
- background: url(/path/to/icon) 0 50% no-repeat;
66
- }
67
- .welcome-panel .welcome-learn-more {
68
- background: url(/path/to/icon) 0 50% no-repeat;
69
- }
70
 
 
 
 
71
 
72
- /*
73
- * Welcome Panel
74
- */
75
- #welcome-panel > p {
76
  margin-left: 15px;
77
  }
78
 
 
 
 
 
79
  .welcome-panel-column {
80
- width: 30%;
81
- margin-right: 3%;
82
- display: inline-block;
83
- vertical-align: top;
84
  }
85
 
86
  .welcome-panel-column:last-child {
@@ -115,11 +105,6 @@ section:first-child {
115
  margin-left: 20px;
116
  }
117
 
118
- .welcome-panel-column ul li {
119
- margin-bottom: 12px;
120
- list-style-type: square;
121
- }
122
-
123
  #wp-people-group-rockstars li {
124
  margin-bottom: 1.33em;
125
  }
53
  .welcome-panel-close {
54
  z-index: 2;
55
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
 
57
+ .welcome-panel {
58
+ overflow-x: hidden;
59
+ }
60
 
61
+ .welcome-panel > p {
 
 
 
62
  margin-left: 15px;
63
  }
64
 
65
+ .welcome-panel-content {
66
+ display: inline-block;
67
+ }
68
+
69
  .welcome-panel-column {
70
+ width: 30% !important;
71
+ margin-right: 3%;
72
+ display: inline-block;
73
+ vertical-align: top;
74
  }
75
 
76
  .welcome-panel-column:last-child {
105
  margin-left: 20px;
106
  }
107
 
 
 
 
 
 
108
  #wp-people-group-rockstars li {
109
  margin-bottom: 1.33em;
110
  }
inc/aioseop_functions.php CHANGED
@@ -428,15 +428,23 @@ if ( ! function_exists( 'aioseop_ajax_save_url' ) ) {
428
 
429
  function aioseop_ajax_save_url() {
430
  $valid = true;
 
431
  aioseop_ajax_init();
432
  $options = array();
433
  parse_str( $_POST['options'], $options );
434
  foreach ( $options as $k => $v ) {
435
  // all values are mandatory while adding to the sitemap.
436
  // this should work in the same way for news and video sitemaps too, but tackling only regular sitemaps for now.
437
- if ( 'sitemap_addl_pages' === $_POST['settings'] && empty( $v ) ) {
438
- $valid = false;
439
- break;
 
 
 
 
 
 
 
440
  }
441
  $_POST[ $k ] = $v;
442
  }
@@ -471,7 +479,11 @@ if ( ! function_exists( 'aioseop_ajax_save_url' ) ) {
471
  $output = str_replace( "'", "\'", $output );
472
  $output = str_replace( "\n", '\n', $output );
473
  } else {
474
- $output = __( 'All values are mandatory.', 'all-in-one-seo-pack' );
 
 
 
 
475
  }
476
  die( sprintf( AIOSEOP_AJAX_MSG_TMPL, $output ) );
477
  }
428
 
429
  function aioseop_ajax_save_url() {
430
  $valid = true;
431
+ $invalid_msg = null;
432
  aioseop_ajax_init();
433
  $options = array();
434
  parse_str( $_POST['options'], $options );
435
  foreach ( $options as $k => $v ) {
436
  // all values are mandatory while adding to the sitemap.
437
  // this should work in the same way for news and video sitemaps too, but tackling only regular sitemaps for now.
438
+ if ( 'sitemap_addl_pages' === $_POST['settings'] ) {
439
+ if ( empty( $v ) ) {
440
+ $valid = false;
441
+ } elseif ( 'aiosp_sitemap_addl_url' === $k && ! aiosp_common::is_url_valid( $v ) ) {
442
+ $valid = false;
443
+ $invalid_msg = __( 'Please provide absolute URLs (including http or https).', 'all-in-one-seo-pack' );
444
+ }
445
+ if ( ! $valid ) {
446
+ break;
447
+ }
448
  }
449
  $_POST[ $k ] = $v;
450
  }
479
  $output = str_replace( "'", "\'", $output );
480
  $output = str_replace( "\n", '\n', $output );
481
  } else {
482
+ if ( $invalid_msg ) {
483
+ $output = $invalid_msg;
484
+ } else {
485
+ $output = __( 'All values are mandatory.', 'all-in-one-seo-pack' );
486
+ }
487
  }
488
  die( sprintf( AIOSEOP_AJAX_MSG_TMPL, $output ) );
489
  }
inc/aiosp_common.php CHANGED
@@ -129,4 +129,45 @@ class aiosp_common {
129
  return $url;
130
  }
131
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  }
129
  return $url;
130
  }
131
 
132
+ /**
133
+ * Check whether a url is relative (does not contain a . before the first /) or absolute and makes it a valid url.
134
+ *
135
+ * @param string $url URL to check.
136
+ *
137
+ * @return string
138
+ */
139
+ static function make_url_valid_smartly( $url ) {
140
+ $scheme = parse_url( home_url(), PHP_URL_SCHEME );
141
+ if ( 0 !== strpos( $url, 'http' ) ) {
142
+ if ( 0 === strpos( $url, '//' ) ) {
143
+ // for //<host>/resource type urls.
144
+ $url = $scheme . ':' . $url;
145
+ } elseif ( strpos( $url, '.' ) !== false && strpos( $url, '/' ) !== false && strpos( $url, '.' ) < strpos( $url, '/' ) ) {
146
+ // if the . comes before the first / then this is absolute.
147
+ $url = $scheme . '://' . $url;
148
+ } else {
149
+ // for /resource type urls.
150
+ $url = home_url( $url );
151
+ }
152
+ } else if ( strpos( $url, 'http://' ) === false ) {
153
+ if ( 0 === strpos( $url, 'http:/' ) ) {
154
+ $url = $scheme . '://' . str_replace( 'http:/', '', $url );
155
+ } else if ( 0 === strpos( $url, 'http:' ) ) {
156
+ $url = $scheme . '://' . str_replace( 'http:', '', $url );
157
+ }
158
+ }
159
+ return $url;
160
+ }
161
+
162
+ /**
163
+ * Check whether a url is valid.
164
+ *
165
+ * @param string $url URL to check.
166
+ *
167
+ * @return bool
168
+ */
169
+ public static function is_url_valid( $url ) {
170
+ return filter_var( filter_var( $url, FILTER_SANITIZE_URL ), FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED | FILTER_FLAG_HOST_REQUIRED ) !== false;
171
+ }
172
+
173
  }
inc/compatability/compat-wpml.php CHANGED
@@ -29,6 +29,7 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Wpml' ) ) {
29
  public function hooks() {
30
  add_filter( 'aioseop_home_url', array( &$this, 'aioseop_home_url' ) );
31
  add_filter( 'aioseop_sitemap_xsl_url', array( &$this, 'aioseop_sitemap_xsl_url' ) );
 
32
  }
33
 
34
  /**
29
  public function hooks() {
30
  add_filter( 'aioseop_home_url', array( &$this, 'aioseop_home_url' ) );
31
  add_filter( 'aioseop_sitemap_xsl_url', array( &$this, 'aioseop_sitemap_xsl_url' ) );
32
+ add_action( 'init', 'aioseop_get_options' ); // #1761 Options are otherwise called too early to work with WPML.
33
  }
34
 
35
  /**
inc/sitemap-xsl.php CHANGED
@@ -139,6 +139,16 @@ echo '<?xml version="1.0" encoding="UTF-8"?>';
139
  </table>
140
  </xsl:template>
141
  <xsl:template name="sitemapTable">
 
 
 
 
 
 
 
 
 
 
142
  <table cellpadding="3">
143
  <thead>
144
  <tr>
@@ -150,6 +160,16 @@ echo '<?xml version="1.0" encoding="UTF-8"?>';
150
  <?php
151
  }
152
  ?>
 
 
 
 
 
 
 
 
 
 
153
  <th>Priority</th>
154
  <th>Change Frequency</th>
155
  <th>Last Change</th>
@@ -170,17 +190,6 @@ echo '<?xml version="1.0" encoding="UTF-8"?>';
170
  <a href="{$itemURL}">
171
  <xsl:value-of select="sitemap:loc"/>
172
  </a>
173
- <xsl:for-each select="video:video">
174
- <xsl:variable name="thumbURL">
175
- <xsl:value-of select="video:thumbnail_loc"/>
176
- </xsl:variable>
177
- <xsl:variable name="playURL">
178
- <xsl:value-of select="video:player_loc"/>
179
- </xsl:variable>
180
- <xsl:if test="$thumbURL != ''">
181
- <a href="{$playURL}"><img src="{$thumbURL}" style="max-width:60px;float:right;"/></a>
182
- </xsl:if>
183
- </xsl:for-each>
184
  </td>
185
  <?php
186
  if ( aiosp_include_images() ) {
@@ -191,6 +200,34 @@ echo '<?xml version="1.0" encoding="UTF-8"?>';
191
  <?php
192
  }
193
  ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
194
  <td>
195
  <xsl:if test="string(number(sitemap:priority))!='NaN'">
196
  <xsl:value-of select="concat(sitemap:priority*100,'%')"/>
139
  </table>
140
  </xsl:template>
141
  <xsl:template name="sitemapTable">
142
+ <xsl:variable name="sitemapType">
143
+ <xsl:for-each select="/*/namespace::*">
144
+ <xsl:if test="name()='video'">
145
+ <xsl:choose>
146
+ <xsl:when test="name()='video'">video</xsl:when>
147
+ </xsl:choose>
148
+ </xsl:if>
149
+ </xsl:for-each>
150
+ </xsl:variable>
151
+
152
  <table cellpadding="3">
153
  <thead>
154
  <tr>
160
  <?php
161
  }
162
  ?>
163
+ <?php
164
+ if ( AIOSEOPPRO ) {
165
+ ?>
166
+ <xsl:if test="$sitemapType='video'">
167
+ <th>Videos</th>
168
+ <th>Video Thumbnails</th>
169
+ </xsl:if>
170
+ <?php
171
+ }
172
+ ?>
173
  <th>Priority</th>
174
  <th>Change Frequency</th>
175
  <th>Last Change</th>
190
  <a href="{$itemURL}">
191
  <xsl:value-of select="sitemap:loc"/>
192
  </a>
 
 
 
 
 
 
 
 
 
 
 
193
  </td>
194
  <?php
195
  if ( aiosp_include_images() ) {
200
  <?php
201
  }
202
  ?>
203
+ <?php
204
+ if ( AIOSEOPPRO ) {
205
+ ?>
206
+ <xsl:if test="$sitemapType='video'">
207
+ <td>
208
+ <xsl:value-of select="count(video:video)"/>
209
+ </td>
210
+ <td>
211
+ <xsl:if test="$sitemapType='video'">
212
+ <xsl:for-each select="video:video">
213
+ <xsl:variable name="thumbURL">
214
+ <xsl:value-of select="video:thumbnail_loc"/>
215
+ </xsl:variable>
216
+ <xsl:variable name="playURL">
217
+ <xsl:value-of select="video:player_loc"/>
218
+ </xsl:variable>
219
+ <xsl:if test="$thumbURL != ''">
220
+ <div style="float: left; width:60px;">
221
+ <a href="{$playURL}" target="_new"><img src="{$thumbURL}"/></a>
222
+ </div>
223
+ </xsl:if>
224
+ </xsl:for-each>
225
+ </xsl:if>
226
+ </td>
227
+ </xsl:if>
228
+ <?php
229
+ }
230
+ ?>
231
  <td>
232
  <xsl:if test="string(number(sitemap:priority))!='NaN'">
233
  <xsl:value-of select="concat(sitemap:priority*100,'%')"/>
js/modules/aioseop_module.js CHANGED
@@ -1,875 +1,887 @@
1
- /**
2
- * Controls all the styling of the plugin.
3
- *
4
- * AIOSEOP Updates class.
5
- * @author Michael Torbert.
6
- * @author Semper Fi Web Design.
7
- * @copyright https://semperplugins.com
8
- * @version 1.0.0
9
- */
10
- if ( typeof aiosp_data != 'undefined' ) {
11
-
12
- /**
13
- * @since 1.0.0
14
- * @param int $index.
15
- * @param $value
16
- */
17
- jQuery.each(
18
- aiosp_data, function( index, value ) {
19
- // aiosp_data[index] = value.json.replace(/&quot;/g, '"');
20
- // aiosp_data[index] = jQuery.parseJSON( value );
21
- if ( index == 0 ) {
22
- if ( typeof value.condshow == 'undefined' ) {
23
- aiosp_data[ index ].condshow = [];
24
- }
25
- } else {
26
- if ( typeof value.condshow != 'undefined' ) {
27
- aiosp_data[ 0 ].condshow =
28
- jQuery.merge( aiosp_data[0].condshow, value.condshow );
29
- }
30
- }
31
- }
32
- );
33
- aiosp_data = aiosp_data[0];
34
- }
35
-
36
- /**
37
- * @summary Changes visibility.
38
- *
39
- * @since 1.0.0
40
- * @param int $id.
41
- */
42
- function toggleVisibility( id ) {
43
- var e = document.getElementById( id );
44
- if ( e.style.display == 'block' ) {
45
- e.style.display = 'none';
46
- } else {
47
- e.style.display = 'block';
48
- }
49
- }
50
-
51
- /**
52
- * @summary Counts characters.
53
- *
54
- * @since 1.0.0
55
- * @param Object $field.
56
- * @param Object $cntfield.
57
- * @return Mixed.
58
- */
59
- function countChars( field, cntfield ) {
60
- var extra = 0;
61
- var field_size;
62
- if ( ( field.attr('name') == 'aiosp_title' )
63
- && ( typeof aiosp_title_extra !== 'undefined' ) ) {
64
- extra = aiosp_title_extra;
65
- }
66
- cntfield.val(field.val().length + extra);
67
- if ( typeof field.attr('size') != 'undefined' ) {
68
- field_size = field.attr('size');
69
- } else {
70
- field_size = field.attr('rows') * field.attr('cols');
71
- }
72
- field_size = parseInt(field_size, 10);
73
- if ( field_size < 10 ) {
74
- return;
75
- }
76
- if ( cntfield.val() > field_size ) {
77
- cntfield.removeClass().addClass('aioseop_count_ugly');
78
- } else if ( ( 'aiosp_title' === field.attr('name' ) ) || ( 'aiosp_home_title' === field.attr('name') ) ) {
79
- if ( cntfield.val() > ( field_size - 6 ) ) {
80
- cntfield.removeClass().addClass('aioseop_count_bad');
81
- } else {
82
- cntfield.removeClass().addClass('aioseop_count_good');
83
- }
84
- } else {
85
- if ( cntfield.val() > ( field_size - 10 ) ) {
86
- cntfield.removeClass().addClass('aioseop_count_bad');
87
- } else {
88
- cntfield.removeClass().addClass('aioseop_count_good');
89
- }
90
- }
91
- }
92
-
93
- /**
94
- * @summary Returns the fields value.
95
- *
96
- * @since 1.0.0
97
- * @param String $field.
98
- * @return Mixed.
99
- */
100
- function aioseop_get_field_value( field ) {
101
- if ( field.length == 0 ) {
102
- return field;
103
- }
104
- cur = jQuery( '[name=' + field + ']' );
105
- if ( cur.length == 0 ) {
106
- return field;
107
- }
108
- type = cur.attr( 'type' );
109
- if ( type == "checkbox" || type == "radio" ) {
110
- cur = jQuery( 'input[name=' + field + ']:checked' );
111
- }
112
- return cur.val();
113
- }
114
-
115
- /**
116
- * @summary Returns the fields value.
117
- *
118
- * @since 1.0.0
119
- * @param String $field.
120
- * @return Mixed.
121
- */
122
- function aioseop_get_field_values( field ) {
123
- arr = [];
124
- cur = jQuery( '[name=' + field + ']' );
125
- if ( cur.length == 0 ) {
126
- return field;
127
- }
128
- type = cur.attr( 'type' );
129
- if ( type == "checkbox" || type == "radio" ) {
130
- jQuery( 'input[name=' + field + ']:checked' ).each(
131
- function() {
132
- arr.push( jQuery( this ).val() );
133
- }
134
- );
135
- }
136
- if ( arr.length <= 0 ) {
137
- arr.push( cur.val() );
138
- }
139
- return arr;
140
- }
141
-
142
- /**
143
- * @summary Evaluates condshow logic.
144
- *
145
- * @since 1.0.0
146
- * @param String $statement.
147
- * @return Mixed.
148
- */
149
- function aioseop_eval_condshow_logic( statement ) {
150
- var lhs, rhs;
151
- if ( ( typeof statement ) == 'object' ) {
152
- lhs = statement.lhs;
153
- rhs = statement.rhs;
154
- if ( lhs !== null && ( ( typeof lhs ) == 'object' ) ) {
155
- lhs = aioseop_eval_condshow_logic( lhs );
156
- }
157
- if ( rhs !== null && ( typeof rhs ) == 'object' ) {
158
- rhs = aioseop_eval_condshow_logic( rhs );
159
- }
160
- lhs = aioseop_get_field_value( lhs );
161
- rhs = aioseop_get_field_value( rhs );
162
- switch ( statement.op ) {
163
- case 'NOT':
164
- return ( ! lhs );
165
- case 'AND':
166
- return ( lhs && rhs );
167
- case 'OR' :
168
- return ( lhs || rhs );
169
- case '==' :
170
- return ( lhs == rhs );
171
- case '!=' :
172
- return ( lhs != rhs );
173
- default :
174
- return null;
175
- }
176
- }
177
- return statement;
178
- }
179
-
180
- /**
181
- * @summary Evaluates condshow logic.
182
- *
183
- * @since 1.0.0
184
- * @param String $index.
185
- * @param $value.
186
- * @return Mixed.
187
- */
188
- function aioseop_do_condshow_match( index, value ) {
189
- if ( typeof value != 'undefined' ) {
190
- matches = true;
191
- jQuery.each(
192
- value, function(subopt, setting) {
193
- var statement;
194
- if ( ( typeof setting ) == 'object' ) {
195
- statement = aioseop_eval_condshow_logic( setting );
196
- if ( ! statement ) {
197
- matches = false;
198
- }
199
- } else {
200
- if ( subopt.match( /\\\[\\\]/ ) ) { // special case for these -- pdb
201
- cur = aioseop_get_field_values( subopt );
202
- if ( jQuery.inArray( setting, cur, 0 ) < 0 ) {
203
- matches = false;
204
- }
205
- } else {
206
- cur = aioseop_get_field_value( subopt );
207
- if ( cur != setting ) {
208
- matches = false;
209
- }
210
- }
211
- }
212
- }
213
- );
214
- if ( matches ) {
215
- jQuery( '#' + index + '_wrapper' ).show();
216
- } else {
217
- jQuery( '#' + index + '_wrapper' ).hide();
218
- }
219
- return matches;
220
- }
221
- return false;
222
- }
223
-
224
- /**
225
- * @summary Adds condshow handlers.
226
- *
227
- * @since 1.0.0
228
- * @param String $index.
229
- * @param $value.
230
- */
231
- function aioseop_add_condshow_handlers( index, value ) {
232
- if ( typeof value != 'undefined' ) {
233
- jQuery.each(
234
- value, function(subopt, setting) {
235
- jQuery( '[name=' + subopt + ']' ).bind(
236
- "change keyup", function() {
237
- aioseop_do_condshow_match( index, value );
238
- }
239
- );
240
- }
241
- );
242
- }
243
- }
244
-
245
- /**
246
- * @summary Does condshow.
247
- *
248
- * @since 1.0.0
249
- * @param $condshow.
250
- */
251
- function aioseop_do_condshow( condshow ) {
252
- if ( typeof aiosp_data.condshow != 'undefined' ) {
253
- jQuery.each(
254
- aiosp_data.condshow, function( index, value ) {
255
- aioseop_do_condshow_match( index, value );
256
- aioseop_add_condshow_handlers( index, value );
257
- }
258
- );
259
- }
260
- }
261
-
262
- /**
263
- * @since 1.0.0
264
- */
265
- jQuery( document ).ready(
266
- function() {
267
- if ( typeof aiosp_data != 'undefined' ) {
268
- if ( typeof aiosp_data.condshow != 'undefined' ) {
269
- aioseop_do_condshow( aiosp_data.condshow );
270
- }
271
- }
272
-
273
- /**
274
- * Turns on image checker on custom url change.
275
- * @since 2.3.16
276
- */
277
- jQuery( '.aioseop_upload_image_label' ).on(
278
- 'change', function() {
279
- this.checker = jQuery( this ).parent().find( '.aioseop_upload_image_checker' );
280
- if ( this.checker.length > 0 ) {
281
- this.checker.val( 1 );
282
- }
283
- }
284
- );
285
-
286
- /**
287
- * @summary workaround for bug that causes radio inputs to lose settings when meta box is dragged.
288
- *
289
- * props to commentluv for this fix
290
- * @author commentluv.
291
- * @link https://core.trac.wordpress.org/ticket/16972
292
- * @since 1.0.0
293
- */
294
- jQuery(document).ready(
295
- function () {
296
- // listen for drag drop of metaboxes , bind mousedown to .hndle so it only fires when starting to drag
297
- jQuery('.hndle').mousedown(
298
- function () {
299
-
300
- // set live event listener for mouse up on the content .wrap and wait a tick to give the dragged div time to settle before firing the reclick function
301
- jQuery('.wrap').mouseup(
302
- function () {
303
- aiosp_store_radio();
304
- setTimeout(function () {
305
- aiosp_reclick_radio();
306
- }, 50);
307
- }
308
- );
309
- }
310
- );
311
- }
312
- );
313
-
314
- /**
315
- * @summary Javascript for using WP media uploader. Indentifies which DOM should use custom uploader plugin.
316
- *
317
- * @see http://www.webmaster-source.com/2013/02/06/using-the-wordpress-3-5-media-uploader-in-your-plugin-or-theme/
318
- * @since ?
319
- * @since 2.3.11.2 Use WP 3.5 new media uploader
320
- * @since 2.3.13 Fixed issue #[740](https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/740)
321
- *
322
- */
323
- jQuery(document).ready(
324
- function ($) {
325
- jQuery('.aioseop_upload_image_button').each(
326
- function () {
327
- jQuery(this).aioseopImageUploader(
328
- {
329
- success: function (url, el) {
330
- // Update checker
331
- if (jQuery(el).prev().length > 0) {
332
- jQuery(el).prev().val(1);
333
- }
334
- },
335
- }
336
- );
337
- }
338
- );
339
- }
340
- );
341
-
342
- jQuery(document).ready(
343
- function () {
344
- jQuery("#poststuff .aioseop_radio_type input[type='radio']").on(
345
- 'click', function () {
346
- var previousValue = jQuery(this).attr('previousValue');
347
- var name = jQuery(this).attr('name');
348
- if (typeof previousValue == 'undefined') {
349
- if (jQuery(this).prop("checked")) {
350
- jQuery(this).prop('checked', true);
351
- jQuery(this).attr('previousValue', 'checked');
352
- } else {
353
- jQuery(this).prop('checked', false);
354
- jQuery(this).attr('previousValue', false);
355
- }
356
- return;
357
- }
358
- if (previousValue == 'checked') {
359
- jQuery(this).prop('checked', false);
360
- jQuery(this).attr('previousValue', false);
361
- } else {
362
- jQuery("input[name=" + name + "]:radio")
363
- .attr('previousValue', false);
364
- jQuery(this).attr('previousValue', 'checked');
365
- }
366
- }
367
- );
368
- }
369
- );
370
- if ( typeof aiosp_data.pointers != 'undefined' ) {
371
-
372
- /**
373
- * @since 1.0.0
374
- * @param $index.
375
- * @param $value.
376
- * @return mixed.
377
- */
378
- jQuery.each(
379
- aiosp_data.pointers, function( index, value ) {
380
- if ( value != 'undefined' && value.pointer_text != '' ) {
381
- aioseop_show_pointer( index, value );
382
- }
383
- }
384
- );
385
- }
386
-
387
- /**
388
- * @since 1.0.0
389
- * @param $e.
390
- * @return boolean.
391
- */
392
- jQuery( ".all-in-one-seo_page_all-in-one-seo-pack-modules-aioseop_feature_manager #aiosp_settings_form .aioseop_settings_left" )
393
- .delegate(
394
- "input[name='Submit']", "click", function( e ) {
395
- e.preventDefault();
396
- return false;
397
- }
398
- );
399
-
400
- /**
401
- * @since 1.0.0
402
- * @param $e.
403
- * @return boolean.
404
- */
405
- jQuery( ".all-in-one-seo_page_all-in-one-seo-pack-modules-aioseop_feature_manager #aiosp_settings_form" )
406
- .delegate(
407
- "input[name='Submit']", "click", function( e ) {
408
- e.preventDefault();
409
- aioseop_handle_post_url(
410
- 'aioseop_ajax_save_settings',
411
- 'ajax_settings_message',
412
- jQuery( 'form#aiosp_settings_form' ).serialize(),
413
- function() {
414
- jQuery( '.wp-has-current-submenu' ).fadeIn(
415
- 'fast', function() {
416
- aioseop_handle_ajax_call(
417
- 'aioseop_ajax_get_menu_links',
418
- 'ajax_settings_message',
419
- jQuery.param( {target: '.wp-has-current-submenu > ul'} )
420
- );
421
- }
422
- );
423
- }
424
- );
425
- return false;
426
- }
427
- );
428
-
429
- /**
430
- * @since 1.0.0
431
- * @param $e.
432
- * @return boolean.
433
- */
434
- jQuery( ".all-in-one-seo_page_all-in-one-seo-pack-pro-modules-aioseop_feature_manager #aiosp_settings_form .aioseop_settings_left" )
435
- .delegate(
436
- "input[name='Submit']", "click", function( e ) {
437
- e.preventDefault();
438
- return false;
439
- }
440
- );
441
-
442
- /**
443
- * @since 1.0.0
444
- * @param $e.
445
- * @return boolean.
446
- */
447
- jQuery( ".all-in-one-seo_page_all-in-one-seo-pack-pro-modules-aioseop_feature_manager #aiosp_settings_form" )
448
- .delegate(
449
- "input[name='Submit']", "click", function( e ) {
450
- e.preventDefault();
451
- aioseop_handle_post_url(
452
- 'aioseop_ajax_save_settings',
453
- 'ajax_settings_message',
454
- jQuery( 'form#aiosp_settings_form' ).serialize(),
455
- function() {
456
- jQuery( '.wp-has-current-submenu' ).fadeIn(
457
- 'fast', function() {
458
- aioseop_handle_ajax_call(
459
- 'aioseop_ajax_get_menu_links',
460
- 'ajax_settings_message',
461
- jQuery.param( {target: '.wp-has-current-submenu > ul'} )
462
- );
463
- }
464
- );
465
- }
466
- );
467
- return false;
468
- }
469
- );
470
-
471
- var selectors =
472
- "div.aioseop_multicheckbox_type div.aioseop_option_div, #aiosp_sitemap_debug div.aioseop_option_div, #aiosp_performance_status div.aioseop_option_div";
473
-
474
- /**
475
- * @since 1.0.0
476
- * @return boolean.
477
- */
478
- jQuery( "div#aiosp_sitemap_addl_pages_metabox" )
479
- .delegate(
480
- "input[name='Submit']", "click", function() {
481
- aioseop_handle_post_url(
482
- 'aioseop_ajax_save_url',
483
- 'sitemap_addl_pages',
484
- jQuery( 'div#aiosp_sitemap_addl_pages_metabox input, div#aiosp_sitemap_addl_pages_metabox select' )
485
- .serialize()
486
- );
487
- return false;
488
- }
489
- );
490
-
491
- /**
492
- * @since 1.0.0
493
- * @return boolean.
494
- */
495
- jQuery( "div#aiosp_video_sitemap_addl_pages_metabox" )
496
- .delegate(
497
- "input[name='Submit']", "click", function() {
498
- aioseop_handle_post_url(
499
- 'aioseop_ajax_save_url',
500
- 'video_sitemap_addl_pages',
501
- jQuery( 'div#aiosp_video_sitemap_addl_pages_metabox input, div#aiosp_video_sitemap_addl_pages_metabox select' )
502
- .serialize()
503
- );
504
- return false;
505
- }
506
- );
507
-
508
- /**
509
- * @since 1.0.0
510
- * @param $e.
511
- * @return boolean.
512
- */
513
- jQuery( "div#aiosp_sitemap_addl_pages_metabox" )
514
- .delegate(
515
- "a.aiosp_delete_url", "click", function( e ) {
516
- e.preventDefault();
517
- aioseop_handle_post_url(
518
- 'aioseop_ajax_delete_url',
519
- 'sitemap_addl_pages',
520
- jQuery( this ).attr( "title" )
521
- );
522
- return false;
523
- }
524
- );
525
-
526
- /**
527
- * @since 1.0.0
528
- * @param $e.
529
- * @return boolean.
530
- */
531
- jQuery( "div#aiosp_video_sitemap_addl_pages_metabox" )
532
- .delegate(
533
- "a.aiosp_delete_url", "click", function( e ) {
534
- e.preventDefault();
535
- aioseop_handle_post_url(
536
- 'aioseop_ajax_delete_url',
537
- 'video_sitemap_addl_pages',
538
- jQuery( this ).attr( "title" )
539
- );
540
- return false;
541
- }
542
- );
543
-
544
- /**
545
- * @since 1.0.0
546
- * @param $e.
547
- * @return boolean.
548
- */
549
- jQuery( "div#aiosp_opengraph_scan_header" )
550
- .delegate(
551
- "input[name='aiosp_opengraph_scan_header']", "click", function( e ) {
552
- e.preventDefault();
553
- aioseop_handle_post_url(
554
- 'aioseop_ajax_scan_header',
555
- 'opengraph_scan_header',
556
- jQuery( 'div#aiosp_opengraph_scan_header' ).serialize()
557
- );
558
- return false;
559
- }
560
- );
561
-
562
- /**
563
- * @since 1.0.0
564
- */
565
- 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"]' )
566
- .click(
567
- function() {
568
- jQuery( this )
569
- .parents( 'div:eq(0)' )
570
- .find( ':checkbox' )
571
- .prop( 'checked', this.checked );
572
- }
573
- );
574
-
575
- /**
576
- * @since 1.0.0
577
- */
578
- 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"]' )
579
- .click(
580
- function () {
581
- if ( ! this.checked ) {
582
- jQuery( this )
583
- .parents( 'div:eq(0)' )
584
- .find( 'input[value="all"]:checkbox' )
585
- .prop( 'checked', this.checked );
586
- }
587
- }
588
- );
589
-
590
- /**
591
- * @since 1.0.0
592
- */
593
- jQuery( ".aioseop_tab:not(:first)" ).hide();
594
-
595
- /**
596
- * @since 1.0.0
597
- */
598
- jQuery( ".aioseop_tab:first" ).show();
599
-
600
- /**
601
- * @since 1.0.0
602
- * @return boolean.
603
- */
604
- jQuery( "a.aioseop_header_tab" ).click(
605
- function() {
606
- var stringref = jQuery( this ).attr( "href" ).split( '#' )[1];
607
- jQuery( '.aioseop_tab:not(#' + stringref + ')' ).hide( 'slow' );
608
- jQuery( '.aioseop_tab#' + stringref ).show( 'slow' );
609
- jQuery( '.aioseop_header_tab[href!="#' + stringref + '"]' ).removeClass( 'active' );
610
- jQuery( '.aioseop_header_tab[href="#' + stringref + '"]' ).addClass( 'active' );
611
- return false;
612
- }
613
- );
614
-
615
-
616
- jQuery( "div#aiosp_robots_default_metabox" )
617
- .delegate(
618
- "a.aiosp_robots_delete_rule", "click", function( e ) {
619
- e.preventDefault();
620
- aioseop_handle_post_url(
621
- 'aioseop_ajax_delete_rule',
622
- 'robots_rules',
623
- jQuery( this ).attr( "data-id" ),
624
- function() {
625
- window.location.reload();
626
- }
627
- );
628
- return false;
629
- }
630
- );
631
-
632
- jQuery( "a.aiosp_robots_physical" ).on( 'click', function( e ) {
633
- e.preventDefault();
634
- aioseop_handle_post_url(
635
- 'aioseop_ajax_robots_physical',
636
- 'robots_physical_import_delete',//'robots_metabox', // No element of the ID existed, and unsure which element its intended for.
637
- jQuery( this ).attr( "data-action" ),
638
- function( data ) {
639
- if ( data.data && data.data.message ) {
640
- alert( data.data.message );
641
- }
642
- window.location.reload();
643
- },
644
- true
645
- );
646
- return false;
647
- });
648
-
649
- aiospinitAll();
650
- aiospinitCounting();
651
-
652
- }
653
- );
654
-
655
- /**
656
- * @summary Custom jQuery plugin that enables image uploader in wordpress.
657
- *
658
- * @since 2.3.13
659
- * @since 2.4.14 Added success callback and options.
660
- * @see http://www.webmaster-source.com/2013/02/06/using-the-wordpress-3-5-media-uploader-in-your-plugin-or-theme/
661
- *
662
- * @param object options Plugin options.
663
- */
664
- jQuery.fn.aioseopImageUploader = function( options ) {
665
- // Keep reference to this.
666
- var self = this;
667
-
668
- // Options
669
- self.options = jQuery.extend(
670
- {
671
- success: undefined,
672
- }, options
673
- );
674
-
675
- // Set input target when to update image url value
676
- self.target = jQuery( self ).next();
677
-
678
- // Uploader per image button
679
- // * Having only one uploader was causing problems when multiple image buttons where in place
680
- self.uploader = wp.media(
681
- {
682
- title: 'Choose Image',
683
- button: {
684
- text: 'Choose Image'
685
- },
686
- multiple: false
687
- }
688
- );
689
-
690
- /**
691
- * Event handler that will be called when an image is selected from media uploader.
692
- */
693
- self.onSelect = function() {
694
- var url = self.uploader.state().get( 'selection' ).first().toJSON().url;
695
- if ( self.target.length >= 0 ) {
696
- jQuery( self.target ).val( url );
697
- }
698
- if ( self.options.success !== undefined ) {
699
- self.options.success( url, self );
700
- }
701
- };
702
-
703
- /**
704
- * Click event handler.
705
- * @param object e Click event.
706
- */
707
- self.onClick = function( e ) {
708
- e.preventDefault();
709
- self.uploader.open();
710
- };
711
-
712
- // Set uploader select handler
713
- self.uploader.on( 'select', self.onSelect );
714
-
715
- // Set click handler
716
- jQuery( self ).click( self.onClick );
717
- };
718
-
719
- /**
720
- * @summary Stores object of all radio buttons that are checked for entire form.
721
- *
722
- * @since 1.0.0
723
- */
724
- function aiosp_store_radio() {
725
- var radioshack = {};
726
- jQuery( 'input[type="radio"]' ).each(
727
- function() {
728
- if ( jQuery( this ).is( ':checked' ) ) {
729
- radioshack[ jQuery( this ).attr( 'name' ) ] = jQuery( this ).val();
730
- }
731
- jQuery( document ).data( 'radioshack', radioshack );
732
- }
733
- );
734
- }
735
-
736
- /**
737
- * @summary Detects mouseup and restore all radio buttons that were checked.
738
- *
739
- * @since 1.0.0
740
- */
741
- function aiosp_reclick_radio() {
742
-
743
- // gets the object of checked radio button names and values
744
- var radios = jQuery( document ).data( 'radioshack' );
745
-
746
- // steps thru each object element and trigger a click on it's corresponding radio button
747
- for ( var key in radios ) {
748
- jQuery( 'input[name="' + key + '"]' )
749
- .filter( '[value="' + radios[ key ] + '"]' )
750
- .trigger( 'click' );
751
- }
752
- // unbinds the event listener on .wrap (prevents clicks on inputs from triggering function)
753
- jQuery( '.wrap' ).unbind( 'mouseup' );
754
- }
755
-
756
- /**
757
- * @summary Handdles ajax call.
758
- *
759
- * @since 1.0.0
760
- * @param $action.
761
- * @param $setting.
762
- * @param $options.
763
- * @param $success.
764
- */
765
- function aioseop_handle_ajax_call( action, settings, options, success ) {
766
- var aioseop_sack = new sack( ajaxurl );
767
- aioseop_sack.execute = 1;
768
- aioseop_sack.method = 'POST';
769
- aioseop_sack.setVar( "action", action );
770
- aioseop_sack.setVar( "settings", settings );
771
- aioseop_sack.setVar( "options", options );
772
- if ( typeof success != 'undefined' ) {
773
- aioseop_sack.onCompletion = success;
774
- }
775
- aioseop_sack.setVar(
776
- "nonce-aioseop",
777
- jQuery( 'input[name="nonce-aioseop"]' ).val()
778
- );
779
- aioseop_sack.setVar(
780
- "nonce-aioseop-edit",
781
- jQuery( 'input[name="nonce-aioseop-edit"]' ).val()
782
- );
783
- aioseop_sack.onError = function() {
784
- alert( 'Ajax error on saving.' );
785
- };
786
- aioseop_sack.runAJAX();
787
- }
788
-
789
- /**
790
- * @summary Handdles posts URL.
791
- *
792
- * @since 1.0.0
793
- * @param $action.
794
- * @param $setting.
795
- * @param $options.
796
- * @param $success.
797
- */
798
- function aioseop_handle_post_url( action, settings, options, success_function, use_native) {
799
- jQuery( "div#aiosp_" + settings ).fadeOut(
800
- 'fast', function() {
801
- var loading = '<label class="aioseop_loading aioseop_' + settings + '_loading"></label> Please wait...';
802
- jQuery( "div#aiosp_" + settings ).fadeIn(
803
- 'fast', function() {
804
- if(use_native) {
805
- jQuery.ajax({
806
- url : ajaxurl,
807
- method : 'POST',
808
- dataType: 'json',
809
- data : {
810
- 'action' : action,
811
- 'options' : options,
812
- 'settings' : settings,
813
- 'nonce-aioseop': jQuery( 'input[name="nonce-aioseop"]' ).val(),
814
- 'nonce-aioseop-edit': jQuery( 'input[name="nonce-aioseop-edit"]' ).val()
815
- },
816
- success : function(data){
817
- if(success_function){
818
- success_function(data);
819
- }
820
- }
821
- });
822
- }else{
823
- aioseop_handle_ajax_call( action, settings, options, success_function );
824
- }
825
- }
826
- );
827
- jQuery( "div#aiosp_" + settings ).html( loading );
828
- }
829
- );
830
- }
831
-
832
- /**
833
- * @summary Handles when AIOSEOP is overflowed.
834
- *
835
- * @since 1.0.0
836
- * @param $element.
837
- * @return mixed.
838
- */
839
- function aioseop_is_overflowed( element ) {
840
- return element.scrollHeight > element.clientHeight || element.scrollWidth > element.clientWidth;
841
- }
842
-
843
- /**
844
- * @summary Handles when overflowed border.
845
- *
846
- * @since 1.0.0
847
- * @param $el.
848
- */
849
- function aioseop_overflow_border( el ) {
850
- if ( aioseop_is_overflowed( el ) ) {
851
- el.className = 'aioseop_option_div aioseop_overflowed';
852
- } else {
853
- el.className = 'aioseop_option_div';
854
- }
855
- }
856
-
857
- function aiospinitAll(){
858
- if ( jQuery( '.aiseop-date' ).length > 0 && jQuery( '.aiseop-date' ).eq( 0 ).prop( 'type' ).toLowerCase() === 'text' ) {
859
- jQuery( '.aiseop-date' ).datepicker(
860
- {
861
- dateFormat: "yy-mm-dd"
862
- }
863
- );
864
- }
865
- }
866
-
867
- function aiospinitCounting(){
868
- /* count them characters */
869
- jQuery( '.aioseop_count_chars' ).on('keyup keydown', function(){
870
- countChars( jQuery(this).eq(0), jQuery(this).parent().find('[name="' + jQuery(this).attr('data-length-field') + '"]').eq(0));
871
- });
872
- jQuery( '.aioseop_count_chars' ).each(function(){
873
- countChars( jQuery(this).eq(0), jQuery(this).parent().find('[name="' + jQuery(this).attr('data-length-field') + '"]').eq(0));
874
- });
875
- }
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Controls all the styling of the plugin.
3
+ *
4
+ * AIOSEOP Updates class.
5
+ * @author Michael Torbert.
6
+ * @author Semper Fi Web Design.
7
+ * @copyright https://semperplugins.com
8
+ * @version 1.0.0
9
+ */
10
+ if ( typeof aiosp_data != 'undefined' ) {
11
+
12
+ /**
13
+ * @since 1.0.0
14
+ * @param int $index.
15
+ * @param $value
16
+ */
17
+ jQuery.each(
18
+ aiosp_data, function( index, value ) {
19
+ // aiosp_data[index] = value.json.replace(/&quot;/g, '"');
20
+ // aiosp_data[index] = jQuery.parseJSON( value );
21
+ if ( index == 0 ) {
22
+ if ( typeof value.condshow == 'undefined' ) {
23
+ aiosp_data[ index ].condshow = [];
24
+ }
25
+ } else {
26
+ if ( typeof value.condshow != 'undefined' ) {
27
+ aiosp_data[ 0 ].condshow =
28
+ jQuery.merge( aiosp_data[0].condshow, value.condshow );
29
+ }
30
+ }
31
+ }
32
+ );
33
+ aiosp_data = aiosp_data[0];
34
+ }
35
+
36
+ /**
37
+ * @summary Changes visibility.
38
+ *
39
+ * @since 1.0.0
40
+ * @param int $id.
41
+ */
42
+ function toggleVisibility( id ) {
43
+ var e = document.getElementById( id );
44
+ if ( e.style.display == 'block' ) {
45
+ e.style.display = 'none';
46
+ } else {
47
+ e.style.display = 'block';
48
+ }
49
+ }
50
+
51
+ /**
52
+ * @summary Counts characters.
53
+ *
54
+ * @since 1.0.0
55
+ * @param Object $field.
56
+ * @param Object $cntfield.
57
+ * @return Mixed.
58
+ */
59
+ function countChars( field, cntfield ) {
60
+ var extra = 0;
61
+ var field_size;
62
+ if ( ( field.attr('name') == 'aiosp_title' )
63
+ && ( typeof aiosp_title_extra !== 'undefined' ) ) {
64
+ extra = aiosp_title_extra;
65
+ }
66
+ cntfield.val(field.val().length + extra);
67
+ if ( typeof field.attr('size') != 'undefined' ) {
68
+ field_size = field.attr('size');
69
+ } else {
70
+ field_size = field.attr('rows') * field.attr('cols');
71
+ }
72
+ field_size = parseInt(field_size, 10);
73
+ if ( field_size < 10 ) {
74
+ return;
75
+ }
76
+ if ( cntfield.val() > field_size ) {
77
+ cntfield.removeClass().addClass('aioseop_count_ugly');
78
+ } else if ( ( 'aiosp_title' === field.attr('name' ) ) || ( 'aiosp_home_title' === field.attr('name') ) ) {
79
+ if ( cntfield.val() > ( field_size - 6 ) ) {
80
+ cntfield.removeClass().addClass('aioseop_count_bad');
81
+ } else {
82
+ cntfield.removeClass().addClass('aioseop_count_good');
83
+ }
84
+ } else {
85
+ if ( cntfield.val() > ( field_size - 10 ) ) {
86
+ cntfield.removeClass().addClass('aioseop_count_bad');
87
+ } else {
88
+ cntfield.removeClass().addClass('aioseop_count_good');
89
+ }
90
+ }
91
+ }
92
+
93
+ /**
94
+ * @summary Returns the fields value.
95
+ *
96
+ * @since 1.0.0
97
+ * @param String $field.
98
+ * @return Mixed.
99
+ */
100
+ function aioseop_get_field_value( field ) {
101
+ if ( field.length == 0 ) {
102
+ return field;
103
+ }
104
+ cur = jQuery( '[name=' + field + ']' );
105
+ if ( cur.length == 0 ) {
106
+ return field;
107
+ }
108
+ type = cur.attr( 'type' );
109
+ if ( type == "checkbox" || type == "radio" ) {
110
+ cur = jQuery( 'input[name=' + field + ']:checked' );
111
+ }
112
+ return cur.val();
113
+ }
114
+
115
+ /**
116
+ * @summary Returns the fields value.
117
+ *
118
+ * @since 1.0.0
119
+ * @param String $field.
120
+ * @return Mixed.
121
+ */
122
+ function aioseop_get_field_values( field ) {
123
+ arr = [];
124
+ cur = jQuery( '[name=' + field + ']' );
125
+ if ( cur.length == 0 ) {
126
+ return field;
127
+ }
128
+ type = cur.attr( 'type' );
129
+ if ( type == "checkbox" || type == "radio" ) {
130
+ jQuery( 'input[name=' + field + ']:checked' ).each(
131
+ function() {
132
+ arr.push( jQuery( this ).val() );
133
+ }
134
+ );
135
+ }
136
+ if ( arr.length <= 0 ) {
137
+ arr.push( cur.val() );
138
+ }
139
+ return arr;
140
+ }
141
+
142
+ /**
143
+ * @summary Evaluates condshow logic.
144
+ *
145
+ * @since 1.0.0
146
+ * @param String $statement.
147
+ * @return Mixed.
148
+ */
149
+ function aioseop_eval_condshow_logic( statement ) {
150
+ var lhs, rhs;
151
+ if ( ( typeof statement ) == 'object' ) {
152
+ lhs = statement.lhs;
153
+ rhs = statement.rhs;
154
+ if ( lhs !== null && ( ( typeof lhs ) == 'object' ) ) {
155
+ lhs = aioseop_eval_condshow_logic( lhs );
156
+ }
157
+ if ( rhs !== null && ( typeof rhs ) == 'object' ) {
158
+ rhs = aioseop_eval_condshow_logic( rhs );
159
+ }
160
+ lhs = aioseop_get_field_value( lhs );
161
+ rhs = aioseop_get_field_value( rhs );
162
+ switch ( statement.op ) {
163
+ case 'NOT':
164
+ return ( ! lhs );
165
+ case 'AND':
166
+ return ( lhs && rhs );
167
+ case 'OR' :
168
+ return ( lhs || rhs );
169
+ case '==' :
170
+ return ( lhs == rhs );
171
+ case '!=' :
172
+ return ( lhs != rhs );
173
+ default :
174
+ return null;
175
+ }
176
+ }
177
+ return statement;
178
+ }
179
+
180
+ /**
181
+ * @summary Evaluates condshow logic.
182
+ *
183
+ * @since 1.0.0
184
+ * @param String $index.
185
+ * @param $value.
186
+ * @return Mixed.
187
+ */
188
+ function aioseop_do_condshow_match( index, value ) {
189
+ if ( typeof value != 'undefined' ) {
190
+ matches = true;
191
+ jQuery.each(
192
+ value, function(subopt, setting) {
193
+ var statement;
194
+ if ( ( typeof setting ) == 'object' ) {
195
+ statement = aioseop_eval_condshow_logic( setting );
196
+ if ( ! statement ) {
197
+ matches = false;
198
+ }
199
+ } else {
200
+ if ( subopt.match( /\\\[\\\]/ ) ) { // special case for these -- pdb
201
+ cur = aioseop_get_field_values( subopt );
202
+ if ( jQuery.inArray( setting, cur, 0 ) < 0 ) {
203
+ matches = false;
204
+ }
205
+ } else {
206
+ cur = aioseop_get_field_value( subopt );
207
+ if ( cur != setting ) {
208
+ matches = false;
209
+ }
210
+ }
211
+ }
212
+ }
213
+ );
214
+ if ( matches ) {
215
+ jQuery( '#' + index + '_wrapper' ).show();
216
+ } else {
217
+ jQuery( '#' + index + '_wrapper' ).hide();
218
+ }
219
+ return matches;
220
+ }
221
+ return false;
222
+ }
223
+
224
+ /**
225
+ * @summary Adds condshow handlers.
226
+ *
227
+ * @since 1.0.0
228
+ * @param String $index.
229
+ * @param $value.
230
+ */
231
+ function aioseop_add_condshow_handlers( index, value ) {
232
+ if ( typeof value != 'undefined' ) {
233
+ jQuery.each(
234
+ value, function(subopt, setting) {
235
+ jQuery( '[name=' + subopt + ']' ).bind(
236
+ "change keyup", function() {
237
+ aioseop_do_condshow_match( index, value );
238
+ }
239
+ );
240
+ }
241
+ );
242
+ }
243
+ }
244
+
245
+ /**
246
+ * @summary Does condshow.
247
+ *
248
+ * @since 1.0.0
249
+ * @param $condshow.
250
+ */
251
+ function aioseop_do_condshow( condshow ) {
252
+ if ( typeof aiosp_data.condshow != 'undefined' ) {
253
+ jQuery.each(
254
+ aiosp_data.condshow, function( index, value ) {
255
+ aioseop_do_condshow_match( index, value );
256
+ aioseop_add_condshow_handlers( index, value );
257
+ }
258
+ );
259
+ }
260
+ }
261
+
262
+ /**
263
+ * @since 1.0.0
264
+ */
265
+ jQuery( document ).ready(
266
+ function() {
267
+ if ( typeof aiosp_data != 'undefined' ) {
268
+ if ( typeof aiosp_data.condshow != 'undefined' ) {
269
+ aioseop_do_condshow( aiosp_data.condshow );
270
+ }
271
+ }
272
+
273
+ /**
274
+ * Turns on image checker on custom url change.
275
+ * @since 2.3.16
276
+ */
277
+ jQuery( '.aioseop_upload_image_label' ).on(
278
+ 'change', function() {
279
+ this.checker = jQuery( this ).parent().find( '.aioseop_upload_image_checker' );
280
+ if ( this.checker.length > 0 ) {
281
+ this.checker.val( 1 );
282
+ }
283
+ }
284
+ );
285
+
286
+ /**
287
+ * @summary workaround for bug that causes radio inputs to lose settings when meta box is dragged.
288
+ *
289
+ * props to commentluv for this fix
290
+ * @author commentluv.
291
+ * @link https://core.trac.wordpress.org/ticket/16972
292
+ * @since 1.0.0
293
+ */
294
+ jQuery(document).ready(
295
+ function () {
296
+ // listen for drag drop of metaboxes , bind mousedown to .hndle so it only fires when starting to drag
297
+ jQuery('.hndle').mousedown(
298
+ function () {
299
+
300
+ // set live event listener for mouse up on the content .wrap and wait a tick to give the dragged div time to settle before firing the reclick function
301
+ jQuery('.wrap').mouseup(
302
+ function () {
303
+ aiosp_store_radio();
304
+ setTimeout(function () {
305
+ aiosp_reclick_radio();
306
+ }, 50);
307
+ }
308
+ );
309
+ }
310
+ );
311
+ }
312
+ );
313
+
314
+ /**
315
+ * @summary Javascript for using WP media uploader. Indentifies which DOM should use custom uploader plugin.
316
+ *
317
+ * @see http://www.webmaster-source.com/2013/02/06/using-the-wordpress-3-5-media-uploader-in-your-plugin-or-theme/
318
+ * @since ?
319
+ * @since 2.3.11.2 Use WP 3.5 new media uploader
320
+ * @since 2.3.13 Fixed issue #[740](https://github.com/semperfiwebdesign/all-in-one-seo-pack/issues/740)
321
+ *
322
+ */
323
+ jQuery(document).ready(
324
+ function ($) {
325
+ jQuery('.aioseop_upload_image_button').each(
326
+ function () {
327
+ jQuery(this).aioseopImageUploader(
328
+ {
329
+ success: function (url, el) {
330
+ // Update checker
331
+ if (jQuery(el).prev().length > 0) {
332
+ jQuery(el).prev().val(1);
333
+ }
334
+ },
335
+ }
336
+ );
337
+ }
338
+ );
339
+ }
340
+ );
341
+
342
+ jQuery(document).ready(
343
+ function () {
344
+ jQuery("#poststuff .aioseop_radio_type input[type='radio']").on(
345
+ 'click', function () {
346
+ var previousValue = jQuery(this).attr('previousValue');
347
+ var name = jQuery(this).attr('name');
348
+ if (typeof previousValue == 'undefined') {
349
+ if (jQuery(this).prop("checked")) {
350
+ jQuery(this).prop('checked', true);
351
+ jQuery(this).attr('previousValue', 'checked');
352
+ } else {
353
+ jQuery(this).prop('checked', false);
354
+ jQuery(this).attr('previousValue', false);
355
+ }
356
+ return;
357
+ }
358
+ if (previousValue == 'checked') {
359
+ jQuery(this).prop('checked', false);
360
+ jQuery(this).attr('previousValue', false);
361
+ } else {
362
+ jQuery("input[name=" + name + "]:radio")
363
+ .attr('previousValue', false);
364
+ jQuery(this).attr('previousValue', 'checked');
365
+ }
366
+ }
367
+ );
368
+ }
369
+ );
370
+ if ( typeof aiosp_data.pointers != 'undefined' ) {
371
+
372
+ /**
373
+ * @since 1.0.0
374
+ * @param $index.
375
+ * @param $value.
376
+ * @return mixed.
377
+ */
378
+ jQuery.each(
379
+ aiosp_data.pointers, function( index, value ) {
380
+ if ( value != 'undefined' && value.pointer_text != '' ) {
381
+ aioseop_show_pointer( index, value );
382
+ }
383
+ }
384
+ );
385
+ }
386
+
387
+ /**
388
+ * @since 1.0.0
389
+ * @param $e.
390
+ * @return boolean.
391
+ */
392
+ jQuery( ".all-in-one-seo_page_all-in-one-seo-pack-modules-aioseop_feature_manager #aiosp_settings_form .aioseop_settings_left" )
393
+ .delegate(
394
+ "input[name='Submit']", "click", function( e ) {
395
+ e.preventDefault();
396
+ return false;
397
+ }
398
+ );
399
+
400
+ /**
401
+ * @since 1.0.0
402
+ * @param $e.
403
+ * @return boolean.
404
+ */
405
+ jQuery( ".all-in-one-seo_page_all-in-one-seo-pack-modules-aioseop_feature_manager #aiosp_settings_form" )
406
+ .delegate(
407
+ "input[name='Submit']", "click", function( e ) {
408
+ e.preventDefault();
409
+ aioseop_handle_post_url(
410
+ 'aioseop_ajax_save_settings',
411
+ 'ajax_settings_message',
412
+ jQuery( 'form#aiosp_settings_form' ).serialize(),
413
+ function() {
414
+ jQuery( '.wp-has-current-submenu' ).fadeIn(
415
+ 'fast', function() {
416
+ aioseop_handle_ajax_call(
417
+ 'aioseop_ajax_get_menu_links',
418
+ 'ajax_settings_message',
419
+ jQuery.param( {target: '.wp-has-current-submenu > ul'} )
420
+ );
421
+ }
422
+ );
423
+ }
424
+ );
425
+ return false;
426
+ }
427
+ );
428
+
429
+ /**
430
+ * @since 1.0.0
431
+ * @param $e.
432
+ * @return boolean.
433
+ */
434
+ jQuery( ".all-in-one-seo_page_all-in-one-seo-pack-pro-modules-aioseop_feature_manager #aiosp_settings_form .aioseop_settings_left" )
435
+ .delegate(
436
+ "input[name='Submit']", "click", function( e ) {
437
+ e.preventDefault();
438
+ return false;
439
+ }
440
+ );
441
+
442
+ /**
443
+ * @since 1.0.0
444
+ * @param $e.
445
+ * @return boolean.
446
+ */
447
+ jQuery( ".all-in-one-seo_page_all-in-one-seo-pack-pro-modules-aioseop_feature_manager #aiosp_settings_form" )
448
+ .delegate(
449
+ "input[name='Submit']", "click", function( e ) {
450
+ e.preventDefault();
451
+ aioseop_handle_post_url(
452
+ 'aioseop_ajax_save_settings',
453
+ 'ajax_settings_message',
454
+ jQuery( 'form#aiosp_settings_form' ).serialize(),
455
+ function() {
456
+ jQuery( '.wp-has-current-submenu' ).fadeIn(
457
+ 'fast', function() {
458
+ aioseop_handle_ajax_call(
459
+ 'aioseop_ajax_get_menu_links',
460
+ 'ajax_settings_message',
461
+ jQuery.param( {target: '.wp-has-current-submenu > ul'} )
462
+ );
463
+ }
464
+ );
465
+ }
466
+ );
467
+ return false;
468
+ }
469
+ );
470
+
471
+ var selectors =
472
+ "div.aioseop_multicheckbox_type div.aioseop_option_div, #aiosp_sitemap_debug div.aioseop_option_div, #aiosp_performance_status div.aioseop_option_div";
473
+
474
+ /**
475
+ * @since 1.0.0
476
+ * @return boolean.
477
+ */
478
+ jQuery( "div#aiosp_sitemap_addl_pages_metabox" )
479
+ .delegate(
480
+ "input[name='Submit']", "click", function() {
481
+ aioseop_handle_post_url(
482
+ 'aioseop_ajax_save_url',
483
+ 'sitemap_addl_pages',
484
+ jQuery( 'div#aiosp_sitemap_addl_pages_metabox input, div#aiosp_sitemap_addl_pages_metabox select' )
485
+ .serialize()
486
+ );
487
+ return false;
488
+ }
489
+ );
490
+
491
+ /**
492
+ * @since 1.0.0
493
+ * @return boolean.
494
+ */
495
+ jQuery( "div#aiosp_video_sitemap_addl_pages_metabox" )
496
+ .delegate(
497
+ "input[name='Submit']", "click", function() {
498
+ aioseop_handle_post_url(
499
+ 'aioseop_ajax_save_url',
500
+ 'video_sitemap_addl_pages',
501
+ jQuery( 'div#aiosp_video_sitemap_addl_pages_metabox input, div#aiosp_video_sitemap_addl_pages_metabox select' )
502
+ .serialize()
503
+ );
504
+ return false;
505
+ }
506
+ );
507
+
508
+ /**
509
+ * @since 1.0.0
510
+ * @param $e.
511
+ * @return boolean.
512
+ */
513
+ jQuery( "div#aiosp_sitemap_addl_pages_metabox" )
514
+ .delegate(
515
+ "a.aiosp_delete_url", "click", function( e ) {
516
+ e.preventDefault();
517
+ aioseop_handle_post_url(
518
+ 'aioseop_ajax_delete_url',
519
+ 'sitemap_addl_pages',
520
+ jQuery( this ).attr( "title" )
521
+ );
522
+ return false;
523
+ }
524
+ );
525
+
526
+ /**
527
+ * @since 1.0.0
528
+ * @param $e.
529
+ * @return boolean.
530
+ */
531
+ jQuery( "div#aiosp_video_sitemap_addl_pages_metabox" )
532
+ .delegate(
533
+ "a.aiosp_delete_url", "click", function( e ) {
534
+ e.preventDefault();
535
+ aioseop_handle_post_url(
536
+ 'aioseop_ajax_delete_url',
537
+ 'video_sitemap_addl_pages',
538
+ jQuery( this ).attr( "title" )
539
+ );
540
+ return false;
541
+ }
542
+ );
543
+
544
+ /**
545
+ * @since 1.0.0
546
+ * @param $e.
547
+ * @return boolean.
548
+ */
549
+ jQuery( "div#aiosp_opengraph_scan_header" )
550
+ .delegate(
551
+ "input[name='aiosp_opengraph_scan_header']", "click", function( e ) {
552
+ e.preventDefault();
553
+ aioseop_handle_post_url(
554
+ 'aioseop_ajax_scan_header',
555
+ 'opengraph_scan_header',
556
+ jQuery( 'div#aiosp_opengraph_scan_header' ).serialize()
557
+ );
558
+ return false;
559
+ }
560
+ );
561
+
562
+ /**
563
+ * @since 1.0.0
564
+ */
565
+ 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"]' )
566
+ .click(
567
+ function() {
568
+ jQuery( this )
569
+ .parents( 'div:eq(0)' )
570
+ .find( ':checkbox' )
571
+ .prop( 'checked', this.checked );
572
+ }
573
+ );
574
+
575
+ /**
576
+ * @since 1.0.0
577
+ */
578
+ 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"]' )
579
+ .click(
580
+ function () {
581
+ if ( ! this.checked ) {
582
+ jQuery( this )
583
+ .parents( 'div:eq(0)' )
584
+ .find( 'input[value="all"]:checkbox' )
585
+ .prop( 'checked', this.checked );
586
+ }
587
+ }
588
+ );
589
+
590
+ /**
591
+ * @since 1.0.0
592
+ */
593
+ jQuery( ".aioseop_tab:not(:first)" ).hide();
594
+
595
+ /**
596
+ * @since 1.0.0
597
+ */
598
+ jQuery( ".aioseop_tab:first" ).show();
599
+
600
+ /**
601
+ * @since 1.0.0
602
+ * @return boolean.
603
+ */
604
+ jQuery( "a.aioseop_header_tab" ).click(
605
+ function() {
606
+ var stringref = jQuery( this ).attr( "href" ).split( '#' )[1];
607
+ jQuery( '.aioseop_tab:not(#' + stringref + ')' ).hide( 'slow' );
608
+ jQuery( '.aioseop_tab#' + stringref ).show( 'slow' );
609
+ jQuery( '.aioseop_header_tab[href!="#' + stringref + '"]' ).removeClass( 'active' );
610
+ jQuery( '.aioseop_header_tab[href="#' + stringref + '"]' ).addClass( 'active' );
611
+ return false;
612
+ }
613
+ );
614
+
615
+
616
+ jQuery( "div#aiosp_robots_default_metabox" )
617
+ .delegate(
618
+ "a.aiosp_robots_delete_rule", "click", function( e ) {
619
+ e.preventDefault();
620
+ aioseop_handle_post_url(
621
+ 'aioseop_ajax_delete_rule',
622
+ 'robots_rules',
623
+ jQuery( this ).attr( "data-id" ),
624
+ function() {
625
+ window.location.reload();
626
+ }
627
+ );
628
+ return false;
629
+ }
630
+ );
631
+
632
+ jQuery( "a.aiosp_robots_physical" ).on( 'click', function( e ) {
633
+ e.preventDefault();
634
+ aioseop_handle_post_url(
635
+ 'aioseop_ajax_robots_physical',
636
+ 'robots_physical_import_delete',//'robots_metabox', // No element of the ID existed, and unsure which element its intended for.
637
+ jQuery( this ).attr( "data-action" ),
638
+ function( data ) {
639
+ if ( data.data && data.data.message ) {
640
+ alert( data.data.message );
641
+ }
642
+ window.location.reload();
643
+ },
644
+ true
645
+ );
646
+ return false;
647
+ });
648
+
649
+ aiospinitAll();
650
+ }
651
+ );
652
+
653
+ /**
654
+ * @summary Custom jQuery plugin that enables image uploader in wordpress.
655
+ *
656
+ * @since 2.3.13
657
+ * @since 2.4.14 Added success callback and options.
658
+ * @see http://www.webmaster-source.com/2013/02/06/using-the-wordpress-3-5-media-uploader-in-your-plugin-or-theme/
659
+ *
660
+ * @param object options Plugin options.
661
+ */
662
+ jQuery.fn.aioseopImageUploader = function( options ) {
663
+ // Keep reference to this.
664
+ var self = this;
665
+
666
+ // Options
667
+ self.options = jQuery.extend(
668
+ {
669
+ success: undefined,
670
+ }, options
671
+ );
672
+
673
+ // Set input target when to update image url value
674
+ self.target = jQuery( self ).next();
675
+
676
+ // Uploader per image button
677
+ // * Having only one uploader was causing problems when multiple image buttons where in place
678
+ self.uploader = wp.media(
679
+ {
680
+ title: 'Choose Image',
681
+ button: {
682
+ text: 'Choose Image'
683
+ },
684
+ multiple: false
685
+ }
686
+ );
687
+
688
+ /**
689
+ * Event handler that will be called when an image is selected from media uploader.
690
+ */
691
+ self.onSelect = function() {
692
+ var url = self.uploader.state().get( 'selection' ).first().toJSON().url;
693
+ if ( self.target.length >= 0 ) {
694
+ jQuery( self.target ).val( url );
695
+ }
696
+ if ( self.options.success !== undefined ) {
697
+ self.options.success( url, self );
698
+ }
699
+ };
700
+
701
+ /**
702
+ * Click event handler.
703
+ * @param object e Click event.
704
+ */
705
+ self.onClick = function( e ) {
706
+ e.preventDefault();
707
+ self.uploader.open();
708
+ };
709
+
710
+ // Set uploader select handler
711
+ self.uploader.on( 'select', self.onSelect );
712
+
713
+ // Set click handler
714
+ jQuery( self ).click( self.onClick );
715
+ };
716
+
717
+ /**
718
+ * @summary Stores object of all radio buttons that are checked for entire form.
719
+ *
720
+ * @since 1.0.0
721
+ */
722
+ function aiosp_store_radio() {
723
+ var radioshack = {};
724
+ jQuery( 'input[type="radio"]' ).each(
725
+ function() {
726
+ if ( jQuery( this ).is( ':checked' ) ) {
727
+ radioshack[ jQuery( this ).attr( 'name' ) ] = jQuery( this ).val();
728
+ }
729
+ jQuery( document ).data( 'radioshack', radioshack );
730
+ }
731
+ );
732
+ }
733
+
734
+ /**
735
+ * @summary Detects mouseup and restore all radio buttons that were checked.
736
+ *
737
+ * @since 1.0.0
738
+ */
739
+ function aiosp_reclick_radio() {
740
+
741
+ // gets the object of checked radio button names and values
742
+ var radios = jQuery( document ).data( 'radioshack' );
743
+
744
+ // steps thru each object element and trigger a click on it's corresponding radio button
745
+ for ( var key in radios ) {
746
+ jQuery( 'input[name="' + key + '"]' )
747
+ .filter( '[value="' + radios[ key ] + '"]' )
748
+ .trigger( 'click' );
749
+ }
750
+ // unbinds the event listener on .wrap (prevents clicks on inputs from triggering function)
751
+ jQuery( '.wrap' ).unbind( 'mouseup' );
752
+ }
753
+
754
+ /**
755
+ * @summary Handdles ajax call.
756
+ *
757
+ * @since 1.0.0
758
+ * @param $action.
759
+ * @param $setting.
760
+ * @param $options.
761
+ * @param $success.
762
+ */
763
+ function aioseop_handle_ajax_call( action, settings, options, success ) {
764
+ var aioseop_sack = new sack( ajaxurl );
765
+ aioseop_sack.execute = 1;
766
+ aioseop_sack.method = 'POST';
767
+ aioseop_sack.setVar( "action", action );
768
+ aioseop_sack.setVar( "settings", settings );
769
+ aioseop_sack.setVar( "options", options );
770
+ if ( typeof success != 'undefined' ) {
771
+ aioseop_sack.onCompletion = success;
772
+ }
773
+ aioseop_sack.setVar(
774
+ "nonce-aioseop",
775
+ jQuery( 'input[name="nonce-aioseop"]' ).val()
776
+ );
777
+ aioseop_sack.setVar(
778
+ "nonce-aioseop-edit",
779
+ jQuery( 'input[name="nonce-aioseop-edit"]' ).val()
780
+ );
781
+ aioseop_sack.onError = function() {
782
+ alert( 'Ajax error on saving.' );
783
+ };
784
+ aioseop_sack.runAJAX();
785
+ }
786
+
787
+ /**
788
+ * @summary Handdles posts URL.
789
+ *
790
+ * @since 1.0.0
791
+ * @param $action.
792
+ * @param $setting.
793
+ * @param $options.
794
+ * @param $success.
795
+ */
796
+ function aioseop_handle_post_url( action, settings, options, success_function, use_native) {
797
+ jQuery( "div#aiosp_" + settings ).fadeOut(
798
+ 'fast', function() {
799
+ var loading = '<label class="aioseop_loading aioseop_' + settings + '_loading"></label> Please wait...';
800
+ jQuery( "div#aiosp_" + settings ).fadeIn(
801
+ 'fast', function() {
802
+ if(use_native) {
803
+ jQuery.ajax({
804
+ url : ajaxurl,
805
+ method : 'POST',
806
+ dataType: 'json',
807
+ data : {
808
+ 'action' : action,
809
+ 'options' : options,
810
+ 'settings' : settings,
811
+ 'nonce-aioseop': jQuery( 'input[name="nonce-aioseop"]' ).val(),
812
+ 'nonce-aioseop-edit': jQuery( 'input[name="nonce-aioseop-edit"]' ).val()
813
+ },
814
+ success : function(data){
815
+ if(success_function){
816
+ success_function(data);
817
+ }
818
+ }
819
+ });
820
+ }else{
821
+ aioseop_handle_ajax_call( action, settings, options, success_function );
822
+ }
823
+ }
824
+ );
825
+ jQuery( "div#aiosp_" + settings ).html( loading );
826
+ }
827
+ );
828
+ }
829
+
830
+ /**
831
+ * @summary Handles when AIOSEOP is overflowed.
832
+ *
833
+ * @since 1.0.0
834
+ * @param $element.
835
+ * @return mixed.
836
+ */
837
+ function aioseop_is_overflowed( element ) {
838
+ return element.scrollHeight > element.clientHeight || element.scrollWidth > element.clientWidth;
839
+ }
840
+
841
+ /**
842
+ * @summary Handles when overflowed border.
843
+ *
844
+ * @since 1.0.0
845
+ * @param $el.
846
+ */
847
+ function aioseop_overflow_border( el ) {
848
+ if ( aioseop_is_overflowed( el ) ) {
849
+ el.className = 'aioseop_option_div aioseop_overflowed';
850
+ } else {
851
+ el.className = 'aioseop_option_div';
852
+ }
853
+ }
854
+
855
+ function aiospinitAll(){
856
+ aiospinitSocialMetaInPosts(jQuery);
857
+ aiospinitCalendar();
858
+ aiospinitCounting();
859
+ }
860
+
861
+ function aiospinitCalendar(){
862
+ if ( jQuery( '.aiseop-date' ).length > 0 && jQuery( '.aiseop-date' ).eq( 0 ).prop( 'type' ).toLowerCase() === 'text' ) {
863
+ jQuery( '.aiseop-date' ).datepicker(
864
+ {
865
+ dateFormat: "yy-mm-dd"
866
+ }
867
+ );
868
+ }
869
+ }
870
+
871
+ function aiospinitSocialMetaInPosts($) {
872
+ // clear the radio buttons when the user clicks the upload button.
873
+ $('input[name="aioseop_opengraph_settings_customimg_checker"] ~ .aioseop_upload_image_button').on('click', function(e){
874
+ $('input[name="aioseop_opengraph_settings_image"]').attr('checked', false);
875
+ });
876
+ }
877
+
878
+
879
+ function aiospinitCounting(){
880
+ /* count them characters */
881
+ jQuery( '.aioseop_count_chars' ).on('keyup keydown', function(){
882
+ countChars( jQuery(this).eq(0), jQuery(this).parent().find('[name="' + jQuery(this).attr('data-length-field') + '"]').eq(0));
883
+ });
884
+ jQuery( '.aioseop_count_chars' ).each(function(){
885
+ countChars( jQuery(this).eq(0), jQuery(this).parent().find('[name="' + jQuery(this).attr('data-length-field') + '"]').eq(0));
886
+ });
887
+ }
modules/aioseop_opengraph.php CHANGED
@@ -774,8 +774,12 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Opengraph' ) ) {
774
  );
775
  }
776
 
 
 
 
 
777
  // Add filters
778
- $description = apply_filters( 'aioseop_description', $description );
779
  // Add placholders
780
  $settings[ "{$prefix}title" ]['placeholder'] = apply_filters( 'aioseop_opengraph_placeholder', $title );
781
  $settings[ "{$prefix}desc" ]['placeholder'] = apply_filters( 'aioseop_opengraph_placeholder', $description );
774
  );
775
  }
776
 
777
+ // #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.
778
+ $screen = get_current_screen();
779
+ $ignore_php_version = is_admin() && isset( $screen->id ) && 'post' == $screen->id;
780
+
781
  // Add filters
782
+ $description = apply_filters( 'aioseop_description', $description, false, $ignore_php_version );
783
  // Add placholders
784
  $settings[ "{$prefix}title" ]['placeholder'] = apply_filters( 'aioseop_opengraph_placeholder', $title );
785
  $settings[ "{$prefix}desc" ]['placeholder'] = apply_filters( 'aioseop_opengraph_placeholder', $description );
modules/aioseop_robots.php CHANGED
@@ -104,6 +104,11 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Robots' ) ) {
104
  add_action( 'wp_ajax_aioseop_ajax_delete_rule', array( $this, 'ajax_delete_rule' ) );
105
  add_action( 'wp_ajax_aioseop_ajax_robots_physical', array( $this, 'ajax_action_physical_file' ) );
106
  add_filter( 'robots_txt', array( $this, 'robots_txt' ), 10, 2 );
 
 
 
 
 
107
  }
108
 
109
  function physical_file_check() {
104
  add_action( 'wp_ajax_aioseop_ajax_delete_rule', array( $this, 'ajax_delete_rule' ) );
105
  add_action( 'wp_ajax_aioseop_ajax_robots_physical', array( $this, 'ajax_action_physical_file' ) );
106
  add_filter( 'robots_txt', array( $this, 'robots_txt' ), 10, 2 );
107
+
108
+ // We want to define this because calling admin init in the unit tests causes an error and does not call this method.
109
+ if ( defined( 'AIOSEOP_UNIT_TESTING' ) ) {
110
+ add_action( "aioseop_ut_{$this->prefix}admin_init", array( $this, 'import_default_robots' ) );
111
+ }
112
  }
113
 
114
  function physical_file_check() {
modules/aioseop_sitemap.php CHANGED
@@ -220,7 +220,7 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
220
  ),
221
  'addl_url' => array(
222
  'name' => __( 'Page URL', 'all-in-one-seo-pack' ),
223
- 'type' => 'text',
224
  'label' => 'top',
225
  'save' => false,
226
  ),
@@ -400,7 +400,15 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
400
  return;
401
  }
402
 
403
- $this->do_sitemaps();
 
 
 
 
 
 
 
 
404
  }
405
 
406
  /**
@@ -502,7 +510,7 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
502
  if ( is_object( $v ) ) {
503
  $v = (Array) $v;
504
  }
505
- $buf .= "\t<tr><td><a href='#' title='$k' class='aiosp_delete aiosp_delete_url'></a> {$k}</td><td>{$v['prio']}</td><td>{$v['freq']}</td><td>{$v['mod']}</td></tr>\n";
506
  }
507
  $buf .= "</table>\n";
508
  }
@@ -679,6 +687,8 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
679
  if ( ! empty( $this->options["{$this->prefix}filename"] ) ) {
680
  $filename = $this->options["{$this->prefix}filename"];
681
  $filename = str_replace( '/', '', $filename );
 
 
682
  }
683
  return $filename;
684
  }
@@ -775,6 +785,7 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
775
  if ( isset( $options[ $this->prefix . 'addl_pages' ][0] ) ) {
776
  unset( $options[ $this->prefix . 'addl_pages' ][0] );
777
  }
 
778
  // TODO Refactor all these... use a nonce, dump the incoming _Post into an array and use that.
779
  if ( ! empty( $_POST[ $this->prefix . 'addl_url' ] ) ) {
780
  foreach ( array( 'addl_url', 'addl_prio', 'addl_freq', 'addl_mod' ) as $field ) {
@@ -787,11 +798,14 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
787
  if ( ! is_array( $options[ $this->prefix . 'addl_pages' ] ) ) {
788
  $options[ $this->prefix . 'addl_pages' ] = array();
789
  }
790
- $options[ $this->prefix . 'addl_pages' ][ $_POST[ $this->prefix . 'addl_url' ] ] = array(
791
- 'prio' => $_POST[ $this->prefix . 'addl_prio' ],
792
- 'freq' => $_POST[ $this->prefix . 'addl_freq' ],
793
- 'mod' => $_POST[ $this->prefix . 'addl_mod' ],
794
- );
 
 
 
795
  }
796
 
797
  return $options;
@@ -1332,7 +1346,7 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
1332
  } elseif ( 'addl' === $sitemap_type ) {
1333
  $sitemap_data = $this->get_addl_pages();
1334
  } elseif ( 'archive' === $sitemap_type && $this->option_isset( 'archive' ) ) {
1335
- $sitemap_data = $this->get_archive_prio_data();
1336
  } elseif ( 'author' === $sitemap_type && $this->option_isset( 'author' ) ) {
1337
  $sitemap_data = $this->get_author_prio_data();
1338
  } elseif ( in_array( $sitemap_type, $posttypes ) ) {
@@ -1939,7 +1953,7 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
1939
  }
1940
 
1941
  if ( $this->option_isset( 'archive' ) ) {
1942
- $prio = array_merge( $prio, $this->get_archive_prio_data() );
1943
  }
1944
  if ( $this->option_isset( 'author' ) ) {
1945
  $prio = array_merge( $prio, $this->get_author_prio_data() );
@@ -2347,10 +2361,8 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
2347
  if ( ! empty( $this->options[ $this->prefix . 'addl_pages' ] ) ) {
2348
  $siteurl = parse_url( aioseop_home_url() );
2349
  foreach ( $this->options[ $this->prefix . 'addl_pages' ] as $k => $v ) {
 
2350
  $url = parse_url( $k );
2351
- if ( empty( $url['scheme'] ) ) {
2352
- $url['scheme'] = $siteurl['scheme'];
2353
- }
2354
  if ( empty( $url['host'] ) ) {
2355
  $url['host'] = $siteurl['host'];
2356
  }
@@ -2448,11 +2460,11 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
2448
  * Scores posts based on date and relative comment count, if any.
2449
  *
2450
  * @param $date
2451
- * @param int $stats
2452
  *
2453
  * @return array
2454
  */
2455
- function get_prio_calc( $date, $stats = 0 ) {
2456
  static $cur_time = null;
2457
  if ( null === $cur_time ) {
2458
  $cur_time = time();
@@ -2507,20 +2519,21 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
2507
  }
2508
 
2509
  /**
2510
- * Generate sitemap priority data for archives from an array of posts.
2511
  *
2512
  * @param $posts
2513
  *
2514
  * @return array
2515
  */
2516
- function get_archive_prio_from_posts( $posts ) {
2517
  $archives = array();
2518
  if ( is_array( $posts ) ) {
2519
  foreach ( $posts as $p ) {
2520
  if ( 'post' !== $p->post_type ) {
2521
  continue;
2522
  }
2523
- $date = date( 'Y-m', mysql2date( 'U', $p->post_date ) );
 
2524
  if ( empty( $archives[ $date ] ) ) {
2525
  $archives[ $date ] = $p;
2526
  } else {
@@ -2530,11 +2543,12 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
2530
  }
2531
  }
2532
  }
 
2533
  if ( ! empty( $archives ) ) {
2534
  return $this->get_prio_from_posts(
2535
  $archives, $this->get_default_priority( 'archive', true ), $this->get_default_frequency( 'archive', true ), array(
2536
  $this,
2537
- 'get_archive_link_from_post',
2538
  )
2539
  );
2540
  }
@@ -2543,13 +2557,68 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
2543
  }
2544
 
2545
  /**
2546
- * Return an archive link from a post.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2547
  *
2548
  * @param $post
2549
  *
2550
  * @return bool|string
2551
  */
2552
  function get_archive_link_from_post( $post ) {
 
 
 
 
 
 
 
 
 
 
 
 
2553
  if ( 'post' !== $post->post_type ) {
2554
  return false;
2555
  }
@@ -2648,7 +2717,7 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
2648
  *
2649
  * @return array
2650
  */
2651
- function get_prio_from_posts( $posts, $prio_override = false, $freq_override = false, $linkfunc = 'get_permalink' ) {
2652
  $prio = array();
2653
  $args = array(
2654
  'prio_override' => $prio_override,
@@ -2664,7 +2733,6 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
2664
  foreach ( $posts as $post ) {
2665
  // Determine if we check the post for images.
2666
  $is_single = true;
2667
- $url = '';
2668
  $post->filter = 'sample';
2669
  if ( 'get_permalink' === $linkfunc ) {
2670
  $url = $this->get_permalink( $post );
@@ -2672,6 +2740,12 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
2672
  $url = call_user_func( $linkfunc, $post );
2673
  $is_single = false;
2674
  }
 
 
 
 
 
 
2675
  $date = $post->post_modified_gmt;
2676
  if ( '0000-00-00 00:00:00' === $date ) {
2677
  $date = $post->post_date_gmt;
@@ -2800,24 +2874,37 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
2800
  return $images;
2801
  }
2802
 
2803
- $attached_url = get_the_post_thumbnail_url( $post->ID );
2804
- if ( $attached_url ) {
2805
- $images[] = $attached_url;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2806
  }
2807
 
2808
  $content = '';
2809
  $content = $post->post_content;
2810
 
2811
- // Check images galleries in the content. DO NOT run the_content filter here as it might cause issues with other shortcodes.
2812
- if ( has_shortcode( $content, 'gallery' ) ) {
2813
- $galleries = get_post_galleries( $post, false );
2814
- if ( $galleries ) {
2815
- foreach ( $galleries as $gallery ) {
2816
- $images = array_merge( $images, $gallery['src'] );
2817
- }
2818
- }
2819
- }
2820
 
 
2821
  $this->parse_content_for_images( $content, $images );
2822
 
2823
  if ( $images ) {
@@ -2839,6 +2926,128 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
2839
  return $images;
2840
  }
2841
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2842
  /**
2843
  * Cleans the URL so that its acceptable in the sitemap.
2844
  *
@@ -2931,7 +3140,8 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
2931
  * @param array $images the array of images.
2932
  */
2933
  function parse_content_for_images( $content, &$images ) {
2934
- $total = substr_count( $content, '<img ' ) + substr_count( $content, '<IMG ' );
 
2935
  // no images found.
2936
  if ( 0 === $total ) {
2937
  return;
@@ -3007,16 +3217,19 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
3007
  }
3008
 
3009
  /**
3010
- * Return sitemap data for archives.
3011
  *
3012
  * @return array
3013
  */
3014
- function get_archive_prio_data() {
3015
- $args = array( 'numberposts' => 50000, 'post_type' => 'post' );
 
 
 
3016
  $args = $this->set_post_args( $args );
3017
  $posts = $this->get_all_post_type_data( $args );
3018
 
3019
- return $this->get_archive_prio_from_posts( $posts );
3020
  }
3021
 
3022
  /**
@@ -3060,7 +3273,9 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
3060
  $args = $this->set_post_args( $args );
3061
  $posts = array_merge( $this->get_all_post_type_data( $args ), $posts );
3062
 
3063
- return $this->get_prio_from_posts( $posts, $this->get_default_priority( 'post', true ), $this->get_default_frequency( 'post', true ) );
 
 
3064
  }
3065
 
3066
  /**
220
  ),
221
  'addl_url' => array(
222
  'name' => __( 'Page URL', 'all-in-one-seo-pack' ),
223
+ 'type' => 'url',
224
  'label' => 'top',
225
  'save' => false,
226
  ),
400
  return;
401
  }
402
 
403
+ if ( defined( 'AIOSEOP_UNIT_TESTING' ) ) {
404
+ $this->do_sitemaps();
405
+ } elseif ( ! has_action( 'shutdown', $callback = array( $this, 'do_sitemaps' ) ) ) {
406
+ /**
407
+ * Defer do_sitemaps until after everything is done.
408
+ * And run it only once regardless of posts updated.
409
+ */
410
+ add_action( 'shutdown', $callback );
411
+ }
412
  }
413
 
414
  /**
510
  if ( is_object( $v ) ) {
511
  $v = (Array) $v;
512
  }
513
+ $buf .= "\t<tr><td><a href='#' title='$k' class='dashicons dashicons-trash aiosp_delete_url'></a> {$k}</td><td>{$v['prio']}</td><td>{$v['freq']}</td><td>{$v['mod']}</td></tr>\n";
514
  }
515
  $buf .= "</table>\n";
516
  }
687
  if ( ! empty( $this->options["{$this->prefix}filename"] ) ) {
688
  $filename = $this->options["{$this->prefix}filename"];
689
  $filename = str_replace( '/', '', $filename );
690
+ } else if ( 'aiosp_video_sitemap_' === $this->prefix ) {
691
+ $filename = 'video-sitemap';
692
  }
693
  return $filename;
694
  }
785
  if ( isset( $options[ $this->prefix . 'addl_pages' ][0] ) ) {
786
  unset( $options[ $this->prefix . 'addl_pages' ][0] );
787
  }
788
+
789
  // TODO Refactor all these... use a nonce, dump the incoming _Post into an array and use that.
790
  if ( ! empty( $_POST[ $this->prefix . 'addl_url' ] ) ) {
791
  foreach ( array( 'addl_url', 'addl_prio', 'addl_freq', 'addl_mod' ) as $field ) {
798
  if ( ! is_array( $options[ $this->prefix . 'addl_pages' ] ) ) {
799
  $options[ $this->prefix . 'addl_pages' ] = array();
800
  }
801
+
802
+ if ( aiosp_common::is_url_valid( $_POST[ $this->prefix . 'addl_url' ] ) ) {
803
+ $options[ $this->prefix . 'addl_pages' ][ $_POST[ $this->prefix . 'addl_url' ] ] = array(
804
+ 'prio' => $_POST[ $this->prefix . 'addl_prio' ],
805
+ 'freq' => $_POST[ $this->prefix . 'addl_freq' ],
806
+ 'mod' => $_POST[ $this->prefix . 'addl_mod' ],
807
+ );
808
+ }
809
  }
810
 
811
  return $options;
1346
  } elseif ( 'addl' === $sitemap_type ) {
1347
  $sitemap_data = $this->get_addl_pages();
1348
  } elseif ( 'archive' === $sitemap_type && $this->option_isset( 'archive' ) ) {
1349
+ $sitemap_data = $this->get_date_archive_prio_data();
1350
  } elseif ( 'author' === $sitemap_type && $this->option_isset( 'author' ) ) {
1351
  $sitemap_data = $this->get_author_prio_data();
1352
  } elseif ( in_array( $sitemap_type, $posttypes ) ) {
1953
  }
1954
 
1955
  if ( $this->option_isset( 'archive' ) ) {
1956
+ $prio = array_merge( $prio, $this->get_date_archive_prio_data() );
1957
  }
1958
  if ( $this->option_isset( 'author' ) ) {
1959
  $prio = array_merge( $prio, $this->get_author_prio_data() );
2361
  if ( ! empty( $this->options[ $this->prefix . 'addl_pages' ] ) ) {
2362
  $siteurl = parse_url( aioseop_home_url() );
2363
  foreach ( $this->options[ $this->prefix . 'addl_pages' ] as $k => $v ) {
2364
+ $k = aiosp_common::make_url_valid_smartly( $k );
2365
  $url = parse_url( $k );
 
 
 
2366
  if ( empty( $url['host'] ) ) {
2367
  $url['host'] = $siteurl['host'];
2368
  }
2460
  * Scores posts based on date and relative comment count, if any.
2461
  *
2462
  * @param $date
2463
+ * @param mixed $stats
2464
  *
2465
  * @return array
2466
  */
2467
+ function get_prio_calc( $date, $stats ) {
2468
  static $cur_time = null;
2469
  if ( null === $cur_time ) {
2470
  $cur_time = time();
2519
  }
2520
 
2521
  /**
2522
+ * Generate sitemap priority data for date archives from an array of posts.
2523
  *
2524
  * @param $posts
2525
  *
2526
  * @return array
2527
  */
2528
+ function get_date_archive_prio_from_posts( $posts ) {
2529
  $archives = array();
2530
  if ( is_array( $posts ) ) {
2531
  foreach ( $posts as $p ) {
2532
  if ( 'post' !== $p->post_type ) {
2533
  continue;
2534
  }
2535
+ // add the post type to the date so as to support posts of different post types created on the same date.
2536
+ $date = date( 'Y-m', mysql2date( 'U', $p->post_date ) ) . $p->post_type;
2537
  if ( empty( $archives[ $date ] ) ) {
2538
  $archives[ $date ] = $p;
2539
  } else {
2543
  }
2544
  }
2545
  }
2546
+
2547
  if ( ! empty( $archives ) ) {
2548
  return $this->get_prio_from_posts(
2549
  $archives, $this->get_default_priority( 'archive', true ), $this->get_default_frequency( 'archive', true ), array(
2550
  $this,
2551
+ 'get_date_archive_link_from_post',
2552
  )
2553
  );
2554
  }
2557
  }
2558
 
2559
  /**
2560
+ * Generate sitemap priority data for archives from an array of posts.
2561
+ *
2562
+ * @param $posts
2563
+ *
2564
+ * @return array
2565
+ */
2566
+ private function get_archive_prio_from_posts( $posts ) {
2567
+ $posttypes = array();
2568
+ if ( ! empty( $this->options["{$this->prefix}posttypes"] ) ) {
2569
+ $posttypes = $this->options["{$this->prefix}posttypes"];
2570
+ }
2571
+
2572
+ $types_supporting_archives = get_post_types( array( 'has_archive' => true, '_builtin' => false, ), 'names' );
2573
+ $types = array();
2574
+ foreach ( $posts as $p ) {
2575
+ if ( array_key_exists( $p->post_type, $types ) ) {
2576
+ continue;
2577
+ }
2578
+ $types[ $p->post_type ] = $p;
2579
+ }
2580
+
2581
+ $archives = array();
2582
+ $types = apply_filters( "{$this->prefix}include_post_types_archives", $types );
2583
+ if ( $types ) {
2584
+ foreach ( $types as $post_type => $p ) {
2585
+ if ( ! ( in_array( $post_type, $posttypes ) && in_array( $post_type, $types_supporting_archives ) ) ) {
2586
+ continue;
2587
+ }
2588
+ $archives = array_merge(
2589
+ $archives,
2590
+ $this->get_prio_from_posts(
2591
+ array( $p ), $this->get_default_priority( 'archive', true ), $this->get_default_frequency( 'archive', true ), array(
2592
+ $this,
2593
+ 'get_archive_link_from_post',
2594
+ )
2595
+ )
2596
+ );
2597
+ }
2598
+ }
2599
+ return $archives;
2600
+ }
2601
+
2602
+ /**
2603
+ * Return an archive link for a post.
2604
  *
2605
  * @param $post
2606
  *
2607
  * @return bool|string
2608
  */
2609
  function get_archive_link_from_post( $post ) {
2610
+ return get_post_type_archive_link( $post->post_type );
2611
+ }
2612
+
2613
+ /**
2614
+ * Return a date archive link for a post.
2615
+ *
2616
+ * @param $post
2617
+ *
2618
+ * @return bool|string
2619
+ */
2620
+ function get_date_archive_link_from_post( $post ) {
2621
+ $extra = array();
2622
  if ( 'post' !== $post->post_type ) {
2623
  return false;
2624
  }
2717
  *
2718
  * @return array
2719
  */
2720
+ private function get_prio_from_posts( $posts, $prio_override = false, $freq_override = false, $linkfunc = 'get_permalink' ) {
2721
  $prio = array();
2722
  $args = array(
2723
  'prio_override' => $prio_override,
2733
  foreach ( $posts as $post ) {
2734
  // Determine if we check the post for images.
2735
  $is_single = true;
 
2736
  $post->filter = 'sample';
2737
  if ( 'get_permalink' === $linkfunc ) {
2738
  $url = $this->get_permalink( $post );
2740
  $url = call_user_func( $linkfunc, $post );
2741
  $is_single = false;
2742
  }
2743
+
2744
+ if ( strpos( $url, '__trashed' ) !== false ) {
2745
+ // excluded trashed urls.
2746
+ continue;
2747
+ }
2748
+
2749
  $date = $post->post_modified_gmt;
2750
  if ( '0000-00-00 00:00:00' === $date ) {
2751
  $date = $post->post_date_gmt;
2874
  return $images;
2875
  }
2876
 
2877
+ /**
2878
+ * Static attachment cache, 1 query vs. n posts.
2879
+ */
2880
+ static $post_thumbnails;
2881
+
2882
+ if ( is_null( $post_thumbnails ) || defined( 'AIOSEOP_UNIT_TESTING' ) ) {
2883
+ global $wpdb;
2884
+
2885
+ $post_thumbnails = $wpdb->get_results( "SELECT post_ID, meta_value FROM $wpdb->postmeta WHERE meta_key = '_thumbnail_id'", ARRAY_A );
2886
+
2887
+ if ( $post_thumbnails ) {
2888
+ $post_thumbnails = array_combine(
2889
+ wp_list_pluck( $post_thumbnails, 'post_ID' ),
2890
+ wp_list_pluck( $post_thumbnails, 'meta_value' )
2891
+ );
2892
+ }
2893
+ }
2894
+
2895
+ if ( isset( $post_thumbnails[ $post->ID ] ) ) {
2896
+ $attachment_url = wp_get_attachment_image_url( $post_thumbnails[ $post->ID ], 'post-thumbnail' );
2897
+ if ( $attachment_url ) {
2898
+ $images[] = $attachment_url;
2899
+ }
2900
  }
2901
 
2902
  $content = '';
2903
  $content = $post->post_content;
2904
 
2905
+ $this->get_gallery_images( $post, $images );
 
 
 
 
 
 
 
 
2906
 
2907
+ $content .= $this->get_content_from_galleries( $content );
2908
  $this->parse_content_for_images( $content, $images );
2909
 
2910
  if ( $images ) {
2926
  return $images;
2927
  }
2928
 
2929
+ /**
2930
+ * Fetch images from WP, Jetpack and WooCommerce galleries.
2931
+ *
2932
+ * @param string $post The post.
2933
+ * @param array $images the array of images.
2934
+ *
2935
+ * @since 2.4.2
2936
+ */
2937
+ private function get_gallery_images( $post, &$images ) {
2938
+ if ( false === apply_filters( 'aioseo_include_images_in_wp_gallery', true ) ) {
2939
+ return;
2940
+ }
2941
+
2942
+ // Check images galleries in the content. DO NOT run the_content filter here as it might cause issues with other shortcodes.
2943
+ if ( has_shortcode( $post->post_content, 'gallery' ) ) {
2944
+ // Get the jetpack gallery images.
2945
+ if ( class_exists( 'Jetpack_PostImages' ) ) {
2946
+ $jetpack = Jetpack_PostImages::get_images( $post->ID );
2947
+ if ( $jetpack ) {
2948
+ foreach ( $jetpack as $jetpack_image ) {
2949
+ $images[] = $jetpack_image['src'];
2950
+ }
2951
+ }
2952
+ }
2953
+
2954
+ // Get the default WP gallery images.
2955
+ $galleries = get_post_galleries( $post, false );
2956
+ if ( $galleries ) {
2957
+ foreach ( $galleries as $gallery ) {
2958
+ $images = array_merge( $images, $gallery['src'] );
2959
+ }
2960
+ }
2961
+ }
2962
+
2963
+ // Check WooCommerce product gallery.
2964
+ if ( class_exists( 'WooCommerce' ) ) {
2965
+ $woo_images = get_post_meta( $post->ID, '_product_image_gallery', true );
2966
+ if ( ! empty( $woo_images ) ) {
2967
+ $woo_images = array_filter( explode( ',', $woo_images ) );
2968
+ if ( is_array( $woo_images ) ) {
2969
+ foreach ( $woo_images as $id ) {
2970
+ $images[] = wp_get_attachment_url( $id );
2971
+ }
2972
+ }
2973
+ }
2974
+ }
2975
+
2976
+ $images = array_unique( $images );
2977
+ }
2978
+
2979
+ /**
2980
+ * Parses the content to find out if specified images galleries exist and if they do, parse them for images.
2981
+ * Supports NextGen.
2982
+ *
2983
+ * @param string $content The post content.
2984
+ *
2985
+ * @since 2.4.2
2986
+ *
2987
+ * @return string
2988
+ */
2989
+ private function get_content_from_galleries( $content ) {
2990
+ // Support for NextGen Gallery.
2991
+ static $gallery_types = array( 'ngg_images' );
2992
+ $types = apply_filters( 'aioseop_gallery_shortcodes', $gallery_types );
2993
+
2994
+ $gallery_content = '';
2995
+
2996
+ if ( ! $types ) {
2997
+ return $gallery_content;
2998
+ }
2999
+
3000
+ $found = array();
3001
+ if ( $types ) {
3002
+ foreach ( $types as $type ) {
3003
+ if ( has_shortcode( $content, $type ) ) {
3004
+ $found[] = $type;
3005
+ }
3006
+ }
3007
+ }
3008
+
3009
+ // If none of the shortcodes-of-interest are found, bail.
3010
+ if ( empty( $found ) ) {
3011
+ return $gallery_content;
3012
+ }
3013
+
3014
+ $galleries = array();
3015
+
3016
+ if ( ! preg_match_all( '/' . get_shortcode_regex() . '/s', $content, $matches, PREG_SET_ORDER ) ) {
3017
+ return $gallery_content;
3018
+ }
3019
+
3020
+ // Collect the shortcodes and their attributes.
3021
+ foreach ( $found as $type ) {
3022
+ foreach ( $matches as $shortcode ) {
3023
+ if ( $type === $shortcode[2] ) {
3024
+
3025
+ $attributes = shortcode_parse_atts( $shortcode[3] );
3026
+
3027
+ if ( '' === $attributes ) { // Valid shortcode without any attributes.
3028
+ $attributes = array();
3029
+ }
3030
+
3031
+ $galleries[ $shortcode[2] ] = $attributes;
3032
+ }
3033
+ }
3034
+ }
3035
+
3036
+ // Recreate the shortcodes and then render them to get the HTML content.
3037
+ if ( $galleries ) {
3038
+ foreach ( $galleries as $shortcode => $attributes ) {
3039
+ $code = '[' . $shortcode;
3040
+ foreach ( $attributes as $key => $value ) {
3041
+ $code .= " $key=$value";
3042
+ }
3043
+ $code .= ']';
3044
+ $gallery_content .= do_shortcode( $code );
3045
+ }
3046
+ }
3047
+
3048
+ return $gallery_content;
3049
+ }
3050
+
3051
  /**
3052
  * Cleans the URL so that its acceptable in the sitemap.
3053
  *
3140
  * @param array $images the array of images.
3141
  */
3142
  function parse_content_for_images( $content, &$images ) {
3143
+ // These tags should be WITHOUT trailing space because some plugins such as the nextgen gallery put newlines immediately after <img.
3144
+ $total = substr_count( $content, '<img' ) + substr_count( $content, '<IMG' );
3145
  // no images found.
3146
  if ( 0 === $total ) {
3147
  return;
3217
  }
3218
 
3219
  /**
3220
+ * Return sitemap data for date archives.
3221
  *
3222
  * @return array
3223
  */
3224
+ function get_date_archive_prio_data() {
3225
+ $args = array(
3226
+ 'numberposts' => 50000,
3227
+ 'post_type' => 'post',
3228
+ );
3229
  $args = $this->set_post_args( $args );
3230
  $posts = $this->get_all_post_type_data( $args );
3231
 
3232
+ return $this->get_date_archive_prio_from_posts( $posts );
3233
  }
3234
 
3235
  /**
3273
  $args = $this->set_post_args( $args );
3274
  $posts = array_merge( $this->get_all_post_type_data( $args ), $posts );
3275
 
3276
+ $links = $this->get_prio_from_posts( $posts, $this->get_default_priority( 'post', true ), $this->get_default_frequency( 'post', true ) );
3277
+ $links = array_merge( $links, $this->get_archive_prio_from_posts( $posts ) );
3278
+ return $links;
3279
  }
3280
 
3281
  /**
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=mrtor
4
  Tags: seo, all in one seo, google, twitter, page, image seo, social, search engine optimization, sitemap, WordPress SEO, meta, meta description, xml sitemap, google sitemap, sitemaps, robots meta, yahoo, bing, news sitemaps, multisite, canonical, nofollow, noindex, keywords, description, webmaster tools, google webmaster tools, google analytics
5
  Requires at least: 4.4
6
  Tested up to: 4.9
7
- Stable tag: 2.7.3
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
4
  Tags: seo, all in one seo, google, twitter, page, image seo, social, search engine optimization, sitemap, WordPress SEO, meta, meta description, xml sitemap, google sitemap, sitemaps, robots meta, yahoo, bing, news sitemaps, multisite, canonical, nofollow, noindex, keywords, description, webmaster tools, google webmaster tools, google analytics
5
  Requires at least: 4.4
6
  Tested up to: 4.9
7
+ Stable tag: 2.8
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10