All in One SEO Pack - Version 3.7.0

Version Description

Download this release

Release Info

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

Code changes from version 3.6.2 to 3.7.0

admin/aioseop_module_class.php CHANGED
@@ -457,6 +457,8 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Module' ) ) {
457
  }
458
  }
459
  }
 
 
460
  }
461
  // phpcs:enable
462
  if ( empty( $output ) ) {
@@ -523,7 +525,7 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Module' ) ) {
523
  }
524
 
525
  // @codingStandardsIgnoreStart
526
- return $wpdb->get_col( "SELECT blog_id FROM {$wpdb->blogs} WHERE site_id = {$blog_id} AND site_id != blog_id" );
527
  // @codingStandardsIgnoreEnd
528
  }
529
 
@@ -1025,14 +1027,13 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Module' ) ) {
1025
  if ( ! empty( $_REQUEST['aiosp_importer_exporter_export_choices'] ) ) {
1026
  $exporter_choices = $_REQUEST['aiosp_importer_exporter_export_choices'];
1027
  }
 
 
1028
  if ( ! empty( $exporter_choices ) && is_array( $exporter_choices ) ) {
1029
  foreach ( $exporter_choices as $ex ) {
1030
  if ( 1 == $ex ) {
1031
  $general_settings = true;
1032
  }
1033
- if ( 2 == $ex && isset( $_REQUEST['aiosp_importer_exporter_export_post_types'] ) ) {
1034
- $post_types = $_REQUEST['aiosp_importer_exporter_export_post_types'];
1035
- }
1036
  }
1037
  }
1038
 
@@ -1098,6 +1099,7 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Module' ) ) {
1098
  * @return bool
1099
  */
1100
  function output_error( $error ) {
 
1101
  echo "<div class='aioseop_module error'>$error</div>";
1102
 
1103
  return false;
@@ -2341,9 +2343,7 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Module' ) ) {
2341
  $prefix = $this->get_prefix( $k );
2342
  $options = apply_filters( $prefix . 'filter_metabox_options', $options, $k, $post_id );
2343
  foreach ( $options as $option ) {
2344
- if ( is_string( $option ) ) {
2345
- $option = esc_html( $option );
2346
- }
2347
  }
2348
  update_post_meta( $post_id, '_' . $prefix . $k, $options );
2349
  }
@@ -2591,6 +2591,9 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Module' ) ) {
2591
  wp_enqueue_script( 'jquery-ui-datepicker' );
2592
  // fall through.
2593
  default:
 
 
 
2594
  $buf .= "<input name='" . esc_attr( $name ) . "' type='" . esc_attr( $options['type'] ) . "' " . wp_kses( $attr, wp_kses_allowed_html( 'data' ) ) . " value='" . htmlspecialchars_decode( $value ) . "' autocomplete='aioseop-" . time() . "'>\n";
2595
  }
2596
 
@@ -2758,7 +2761,7 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Module' ) ) {
2758
  $opt = $opts['default'];
2759
  }
2760
 
2761
- $args = array(
2762
  'name' => $name,
2763
  'options' => $opts,
2764
  'attr' => $attr,
@@ -2766,13 +2769,13 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Module' ) ) {
2766
  'prefix' => $prefix,
2767
  );
2768
  if ( ! empty( $opts['nowrap'] ) ) {
2769
- echo $this->get_option_html( $args );
2770
  } else {
2771
  if ( $container ) {
2772
  echo $container;
2773
  $container = '';
2774
  }
2775
- echo $this->get_option_row( $name, $opts, $args );
2776
  }
2777
  }
2778
  if ( ! $container ) {
457
  }
458
  }
459
  }
460
+ default:
461
+ return array();
462
  }
463
  // phpcs:enable
464
  if ( empty( $output ) ) {
525
  }
526
 
527
  // @codingStandardsIgnoreStart
528
+ return $wpdb->get_col( $wpdb->prepare( "SELECT blog_id FROM {$wpdb->blogs} WHERE site_id = %d AND site_id != blog_id", $blog_id ) );
529
  // @codingStandardsIgnoreEnd
530
  }
531
 
1027
  if ( ! empty( $_REQUEST['aiosp_importer_exporter_export_choices'] ) ) {
1028
  $exporter_choices = $_REQUEST['aiosp_importer_exporter_export_choices'];
1029
  }
1030
+
1031
+ $post_types = isset( $_REQUEST['aiosp_importer_exporter_export_post_types'] ) ? $_REQUEST['aiosp_importer_exporter_export_post_types'] : array();
1032
  if ( ! empty( $exporter_choices ) && is_array( $exporter_choices ) ) {
1033
  foreach ( $exporter_choices as $ex ) {
1034
  if ( 1 == $ex ) {
1035
  $general_settings = true;
1036
  }
 
 
 
1037
  }
1038
  }
1039
 
1099
  * @return bool
1100
  */
1101
  function output_error( $error ) {
1102
+ $error = esc_html( $error );
1103
  echo "<div class='aioseop_module error'>$error</div>";
1104
 
1105
  return false;
2343
  $prefix = $this->get_prefix( $k );
2344
  $options = apply_filters( $prefix . 'filter_metabox_options', $options, $k, $post_id );
2345
  foreach ( $options as $option ) {
2346
+ $option = aioseop_sanitize( $option );
 
 
2347
  }
2348
  update_post_meta( $post_id, '_' . $prefix . $k, $options );
2349
  }
2591
  wp_enqueue_script( 'jquery-ui-datepicker' );
2592
  // fall through.
2593
  default:
2594
+ if ( 'number' === $options['type'] ) {
2595
+ $value = intval( $value );
2596
+ }
2597
  $buf .= "<input name='" . esc_attr( $name ) . "' type='" . esc_attr( $options['type'] ) . "' " . wp_kses( $attr, wp_kses_allowed_html( 'data' ) ) . " value='" . htmlspecialchars_decode( $value ) . "' autocomplete='aioseop-" . time() . "'>\n";
2598
  }
2599
 
2761
  $opt = $opts['default'];
2762
  }
2763
 
2764
+ $newArgs = array(
2765
  'name' => $name,
2766
  'options' => $opts,
2767
  'attr' => $attr,
2769
  'prefix' => $prefix,
2770
  );
2771
  if ( ! empty( $opts['nowrap'] ) ) {
2772
+ echo $this->get_option_html( $newArgs );
2773
  } else {
2774
  if ( $container ) {
2775
  echo $container;
2776
  $container = '';
2777
  }
2778
+ echo $this->get_option_row( $name, $opts, $newArgs );
2779
  }
2780
  }
2781
  if ( ! $container ) {
admin/aioseop_module_manager.php CHANGED
@@ -165,7 +165,8 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Module_Manager' ) ) {
165
  $classname = 'All_in_One_SEO_Pack_' . strtr( ucwords( strtr( $mod, '_', ' ' ) ), ' ', '_' );
166
  $classname = apply_filters( "aioseop_class_$mod", $classname );
167
  $module_class = new $classname( $args );
168
- $GLOBALS[ $ref ] = $module_class;
 
169
  $this->modules[ $mod ] = $module_class;
170
  if ( is_user_logged_in() && is_admin_bar_showing() && current_user_can( 'aiosp_manage_seo' ) ) {
171
  add_action(
165
  $classname = 'All_in_One_SEO_Pack_' . strtr( ucwords( strtr( $mod, '_', ' ' ) ), ' ', '_' );
166
  $classname = apply_filters( "aioseop_class_$mod", $classname );
167
  $module_class = new $classname( $args );
168
+ global $$ref;
169
+ $$ref = $module_class;
170
  $this->modules[ $mod ] = $module_class;
171
  if ( is_user_logged_in() && is_admin_bar_showing() && current_user_can( 'aiosp_manage_seo' ) ) {
172
  add_action(
admin/class-aioseop-helper.php CHANGED
@@ -83,6 +83,8 @@ class AIOSEOP_Helper {
83
  case 'All_in_One_SEO_Pack_Image_Seo':
84
  $this->help_text = $this->help_text_image_seo();
85
  break;
 
 
86
  }
87
 
88
  /**
@@ -116,6 +118,7 @@ class AIOSEOP_Helper {
116
  'aiosp_schema_markup' => __( 'This enables Schema.org structured data markup for rich snippets in search results.', 'all-in-one-seo-pack' ),
117
  /* translators: %s is a placeholder, which means that it should not be translated. It will be replaced with the name of the plugin, All in One SEO Pack. */
118
  'aiosp_do_log' => sprintf( __( 'Check this and %s will create a log of important events (all-in-one-seo-pack.log) in the wp-content directory which might help debugging. Make sure this directory is writable.', 'all-in-one-seo-pack' ), AIOSEOP_PLUGIN_NAME ),
 
119
 
120
  // Home Page Settings.
121
  'aiosp_home_title' => __( 'As the name implies, this will be the Meta Title of your homepage. This is independent of any other option. If not set, the default Site Title (found in WordPress under Settings, General, Site Title) will be used.', 'all-in-one-seo-pack' ),
@@ -449,6 +452,49 @@ class AIOSEOP_Helper {
449
  'aiosp_front_meta_tags' => __( 'What you enter here will be copied verbatim to the header of the front page if you have set a static page in Settings, Reading, Front Page Displays. You can enter whatever additional headers you want here, even references to stylesheets. This will fall back to using Additional Page Headers if you have them set and nothing is entered here.', 'all-in-one-seo-pack' ),
450
  'aiosp_home_meta_tags' => __( 'What you enter here will be copied verbatim to the header of the home page if you have Front page displays your latest posts selected in Settings, Reading.  It will also be copied verbatim to the header on the Posts page if you have one set in Settings, Reading. You can enter whatever additional headers you want here, even references to stylesheets.', 'all-in-one-seo-pack' ),
451
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
452
  // Keyword Settings.
453
  'aiosp_togglekeywords' => __( 'This option allows you to toggle the use of Meta Keywords throughout the whole of the site.', 'all-in-one-seo-pack' ),
454
  'aiosp_use_categories' => __( 'Check this if you want your categories for a given post used as the Meta Keywords for this post (in addition to any keywords you specify on the Edit Post screen).', 'all-in-one-seo-pack' ),
@@ -539,6 +585,7 @@ class AIOSEOP_Helper {
539
  'aiosp_use_original_title' => 'https://semperplugins.com/documentation/general-settings/#use-original-title',
540
  'aiosp_schema_markup' => 'https://semperplugins.com/documentation/schema-settings/#use-schema-markup',
541
  'aiosp_do_log' => 'https://semperplugins.com/documentation/general-settings/#log-important-events',
 
542
 
543
  // Home Page Settings.
544
  'aiosp_home_title' => 'https://semperplugins.com/documentation/home-page-settings/#home-title',
@@ -623,6 +670,10 @@ class AIOSEOP_Helper {
623
  'aiosp_front_meta_tags' => 'https://semperplugins.com/documentation/all-in-one-seo-pack-advanced-settings/#additional-front-page-headers',
624
  'aiosp_home_meta_tags' => 'https://semperplugins.com/documentation/all-in-one-seo-pack-advanced-settings/#additional-blog-page-headers',
625
 
 
 
 
 
626
  // Keyword Settings.
627
  'aiosp_togglekeywords' => 'https://semperplugins.com/documentation/keyword-settings/#use-keywords',
628
  'aiosp_use_categories' => 'https://semperplugins.com/documentation/keyword-settings/#use-categories-for-meta-keywords',
@@ -717,7 +768,7 @@ class AIOSEOP_Helper {
717
  'aiosp_sitemap_posttypes_news' => __( 'Select which Post Types should appear in your Google News sitemap. This sitemap only includes posts that were published in the last 48 hours.', 'all-in-one-seo-pack' ),
718
  'aiosp_sitemap_rss_sitemap' => __( 'Generate an RSS sitemap in addition to the regular XML Sitemap.', 'all-in-one-seo-pack' ),
719
  'aiosp_sitemap_publication_name' => __( 'The publication name for your Google News sitemap. It must exactly match the name as it appears on your articles on news.google.com, except for anything in parentheses.', 'all-in-one-seo-pack' ),
720
-
721
  // Priorities.
722
  'aiosp_sitemap_prio_homepage' => sprintf( __( 'Manually set the %1$s of your %2$s.', 'all-in-one-seo-pack' ), __( 'priority', 'all-in-one-seo-pack' ), __( 'Homepage', 'all-in-one-seo-pack' ) ),
723
  'aiosp_sitemap_prio_post' => sprintf( __( 'Manually set the %1$s of your %2$s.', 'all-in-one-seo-pack' ), __( 'priority', 'all-in-one-seo-pack' ), __( 'Posts', 'all-in-one-seo-pack' ) ),
83
  case 'All_in_One_SEO_Pack_Image_Seo':
84
  $this->help_text = $this->help_text_image_seo();
85
  break;
86
+ default:
87
+ break;
88
  }
89
 
90
  /**
118
  'aiosp_schema_markup' => __( 'This enables Schema.org structured data markup for rich snippets in search results.', 'all-in-one-seo-pack' ),
119
  /* translators: %s is a placeholder, which means that it should not be translated. It will be replaced with the name of the plugin, All in One SEO Pack. */
120
  'aiosp_do_log' => sprintf( __( 'Check this and %s will create a log of important events (all-in-one-seo-pack.log) in the wp-content directory which might help debugging. Make sure this directory is writable.', 'all-in-one-seo-pack' ), AIOSEOP_PLUGIN_NAME ),
121
+ 'aiosp_usage_tracking' => __( 'By allowing us to track usage data we can better help you because we know with which WordPress configurations, themes and plugins we should test.', 'all-in-one-seo-pack' ),
122
 
123
  // Home Page Settings.
124
  'aiosp_home_title' => __( 'As the name implies, this will be the Meta Title of your homepage. This is independent of any other option. If not set, the default Site Title (found in WordPress under Settings, General, Site Title) will be used.', 'all-in-one-seo-pack' ),
452
  'aiosp_front_meta_tags' => __( 'What you enter here will be copied verbatim to the header of the front page if you have set a static page in Settings, Reading, Front Page Displays. You can enter whatever additional headers you want here, even references to stylesheets. This will fall back to using Additional Page Headers if you have them set and nothing is entered here.', 'all-in-one-seo-pack' ),
453
  'aiosp_home_meta_tags' => __( 'What you enter here will be copied verbatim to the header of the home page if you have Front page displays your latest posts selected in Settings, Reading.  It will also be copied verbatim to the header on the Posts page if you have one set in Settings, Reading. You can enter whatever additional headers you want here, even references to stylesheets.', 'all-in-one-seo-pack' ),
454
 
455
+ // RSS Content Settings.
456
+ 'aiosp_rss_content_before' =>
457
+ __( "This feature allows you to automatically add content <u>before</u> each post in your site's RSS feed.", 'all-in-one-seo-pack' ) . '<br /><br />' .
458
+ __( 'The following macros are supported:', 'all-in-one-seo-pack' ) .
459
+ '<dl>' .
460
+ '<dt>%site_title%</dt>' .
461
+ '<dd>' . __( 'Your site title', 'all-in-one-seo-pack' ) . '</dd>' .
462
+ '<dt>%site_link%</dt>' .
463
+ '<dd>' . __( 'A link to your homepage with your site title as anchor text', 'all-in-one-seo-pack' ) . '</dd>' .
464
+ '<dt>%site_link_raw%</dt>' .
465
+ '<dd>' . __( 'A link to your homepage with the link as anchor text.', 'all-in-one-seo-pack' ) . '</dd>' .
466
+ '<dt>%post_title%</dt>' .
467
+ '<dd>' . sprintf( __( 'The original title of the %s', 'all-in-one-seo-pack' ), __( 'Post', 'all-in-one-seo-pack' ) ) . '</dd>' .
468
+ '<dt>%post_link%</dt>' .
469
+ '<dd>' . __( 'A link to the post with the post name as anchor text', 'all-in-one-seo-pack' ) . '</dd>' .
470
+ '<dt>%post_link_raw%</dt>' .
471
+ '<dd>' . __( 'A link to the post with the link as anchor text', 'all-in-one-seo-pack' ) . '</dd>' .
472
+ '<dt>%author_name%</dt>' .
473
+ '<dd>' . __( 'The display name of the post author', 'all-in-one-seo-pack' ) . '</dd>' .
474
+ '<dt>%author_link%</dt>' .
475
+ '<dd>' . __( 'A link to the author archive of the post author with the author name as anchor text', 'all-in-one-seo-pack' ) . '</dd>' .
476
+ '</dl>',
477
+ 'aiosp_rss_content_after' =>
478
+ __( "This feature allows you to automatically add content <u>after</u> each post in your site's RSS feed.", 'all-in-one-seo-pack' ) . '<br /><br />' .
479
+ __( 'The following macros are supported:', 'all-in-one-seo-pack' ) .
480
+ '<dl>' .
481
+ '<dt>%site_title%</dt>' .
482
+ '<dd>' . __( 'Your site title', 'all-in-one-seo-pack' ) . '</dd>' .
483
+ '<dt>%site_link%</dt>' .
484
+ '<dd>' . __( 'A link to your homepage with your site title as anchor text', 'all-in-one-seo-pack' ) . '</dd>' .
485
+ '<dt>%site_link_raw%</dt>' .
486
+ '<dd>' . __( 'A link to your homepage with the link as anchor text.', 'all-in-one-seo-pack' ) . '</dd>' .
487
+ '<dt>%post_title%</dt>' .
488
+ '<dd>' . sprintf( __( 'The original title of the %s', 'all-in-one-seo-pack' ), __( 'Post', 'all-in-one-seo-pack' ) ) . '</dd>' .
489
+ '<dt>%post_link%</dt>' .
490
+ '<dd>' . __( 'A link to the post with the post name as anchor text', 'all-in-one-seo-pack' ) . '</dd>' .
491
+ '<dt>%post_link_raw%</dt>' .
492
+ '<dd>' . __( 'A link to the post with the link as anchor text', 'all-in-one-seo-pack' ) . '</dd>' .
493
+ '<dt>%author_name%</dt>' .
494
+ '<dd>' . __( 'The display name of the post author', 'all-in-one-seo-pack' ) . '</dd>' .
495
+ '<dt>%author_link%</dt>' .
496
+ '<dd>' . __( 'A link to the author archive of the post author with the author name as anchor text', 'all-in-one-seo-pack' ) . '</dd>' .
497
+ '</dl>',
498
  // Keyword Settings.
499
  'aiosp_togglekeywords' => __( 'This option allows you to toggle the use of Meta Keywords throughout the whole of the site.', 'all-in-one-seo-pack' ),
500
  'aiosp_use_categories' => __( 'Check this if you want your categories for a given post used as the Meta Keywords for this post (in addition to any keywords you specify on the Edit Post screen).', 'all-in-one-seo-pack' ),
585
  'aiosp_use_original_title' => 'https://semperplugins.com/documentation/general-settings/#use-original-title',
586
  'aiosp_schema_markup' => 'https://semperplugins.com/documentation/schema-settings/#use-schema-markup',
587
  'aiosp_do_log' => 'https://semperplugins.com/documentation/general-settings/#log-important-events',
588
+ 'aiosp_usage_tracking' => 'https://semperplugins.com/documentation/usage-tracking/',
589
 
590
  // Home Page Settings.
591
  'aiosp_home_title' => 'https://semperplugins.com/documentation/home-page-settings/#home-title',
670
  'aiosp_front_meta_tags' => 'https://semperplugins.com/documentation/all-in-one-seo-pack-advanced-settings/#additional-front-page-headers',
671
  'aiosp_home_meta_tags' => 'https://semperplugins.com/documentation/all-in-one-seo-pack-advanced-settings/#additional-blog-page-headers',
672
 
673
+ // RSS Content Settings.
674
+ 'aiosp_rss_content_before' => 'https://semperplugins.com/documentation/rss-content-settings/',
675
+ 'aiosp_rss_content_after' => 'https://semperplugins.com/documentation/rss-content-settings/',
676
+
677
  // Keyword Settings.
678
  'aiosp_togglekeywords' => 'https://semperplugins.com/documentation/keyword-settings/#use-keywords',
679
  'aiosp_use_categories' => 'https://semperplugins.com/documentation/keyword-settings/#use-categories-for-meta-keywords',
768
  'aiosp_sitemap_posttypes_news' => __( 'Select which Post Types should appear in your Google News sitemap. This sitemap only includes posts that were published in the last 48 hours.', 'all-in-one-seo-pack' ),
769
  'aiosp_sitemap_rss_sitemap' => __( 'Generate an RSS sitemap in addition to the regular XML Sitemap.', 'all-in-one-seo-pack' ),
770
  'aiosp_sitemap_publication_name' => __( 'The publication name for your Google News sitemap. It must exactly match the name as it appears on your articles on news.google.com, except for anything in parentheses.', 'all-in-one-seo-pack' ),
771
+
772
  // Priorities.
773
  'aiosp_sitemap_prio_homepage' => sprintf( __( 'Manually set the %1$s of your %2$s.', 'all-in-one-seo-pack' ), __( 'priority', 'all-in-one-seo-pack' ), __( 'Homepage', 'all-in-one-seo-pack' ) ),
774
  'aiosp_sitemap_prio_post' => sprintf( __( 'Manually set the %1$s of your %2$s.', 'all-in-one-seo-pack' ), __( 'priority', 'all-in-one-seo-pack' ), __( 'Posts', 'all-in-one-seo-pack' ) ),
admin/class-aioseop-usage.php ADDED
@@ -0,0 +1,215 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * AIOSEOP Usage Tracking Class
4
+ *
5
+ * @package All-in-One-SEO-Pack
6
+ * @since 3.7
7
+ */
8
+
9
+ /**
10
+ * All in One SEO Usage Tracking
11
+ *
12
+ * @since 3.7
13
+ */
14
+ class AIOSEOP_Usage {
15
+ /**
16
+ * Class Constructor.
17
+ *
18
+ * @since 3.7
19
+ */
20
+ public function __construct() {
21
+ add_action( 'init', array( $this, 'schedule_send' ) );
22
+ add_filter( 'cron_schedules', array( $this, 'add_schedules' ) );
23
+ add_action( 'aioseop_usage_tracking_cron', array( $this, 'send_checkin' ) );
24
+ }
25
+
26
+ /**
27
+ * Get the data.
28
+ *
29
+ * @since 3.7
30
+ *
31
+ * @return array An array of data.
32
+ */
33
+ private function get_data() {
34
+ global $wpdb, $aioseop_options;
35
+ $themeData = wp_get_theme();
36
+
37
+ return array(
38
+ // Generic data (environment).
39
+ 'url' => home_url(),
40
+ 'php_version' => PHP_VERSION,
41
+ 'wp_version' => get_bloginfo( 'version' ),
42
+ 'mysql_version' => $wpdb->db_version(),
43
+ 'server_version' => isset( $_SERVER['SERVER_SOFTWARE'] ) ? sanitize_text_field( wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) ) : '',
44
+ 'is_ssl' => is_ssl(),
45
+ 'is_multisite' => is_multisite(),
46
+ 'sites_count' => function_exists( 'get_blog_count' ) ? (int) get_blog_count() : 1,
47
+ 'active_plugins' => $this->get_active_plugins(),
48
+ 'theme_name' => $themeData->name,
49
+ 'theme_version' => $themeData->version,
50
+ 'user_count' => function_exists( 'get_user_count' ) ? get_user_count() : null,
51
+ 'locale' => get_locale(),
52
+ 'timezone_offset' => date('P'),
53
+ 'email' => get_bloginfo( 'admin_email' ),
54
+ // AIOSEO specific data.
55
+ 'aioseo_version' => AIOSEOP_VERSION,
56
+ 'aioseo_license_key' => AIOSEOPPRO && isset( $aioseop_options['aiosp_license_key'] ) ? $aioseop_options['aiosp_license_key'] : null,
57
+ 'aioseo_license_type' => AIOSEOPPRO && isset( $aioseop_options['plan'] ) ? $aioseop_options['plan'] : null,
58
+ 'aioseo_is_pro' => AIOSEOPPRO,
59
+ 'aioseo_settings' => $aioseop_options,
60
+ 'aioseo_usagetracking' => get_option( 'aioseop_usage_tracking_config', false ),
61
+ );
62
+ }
63
+
64
+ /**
65
+ * Get the active plugins.
66
+ *
67
+ * @since 3.7
68
+ *
69
+ * @return array An array of active plugins.
70
+ */
71
+ private function get_active_plugins() {
72
+ if ( ! function_exists( 'get_plugins' ) ) {
73
+ include ABSPATH . '/wp-admin/includes/plugin.php';
74
+ }
75
+ $active = get_option( 'active_plugins', array() );
76
+ $plugins = array_intersect_key( get_plugins(), array_flip( $active ) );
77
+
78
+ return array_map( array( $this, 'getPluginVersion' ), $plugins );
79
+ }
80
+
81
+ /**
82
+ * Get the plugin version.
83
+ *
84
+ * @since 3.7
85
+ *
86
+ * @return string The plugin version.
87
+ */
88
+ private function getPluginVersion( $plugin ) {
89
+ if ( isset( $plugin['Version'] ) ) {
90
+ return $plugin['Version'];
91
+ }
92
+
93
+ return 'Not Set';
94
+ }
95
+
96
+ /**
97
+ * Send the checkin.
98
+ *
99
+ * @since 3.7
100
+ *
101
+ * @return boolean Whether or not it worked.
102
+ */
103
+ public function send_checkin( $override = false, $ignore_last_checkin = false ) {
104
+ $home_url = trailingslashit( home_url() );
105
+ if ( strpos( $home_url, 'aioseo.com' ) !== false ) {
106
+ return false;
107
+ }
108
+
109
+ if ( ! $this->tracking_allowed() && ! $override ) {
110
+ return false;
111
+ }
112
+
113
+ // Send a maximum of once per week
114
+ $last_send = get_option( 'aioseop_usage_tracking_last_checkin' );
115
+ if ( is_numeric( $last_send ) && $last_send > strtotime( '-1 week' ) && ! $ignore_last_checkin ) {
116
+ return false;
117
+ }
118
+
119
+ $request = wp_remote_post( $this->get_url(), array(
120
+ 'timeout' => 5,
121
+ 'redirection' => 5,
122
+ 'httpversion' => '1.1',
123
+ 'blocking' => false,
124
+ 'headers' => array( 'Content-Type' => 'application/json; charset=utf-8' ),
125
+ 'body' => wp_json_encode( $this->get_data() ),
126
+ 'user-agent' => 'AIOSEO/' . AIOSEOP_VERSION . '; ' . get_bloginfo( 'url' ),
127
+ ) );
128
+
129
+ // If we have completed successfully, recheck in 1 week
130
+ if ( ! $ignore_last_checkin ) {
131
+ update_option( 'aioseop_usage_tracking_last_checkin', time() );
132
+ }
133
+ return true;
134
+ }
135
+
136
+ /**
137
+ * Checks if we are allowed to track.
138
+ *
139
+ * @since 3.7
140
+ *
141
+ * @return boolean Whether or not we are allowed to track.
142
+ */
143
+ private function tracking_allowed() {
144
+ global $aioseop_options;
145
+ return ! empty( $aioseop_options['aiosp_usage_tracking'] ) || AIOSEOPPRO;
146
+ }
147
+
148
+ /**
149
+ * Get the url.
150
+ *
151
+ * @since 3.7
152
+ *
153
+ * @return string The url.
154
+ */
155
+ private function get_url() {
156
+ $url = 'https://usage.aioseo.com/v1/track';
157
+ if ( defined( 'AIOSEO_USAGE_TRACKING_URL' ) ) {
158
+ $url = AIOSEO_USAGE_TRACKING_URL;
159
+ }
160
+
161
+ return $url;
162
+ }
163
+
164
+ /**
165
+ * Schedules sending.
166
+ *
167
+ * @since 3.7
168
+ *
169
+ * @return void
170
+ */
171
+ public function schedule_send() {
172
+ $scheduled = wp_next_scheduled( 'aioseop_usage_tracking_cron' );
173
+ if ( ! $this->tracking_allowed() ) {
174
+ if ( $scheduled ) {
175
+ wp_unschedule_event( $scheduled, 'aioseop_usage_tracking_cron' );
176
+ }
177
+ return;
178
+ }
179
+
180
+ if ( ! $scheduled ) {
181
+ $tracking = array();
182
+ $tracking['day'] = rand( 0, 6 );
183
+ $tracking['hour'] = rand( 0, 23 );
184
+ $tracking['minute'] = rand( 0, 59 );
185
+ $tracking['second'] = rand( 0, 59 );
186
+ $tracking['offset'] = ( $tracking['day'] * DAY_IN_SECONDS ) +
187
+ ( $tracking['hour'] * HOUR_IN_SECONDS ) +
188
+ ( $tracking['minute'] * MINUTE_IN_SECONDS ) +
189
+ $tracking['second'];
190
+ $tracking['initsend'] = strtotime("next sunday") + $tracking['offset'];
191
+
192
+ wp_schedule_event( $tracking['initsend'], 'weekly', 'aioseop_usage_tracking_cron' );
193
+ update_option( 'aioseop_usage_tracking_config', $tracking );
194
+
195
+ // Send immediately.
196
+ $this->send_checkin( true, true );
197
+ }
198
+ }
199
+
200
+ /**
201
+ * Create a weekly schedule.
202
+ *
203
+ * @since 3.7
204
+ *
205
+ * @return array an Array of schedules.
206
+ */
207
+ public function add_schedules( $schedules = array() ) {
208
+ // Adds once weekly to the existing schedules.
209
+ $schedules['weekly'] = array(
210
+ 'interval' => 604800,
211
+ 'display' => __( 'Once Weekly', 'all-in-one-seo-pack' ),
212
+ );
213
+ return $schedules;
214
+ }
215
+ }
admin/display/general-metaboxes.php CHANGED
@@ -165,7 +165,10 @@ class aiosp_metaboxes {
165
  </li>
166
  </ul>
167
  </div>
168
- <?php break; ?>
 
 
 
169
  <?php endswitch; ?>
170
  </div>
171
  <?php
165
  </li>
166
  </ul>
167
  </div>
168
+ <?php break;
169
+ default:
170
+ break;
171
+ ?>
172
  <?php endswitch; ?>
173
  </div>
174
  <?php
admin/display/notices/local-business-markup-notice.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Configures the Local Business Markup notice.
4
+ *
5
+ * Appears when the user has enabled the Local Business SEO module, but has disabled Schema markup as a whole in the General Settings menu.
6
+ *
7
+ * @since 3.7.0
8
+ *
9
+ * @return array The notice data.
10
+ */
11
+ function aioseoLocalBusinessMarkupNotice() {
12
+ $dirname = dirname( plugin_basename( AIOSEO_PLUGIN_FILE ) );
13
+ $menuPath = admin_url( "admin.php?page=$dirname/aioseop_class.php" );
14
+
15
+ return array(
16
+ 'slug' => 'local_business_markup',
17
+ 'delay_time' => 0,
18
+ 'message' => __( "You've enabled the Local Business SEO module, but all Schema markup (including Local Business schema) is currently disabled.", 'all-in-one-seo-pack' ),
19
+ 'class' => 'notice-warning',
20
+ 'target' => 'site',
21
+ 'screens' => aioseop_get_admin_screens(),
22
+ 'action_options' => array(
23
+ array(
24
+ 'time' => 0,
25
+ 'text' => __( 'Go to General Settings menu', 'all-in-one-seo-pack' ),
26
+ 'link' => $menuPath,
27
+ 'new_tab' => false,
28
+ 'dismiss' => false,
29
+ 'class' => 'button-primary',
30
+ )
31
+ ),
32
+ );
33
+ }
34
+ add_filter( 'aioseop_admin_notice-local_business_markup', 'aioseoLocalBusinessMarkupNotice' );
admin/display/notices/local-business-organization-notice.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Configures the Local Business Organization notice.
4
+ *
5
+ * Appears when the user's schema markup isn't set to Organization in the General Settings menu.
6
+ *
7
+ * @since 3.6.0
8
+ *
9
+ * @return array The notice data.
10
+ */
11
+ function aioseoLocalBusinessOrganizationNotice() {
12
+ $dirname = dirname( plugin_basename( AIOSEO_PLUGIN_FILE ) );
13
+ $menuPath = admin_url( "admin.php?page=$dirname/aioseop_class.php" );
14
+
15
+ return array(
16
+ 'slug' => 'local_business_organization',
17
+ 'delay_time' => 0,
18
+ 'message' => __( 'Your site is currently set to represent a Person. In order to use Local Business schema, you must set your site to represent an Organization.', 'all-in-one-seo-pack' ),
19
+ 'class' => 'notice-warning',
20
+ 'target' => 'site',
21
+ 'screens' => aioseop_get_admin_screens(),
22
+ 'action_options' => array(
23
+ array(
24
+ 'time' => 0,
25
+ 'text' => __( 'Go to General Settings menu', 'all-in-one-seo-pack' ),
26
+ 'link' => $menuPath,
27
+ 'new_tab' => false,
28
+ 'dismiss' => false,
29
+ 'class' => 'button-primary',
30
+ )
31
+ ),
32
+ );
33
+ }
34
+ add_filter( 'aioseop_admin_notice-local_business_organization', 'aioseoLocalBusinessOrganizationNotice' );
admin/display/notices/news-sitemap-notice.php CHANGED
@@ -12,7 +12,7 @@ function aioseop_notice_news_sitemap() {
12
  return array(
13
  'slug' => 'news_sitemap',
14
  'delay_time' => 0,
15
- 'target' => 'user',
16
  'screens' => array(),
17
  'class' => 'notice-error',
18
  'dismissible' => false,
12
  return array(
13
  'slug' => 'news_sitemap',
14
  'delay_time' => 0,
15
+ 'target' => 'site',
16
  'screens' => array(),
17
  'class' => 'notice-error',
18
  'dismissible' => false,
admin/meta_import.php CHANGED
@@ -278,13 +278,13 @@ function aiosp_seometa_meta_key_convert( $old = '', $new = '', $delete_old = fal
278
  }
279
 
280
  // See which records we need to ignore, if any.
281
- $exclude = $wpdb->get_results( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = %s", $new ) );
282
 
283
  // If no records to ignore, we'll do a basic UPDATE and DELETE.
284
  if ( ! $exclude ) {
285
 
286
  $output->updated = $wpdb->update( $wpdb->postmeta, array( 'meta_key' => $new ), array( 'meta_key' => $old ) );
287
- $output->deleted = $delete_old ? $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->postmeta WHERE meta_key = %s", $old ) ) : 0;
288
  $output->ignored = 0;
289
 
290
  } else {
@@ -295,8 +295,8 @@ function aiosp_seometa_meta_key_convert( $old = '', $new = '', $delete_old = fal
295
  $not_in = implode( ', ', (array) $not_in );
296
 
297
  // @codingStandardsIgnoreStart
298
- $output->updated = $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->postmeta SET meta_key = %s WHERE meta_key = %s AND post_id NOT IN ($not_in)", $new, $old ) );
299
- $output->deleted = $delete_old ? $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->postmeta WHERE meta_key = %s", $old ) ) : 0;
300
  // @codingStandardsIgnoreEnd
301
  $output->ignored = count( $exclude );
302
 
@@ -411,7 +411,7 @@ function aiosp_seometa_post_meta_analyze( $old_platform = '', $new_platform = 'A
411
  $ignore = 0;
412
  // $ignore = $wpdb->get_results( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = %s", $meta_key ) );
413
  // See which records to update, if any.
414
- $update = $wpdb->get_results( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = %s", $meta_key ) );
415
 
416
  // Count items in returned arrays.
417
  // phpcs:ignore Squiz.Commenting.InlineComment.InvalidEndChar
278
  }
279
 
280
  // See which records we need to ignore, if any.
281
+ $exclude = $wpdb->get_results( $wpdb->prepare( "SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = %s", $new ) );
282
 
283
  // If no records to ignore, we'll do a basic UPDATE and DELETE.
284
  if ( ! $exclude ) {
285
 
286
  $output->updated = $wpdb->update( $wpdb->postmeta, array( 'meta_key' => $new ), array( 'meta_key' => $old ) );
287
+ $output->deleted = $delete_old ? $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->postmeta} WHERE meta_key = %s", $old ) ) : 0;
288
  $output->ignored = 0;
289
 
290
  } else {
295
  $not_in = implode( ', ', (array) $not_in );
296
 
297
  // @codingStandardsIgnoreStart
298
+ $output->updated = $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->postmeta} SET meta_key = %s WHERE meta_key = %s AND post_id NOT IN (%s)", $new, $old, $not_in ) );
299
+ $output->deleted = $delete_old ? $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->postmeta} WHERE meta_key = %s", $old ) ) : 0;
300
  // @codingStandardsIgnoreEnd
301
  $output->ignored = count( $exclude );
302
 
411
  $ignore = 0;
412
  // $ignore = $wpdb->get_results( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = %s", $meta_key ) );
413
  // See which records to update, if any.
414
+ $update = $wpdb->get_results( $wpdb->prepare( "SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = %s", $meta_key ) );
415
 
416
  // Count items in returned arrays.
417
  // phpcs:ignore Squiz.Commenting.InlineComment.InvalidEndChar
aioseop_class.php CHANGED
@@ -120,6 +120,17 @@ class All_in_One_SEO_Pack extends All_in_One_SEO_Pack_Module {
120
  */
121
  var $do_log;
122
 
 
 
 
 
 
 
 
 
 
 
 
123
  /**
124
  * Token
125
  *
@@ -217,6 +228,13 @@ class All_in_One_SEO_Pack extends All_in_One_SEO_Pack_Module {
217
  } else {
218
  $this->do_log = false;
219
  }
 
 
 
 
 
 
 
220
  /* translators: This is a header for the General Settings menu. %s is a placeholder and is replaced with the name of the plugin. */
221
  $this->name = sprintf( __( '%s Plugin Options', 'all-in-one-seo-pack' ), AIOSEOP_PLUGIN_NAME );
222
  /* translators: This is the main menu of the plugin. */
@@ -863,11 +881,33 @@ class All_in_One_SEO_Pack extends All_in_One_SEO_Pack_Module {
863
  'name' => __( 'Log important events', 'all-in-one-seo-pack' ),
864
  'default' => null,
865
  ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
866
 
 
 
 
 
867
  );
868
 
869
  if ( ! AIOSEOPPRO ) {
870
  unset( $this->default_options['taxactive'] );
 
 
871
  }
872
 
873
  $this->locations = array(
@@ -1154,6 +1194,14 @@ class All_in_One_SEO_Pack extends All_in_One_SEO_Pack_Module {
1154
  'paginated_nofollow',
1155
  ),
1156
  ),
 
 
 
 
 
 
 
 
1157
  'advanced' => array(
1158
  'name' => __( 'Advanced Settings', 'all-in-one-seo-pack' ),
1159
  'help_link' => 'https://semperplugins.com/documentation/all-in-one-seo-pack-advanced-settings/',
@@ -1193,7 +1241,7 @@ class All_in_One_SEO_Pack extends All_in_One_SEO_Pack_Module {
1193
  );
1194
 
1195
  global $wpdb;
1196
- $user_count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->users" );
1197
  if ( 50 < $user_count ) {
1198
  $this->default_options['schema_person_user']['initial_options'] = array(
1199
  -1 => __( 'Manually Enter', 'all-in-one-seo-pack' ),
@@ -3753,7 +3801,7 @@ class All_in_One_SEO_Pack extends All_in_One_SEO_Pack_Module {
3753
 
3754
  $snippet_preview_data = array(
3755
  'autogenerateDescriptions' => isset( $aioseop_options['aiosp_generate_descriptions'] ) ? $aioseop_options['aiosp_generate_descriptions'] : '',
3756
- 'skipExcerpt' => isset( $aioseop_options['aiosp_skip_excerpt'] ) ? $aioseop_options['aiosp_skip_excerpt'] : '',
3757
  'dontTruncateDescriptions' => isset( $aioseop_options['aiosp_dont_truncate_descriptions'] ) ? $aioseop_options['aiosp_dont_truncate_descriptions'] : '',
3758
  );
3759
 
@@ -3800,6 +3848,8 @@ class All_in_One_SEO_Pack extends All_in_One_SEO_Pack_Module {
3800
  );
3801
  wp_localize_script( 'aioseop-count-chars', 'aioseopCharacterCounter', $count_chars_data );
3802
  break;
 
 
3803
  }
3804
  parent::admin_enqueue_scripts( $hook_suffix );
3805
  }
@@ -4143,7 +4193,8 @@ class All_in_One_SEO_Pack extends All_in_One_SEO_Pack_Module {
4143
  }
4144
 
4145
  if ( ! empty( $old_wp_query ) ) {
4146
- $GLOBALS['wp_query'] = $old_wp_query;
 
4147
  // Change the query back after we've finished.
4148
  unset( $old_wp_query );
4149
  }
@@ -4513,7 +4564,8 @@ class All_in_One_SEO_Pack extends All_in_One_SEO_Pack_Module {
4513
 
4514
  if ( ! empty( $old_wp_query ) ) {
4515
  // Change the query back after we've finished.
4516
- $GLOBALS['wp_query'] = $old_wp_query;
 
4517
  unset( $old_wp_query );
4518
  }
4519
 
@@ -4540,7 +4592,8 @@ class All_in_One_SEO_Pack extends All_in_One_SEO_Pack_Module {
4540
  echo "\n<!-- " . sprintf( __( 'Debug Warning: %1$s meta data was included again from %2$s filter. Called %3$s times!', 'all-in-one-seo-pack' ), AIOSEOP_PLUGIN_NAME, current_filter(), $aioseop_dup_counter ) . " -->\n";
4541
  if ( ! empty( $old_wp_query ) ) {
4542
  // Change the query back after we've finished.
4543
- $GLOBALS['wp_query'] = $old_wp_query;
 
4544
  unset( $old_wp_query );
4545
  }
4546
 
@@ -4748,7 +4801,8 @@ class All_in_One_SEO_Pack extends All_in_One_SEO_Pack_Module {
4748
 
4749
  if ( ! empty( $old_wp_query ) ) {
4750
  // Change the query back after we've finished.
4751
- $GLOBALS['wp_query'] = $old_wp_query;
 
4752
  unset( $old_wp_query );
4753
  }
4754
 
@@ -5105,11 +5159,7 @@ class All_in_One_SEO_Pack extends All_in_One_SEO_Pack_Module {
5105
 
5106
  foreach ( $optlist as $optionName ) {
5107
  $value = isset( $_POST[ "aiosp_$optionName" ] ) ? $_POST[ "aiosp_$optionName" ] : '';
5108
-
5109
- if ( is_string( $value) ) {
5110
- $value = esc_html( $value );
5111
- }
5112
- update_post_meta( $id, "_aioseop_$optionName", $value );
5113
  }
5114
  }
5115
  }
@@ -5253,7 +5303,7 @@ class All_in_One_SEO_Pack extends All_in_One_SEO_Pack_Module {
5253
 
5254
  if ( ! is_admin() ) {
5255
  AIOSEOP_Education::external_tools( $wp_admin_bar );
5256
- }
5257
 
5258
  $aioseop_admin_menu = 1;
5259
  if ( ! empty( $post ) ) {
@@ -5396,14 +5446,10 @@ class All_in_One_SEO_Pack extends All_in_One_SEO_Pack_Module {
5396
  $optlist = array_diff( $optlist, array( 'sitemap_priority', 'sitemap_frequency' ) );
5397
  }
5398
 
5399
-
5400
  foreach ( $optlist as $optionName ) {
5401
  $value = isset( $_POST[ "aiosp_$optionName" ] ) ? $_POST[ "aiosp_$optionName" ] : '';
5402
-
5403
- if ( is_string( $value) ) {
5404
- $value = esc_html( $value );
5405
- }
5406
- update_term_meta( $id, "_aioseop_$optionName", $value );
5407
  }
5408
  }
5409
  }
120
  */
121
  var $do_log;
122
 
123
+ /**
124
+ * Usage Tracking
125
+ *
126
+ * Flag whether there should be usage tracking.
127
+ *
128
+ * @since 3.7
129
+ *
130
+ * @var bool $usage_tracking
131
+ */
132
+ var $usage_tracking;
133
+
134
  /**
135
  * Token
136
  *
228
  } else {
229
  $this->do_log = false;
230
  }
231
+
232
+ if ( ! empty( $aioseop_options ) && isset( $aioseop_options['aiosp_usage_tracking'] ) && $aioseop_options['aiosp_usage_tracking'] ) {
233
+ $this->usage_tracking = true;
234
+ } else {
235
+ $this->usage_tracking = false;
236
+ }
237
+
238
  /* translators: This is a header for the General Settings menu. %s is a placeholder and is replaced with the name of the plugin. */
239
  $this->name = sprintf( __( '%s Plugin Options', 'all-in-one-seo-pack' ), AIOSEOP_PLUGIN_NAME );
240
  /* translators: This is the main menu of the plugin. */
881
  'name' => __( 'Log important events', 'all-in-one-seo-pack' ),
882
  'default' => null,
883
  ),
884
+ 'rss_content_before' => array(
885
+ 'name' => __( 'Before Your Content', 'all-in-one-seo-pack' ),
886
+ 'type' => 'textarea',
887
+ 'rows' => 2,
888
+ ),
889
+ 'rss_content_after' => array(
890
+ 'name' => __( 'After Your Content', 'all-in-one-seo-pack' ),
891
+ 'type' => 'textarea',
892
+ 'rows' => 2,
893
+ 'default' => sprintf(
894
+ /* translators: 1 - The post title, 2 - The site title. */
895
+ __( 'The post %1$s first appeared on %2$s.', 'all-in-one-seo-pack' ),
896
+ '%post_link%',
897
+ '%site_link%'
898
+ )
899
+ ),
900
 
901
+ 'usage_tracking' => array(
902
+ 'name' => __( 'Allow Usage Tracking', 'all-in-one-seo-pack' ),
903
+ 'default' => null,
904
+ ),
905
  );
906
 
907
  if ( ! AIOSEOPPRO ) {
908
  unset( $this->default_options['taxactive'] );
909
+ } else {
910
+ unset( $this->default_options['usage_tracking'] );
911
  }
912
 
913
  $this->locations = array(
1194
  'paginated_nofollow',
1195
  ),
1196
  ),
1197
+ 'rss_content' => array(
1198
+ 'name' => __( 'RSS Content Settings', 'all-in-one-seo-pack' ),
1199
+ 'help_link' => 'https://semperplugins.com/documentation/rss-content-settings/',
1200
+ 'options' => array(
1201
+ 'rss_content_before',
1202
+ 'rss_content_after',
1203
+ ),
1204
+ ),
1205
  'advanced' => array(
1206
  'name' => __( 'Advanced Settings', 'all-in-one-seo-pack' ),
1207
  'help_link' => 'https://semperplugins.com/documentation/all-in-one-seo-pack-advanced-settings/',
1241
  );
1242
 
1243
  global $wpdb;
1244
+ $user_count = $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->users}" );
1245
  if ( 50 < $user_count ) {
1246
  $this->default_options['schema_person_user']['initial_options'] = array(
1247
  -1 => __( 'Manually Enter', 'all-in-one-seo-pack' ),
3801
 
3802
  $snippet_preview_data = array(
3803
  'autogenerateDescriptions' => isset( $aioseop_options['aiosp_generate_descriptions'] ) ? $aioseop_options['aiosp_generate_descriptions'] : '',
3804
+ 'skipExcerpt' => isset( $aioseop_options['aiosp_skip_excerpt'] ) ? $aioseop_options['aiosp_skip_excerpt'] : '',
3805
  'dontTruncateDescriptions' => isset( $aioseop_options['aiosp_dont_truncate_descriptions'] ) ? $aioseop_options['aiosp_dont_truncate_descriptions'] : '',
3806
  );
3807
 
3848
  );
3849
  wp_localize_script( 'aioseop-count-chars', 'aioseopCharacterCounter', $count_chars_data );
3850
  break;
3851
+ default:
3852
+ break;
3853
  }
3854
  parent::admin_enqueue_scripts( $hook_suffix );
3855
  }
4193
  }
4194
 
4195
  if ( ! empty( $old_wp_query ) ) {
4196
+ global $wp_query;
4197
+ $wp_query = $old_wp_query;
4198
  // Change the query back after we've finished.
4199
  unset( $old_wp_query );
4200
  }
4564
 
4565
  if ( ! empty( $old_wp_query ) ) {
4566
  // Change the query back after we've finished.
4567
+ global $wp_query;
4568
+ $wp_query = $old_wp_query;
4569
  unset( $old_wp_query );
4570
  }
4571
 
4592
  echo "\n<!-- " . sprintf( __( 'Debug Warning: %1$s meta data was included again from %2$s filter. Called %3$s times!', 'all-in-one-seo-pack' ), AIOSEOP_PLUGIN_NAME, current_filter(), $aioseop_dup_counter ) . " -->\n";
4593
  if ( ! empty( $old_wp_query ) ) {
4594
  // Change the query back after we've finished.
4595
+ global $wp_query;
4596
+ $wp_query = $old_wp_query;
4597
  unset( $old_wp_query );
4598
  }
4599
 
4801
 
4802
  if ( ! empty( $old_wp_query ) ) {
4803
  // Change the query back after we've finished.
4804
+ global $wp_query;
4805
+ $wp_query = $old_wp_query;
4806
  unset( $old_wp_query );
4807
  }
4808
 
5159
 
5160
  foreach ( $optlist as $optionName ) {
5161
  $value = isset( $_POST[ "aiosp_$optionName" ] ) ? $_POST[ "aiosp_$optionName" ] : '';
5162
+ update_post_meta( $id, "_aioseop_$optionName", aioseop_sanitize( $value ) );
 
 
 
 
5163
  }
5164
  }
5165
  }
5303
 
5304
  if ( ! is_admin() ) {
5305
  AIOSEOP_Education::external_tools( $wp_admin_bar );
5306
+ }
5307
 
5308
  $aioseop_admin_menu = 1;
5309
  if ( ! empty( $post ) ) {
5446
  $optlist = array_diff( $optlist, array( 'sitemap_priority', 'sitemap_frequency' ) );
5447
  }
5448
 
5449
+
5450
  foreach ( $optlist as $optionName ) {
5451
  $value = isset( $_POST[ "aiosp_$optionName" ] ) ? $_POST[ "aiosp_$optionName" ] : '';
5452
+ update_term_meta( $id, "_aioseop_$optionName", aioseop_sanitize( $value ) );
 
 
 
 
5453
  }
5454
  }
5455
  }
all_in_one_seo_pack.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: All In One SEO Pack
4
  Plugin URI: https://semperplugins.com/all-in-one-seo-pack-pro-version/
5
  Description: Out-of-the-box SEO for WordPress. Features like XML Sitemaps, SEO for custom post types, SEO for blogs or business sites, SEO for ecommerce sites, and much more. More than 50 million downloads since 2007.
6
- Version: 3.6.2
7
  Author: All in One SEO Team
8
  Author URI: https://semperplugins.com/all-in-one-seo-pack-pro-version/
9
  Text Domain: all-in-one-seo-pack
@@ -59,4 +59,4 @@ if ( ! class_exists( 'AIOSEOP_Core' ) ) {
59
  if ( is_null( $aioseop_core ) ) {
60
  $aioseop_core = new AIOSEOP_Core();
61
  }
62
- }
3
  Plugin Name: All In One SEO Pack
4
  Plugin URI: https://semperplugins.com/all-in-one-seo-pack-pro-version/
5
  Description: Out-of-the-box SEO for WordPress. Features like XML Sitemaps, SEO for custom post types, SEO for blogs or business sites, SEO for ecommerce sites, and much more. More than 50 million downloads since 2007.
6
+ Version: 3.7.0
7
  Author: All in One SEO Team
8
  Author URI: https://semperplugins.com/all-in-one-seo-pack-pro-version/
9
  Text Domain: all-in-one-seo-pack
59
  if ( is_null( $aioseop_core ) ) {
60
  $aioseop_core = new AIOSEOP_Core();
61
  }
62
+ }
class-aioseop-core.php CHANGED
@@ -140,6 +140,8 @@ class AIOSEOP_Core {
140
  AIOSEOP_Education::init();
141
  AIOSEOP_Flyout::init();
142
 
 
 
143
  // TODO Move this add_action to All_in_One_SEO_Pack::__construct().
144
  add_action( 'init', array( $aiosp, 'add_hooks' ) );
145
 
@@ -331,11 +333,13 @@ class AIOSEOP_Core {
331
  require_once AIOSEOP_PLUGIN_DIR . 'admin/display/dashboard_widget.php';
332
  require_once AIOSEOP_PLUGIN_DIR . 'admin/display/menu.php';
333
  require_once AIOSEOP_PLUGIN_DIR . 'admin/class-aioseop-notices.php';
 
334
  require_once AIOSEOP_PLUGIN_DIR . 'inc/schema/schema-builder.php';
335
  require_once AIOSEOP_PLUGIN_DIR . 'inc/admin/class-aioseop-link-attributes.php';
336
  require_once( AIOSEOP_PLUGIN_DIR . 'inc/admin/class-aioseop-education.php' );
337
  require_once( AIOSEOP_PLUGIN_DIR . 'inc/admin/views/class-aioseop-flyout.php' );
338
  require_once( AIOSEOP_PLUGIN_DIR . 'inc/admin/views/class-aioseop-about.php' );
 
339
 
340
  // Loads pro files and other pro init stuff.
341
  if ( AIOSEOPPRO ) {
@@ -400,6 +404,7 @@ class AIOSEOP_Core {
400
  global $wp_version;
401
 
402
  AIOSEOP_Welcome::hooks();
 
403
 
404
  add_action( 'plugins_loaded', array( $this, 'add_cap' ) );
405
 
@@ -425,7 +430,7 @@ class AIOSEOP_Core {
425
 
426
  $file_dir = AIOSEOP_PLUGIN_DIR . 'all_in_one_seo_pack.php';
427
  register_activation_hook( $file_dir, array( 'AIOSEOP_Core', 'activate' ) );
428
- register_deactivation_hook( $file_dir, array( 'AIOSEOP_Core', 'deactivate' ) );
429
 
430
  // TODO Move AJAX to aioseop_admin class, and could be a separate function hooked onto admin_init.
431
  add_action( 'wp_ajax_aioseop_ajax_save_meta', 'aioseop_ajax_save_meta' );
@@ -509,7 +514,7 @@ class AIOSEOP_Core {
509
 
510
  /**
511
  * Runs on plugin deactivation.
512
- *
513
  * @since 3.4.3
514
  */
515
  public static function deactivate() {
@@ -590,6 +595,8 @@ class AIOSEOP_Core {
590
  // fall through.
591
  case 'K':
592
  $num *= 1024;
 
 
593
  }
594
  }
595
 
@@ -774,7 +781,7 @@ class AIOSEOP_Core {
774
  * Enqueues stylesheets used on the frontend.
775
  *
776
  * @since 3.4.0
777
- *
778
  * @return void
779
  */
780
  function front_enqueue_styles() {
140
  AIOSEOP_Education::init();
141
  AIOSEOP_Flyout::init();
142
 
143
+ new AIOSEOP_Usage();
144
+
145
  // TODO Move this add_action to All_in_One_SEO_Pack::__construct().
146
  add_action( 'init', array( $aiosp, 'add_hooks' ) );
147
 
333
  require_once AIOSEOP_PLUGIN_DIR . 'admin/display/dashboard_widget.php';
334
  require_once AIOSEOP_PLUGIN_DIR . 'admin/display/menu.php';
335
  require_once AIOSEOP_PLUGIN_DIR . 'admin/class-aioseop-notices.php';
336
+ require_once AIOSEOP_PLUGIN_DIR . 'admin/class-aioseop-usage.php';
337
  require_once AIOSEOP_PLUGIN_DIR . 'inc/schema/schema-builder.php';
338
  require_once AIOSEOP_PLUGIN_DIR . 'inc/admin/class-aioseop-link-attributes.php';
339
  require_once( AIOSEOP_PLUGIN_DIR . 'inc/admin/class-aioseop-education.php' );
340
  require_once( AIOSEOP_PLUGIN_DIR . 'inc/admin/views/class-aioseop-flyout.php' );
341
  require_once( AIOSEOP_PLUGIN_DIR . 'inc/admin/views/class-aioseop-about.php' );
342
+ require_once( AIOSEOP_PLUGIN_DIR . 'inc/class-aioseop-rss.php' );
343
 
344
  // Loads pro files and other pro init stuff.
345
  if ( AIOSEOPPRO ) {
404
  global $wp_version;
405
 
406
  AIOSEOP_Welcome::hooks();
407
+ new AIOSEOP_Rss();
408
 
409
  add_action( 'plugins_loaded', array( $this, 'add_cap' ) );
410
 
430
 
431
  $file_dir = AIOSEOP_PLUGIN_DIR . 'all_in_one_seo_pack.php';
432
  register_activation_hook( $file_dir, array( 'AIOSEOP_Core', 'activate' ) );
433
+ register_deactivation_hook( $file_dir, array( 'AIOSEOP_Core', 'deactivate' ) );
434
 
435
  // TODO Move AJAX to aioseop_admin class, and could be a separate function hooked onto admin_init.
436
  add_action( 'wp_ajax_aioseop_ajax_save_meta', 'aioseop_ajax_save_meta' );
514
 
515
  /**
516
  * Runs on plugin deactivation.
517
+ *
518
  * @since 3.4.3
519
  */
520
  public static function deactivate() {
595
  // fall through.
596
  case 'K':
597
  $num *= 1024;
598
+ default:
599
+ return false;
600
  }
601
  }
602
 
781
  * Enqueues stylesheets used on the frontend.
782
  *
783
  * @since 3.4.0
784
+ *
785
  * @return void
786
  */
787
  function front_enqueue_styles() {
css/aiosp_admin.css CHANGED
@@ -534,4 +534,22 @@ body #wp-link-wrap #link-selector {
534
  background-color: #ca4a1f !important;
535
  line-height: 1.6 !important;
536
  animation: aioseo-menu-notification-indicator-pulse 1.5s infinite !important;
537
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
534
  background-color: #ca4a1f !important;
535
  line-height: 1.6 !important;
536
  animation: aioseo-menu-notification-indicator-pulse 1.5s infinite !important;
537
+ }
538
+
539
+ #wpbody .All_in_One_SEO_Pack_Importer_Exporter .aioseop_option_div ul {
540
+ margin: 20px 30px;
541
+ list-style: disc;
542
+ }
543
+
544
+ #aiosp_rss_content_metabox .inside .aiosp_settings .aioseop-rss-content-description {
545
+ margin: 20px;
546
+ }
547
+
548
+ #aiosp_rss_content_metabox .inside .aiosp_settings .aioseop-rss-content-tags {
549
+ margin: 10px 20px
550
+ }
551
+
552
+ #wpbody .aioseop_options_wrapper .postbox .handle-order-higher,
553
+ #wpbody .aioseop_options_wrapper .postbox .handle-order-lower {
554
+ display: none;
555
+ }
css/modules/aioseop_module.css CHANGED
@@ -1541,6 +1541,7 @@ div#aiosp_sitemap_status_metabox .toggle-indicator {
1541
  font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif !important;
1542
  }
1543
 
 
1544
  .aioseop_options_wrapper .ui-sortable-handle span {
1545
  font-size: 16px;
1546
  font-weight: 600;
1541
  font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif !important;
1542
  }
1543
 
1544
+ .aioseop_options_wrapper .ui-sortable-handle,
1545
  .aioseop_options_wrapper .ui-sortable-handle span {
1546
  font-size: 16px;
1547
  font-weight: 600;
inc/admin/class-aioseop-education.php CHANGED
@@ -754,10 +754,10 @@ class AIOSEOP_Education {
754
  private static function check_new_conflicting_plugins( $conflicting_plugins ) {
755
  // get_option() doesn't work here because it returns false if the option is blank, and we need to know if it exists.
756
  global $wpdb;
757
- $count = (int) $wpdb->get_var( "select count(*) from {$wpdb->prefix}options where option_name = 'aioseop_detected_conflicting_plugins'");
758
 
759
  $stored = array();
760
- if( 0 !== $count ) {
761
  $stored = get_option( 'aioseop_detected_conflicting_plugins' );
762
  update_option( 'aioseop_detected_conflicting_plugins', $conflicting_plugins );
763
  } else {
@@ -765,7 +765,7 @@ class AIOSEOP_Education {
765
  }
766
 
767
  if ( count( $stored ) < count( $conflicting_plugins ) ) {
768
- if( get_user_meta( get_current_user_id(), 'aioseop_notice_display_time_conflicting_plugin' ) ) {
769
  delete_user_meta( get_current_user_id(), 'aioseop_notice_display_time_conflicting_plugin' );
770
  }
771
  }
754
  private static function check_new_conflicting_plugins( $conflicting_plugins ) {
755
  // get_option() doesn't work here because it returns false if the option is blank, and we need to know if it exists.
756
  global $wpdb;
757
+ $count = (int) $wpdb->get_var( "SELECT count(*) FROM {$wpdb->options} WHERE option_name = 'aioseop_detected_conflicting_plugins'" );
758
 
759
  $stored = array();
760
+ if ( 0 !== $count ) {
761
  $stored = get_option( 'aioseop_detected_conflicting_plugins' );
762
  update_option( 'aioseop_detected_conflicting_plugins', $conflicting_plugins );
763
  } else {
765
  }
766
 
767
  if ( count( $stored ) < count( $conflicting_plugins ) ) {
768
+ if ( get_user_meta( get_current_user_id(), 'aioseop_notice_display_time_conflicting_plugin' ) ) {
769
  delete_user_meta( get_current_user_id(), 'aioseop_notice_display_time_conflicting_plugin' );
770
  }
771
  }
inc/admin/views/class-aioseop-about.php CHANGED
@@ -224,6 +224,8 @@ class AIOSEOP_About {
224
  self::output_versus_grid();
225
  break;
226
  }
 
 
227
  }
228
 
229
  echo '</div>';
224
  self::output_versus_grid();
225
  break;
226
  }
227
+ default:
228
+ break;
229
  }
230
 
231
  echo '</div>';
inc/aioseop_functions.php CHANGED
@@ -840,7 +840,7 @@ if ( ! function_exists( 'render_seo_column' ) ) {
840
  }
841
  }
842
 
843
- $value = esc_html( trim( $value ) );
844
  if ( empty( $value ) ) {
845
  $value = sprintf( '<strong>%s</strong>', sprintf( __( 'No value', 'all-in-one-seo-pack' ), str_replace( '_', ' ', $name ) ) );
846
  }
@@ -919,9 +919,11 @@ if ( ! function_exists( 'aioseop_ajax_save_meta' ) ) {
919
  $key = '_wp_attachment_image_alt';
920
  break;
921
  }
 
 
922
  }
923
 
924
- update_post_meta( $post_id, $key, esc_html( $value ) );
925
  }
926
  }
927
 
@@ -1482,6 +1484,7 @@ if ( ! function_exists( 'aioseop_get_admin_screens' ) ) {
1482
  'Video Sitemap' => 'all-in-one-seo_page_' . AIOSEOP_PLUGIN_DIRNAME . '/pro/video_sitemap',
1483
  'Image SEO' => 'all-in-one-seo_page_aiosp_image_seo',
1484
  'About Us' => 'all-in-one-seo_page_aioseop-about',
 
1485
  );
1486
  }
1487
  }
@@ -1648,4 +1651,36 @@ if ( ! function_exists( 'aioseop_last_modified_post' ) ) {
1648
  }
1649
  return $query->posts[0];
1650
  }
1651
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
840
  }
841
  }
842
 
843
+ $value = aioseop_sanitize( $value );
844
  if ( empty( $value ) ) {
845
  $value = sprintf( '<strong>%s</strong>', sprintf( __( 'No value', 'all-in-one-seo-pack' ), str_replace( '_', ' ', $name ) ) );
846
  }
919
  $key = '_wp_attachment_image_alt';
920
  break;
921
  }
922
+ default:
923
+ return;
924
  }
925
 
926
+ update_post_meta( $post_id, $key, aioseop_sanitize( $value ) );
927
  }
928
  }
929
 
1484
  'Video Sitemap' => 'all-in-one-seo_page_' . AIOSEOP_PLUGIN_DIRNAME . '/pro/video_sitemap',
1485
  'Image SEO' => 'all-in-one-seo_page_aiosp_image_seo',
1486
  'About Us' => 'all-in-one-seo_page_aioseop-about',
1487
+ 'Local Business SEO' => 'all-in-one-seo_page_' . AIOSEOP_PLUGIN_DIRNAME . '/pro/modules/class-aioseop-schema-local-business',
1488
  );
1489
  }
1490
  }
1651
  }
1652
  return $query->posts[0];
1653
  }
1654
+ }
1655
+
1656
+ if ( ! function_exists( 'aioseop_sanitize' ) ) {
1657
+ /**
1658
+ * Sanitizes a given value before we store it in the DB.
1659
+ *
1660
+ * @since 3.7.0
1661
+ *
1662
+ * @param mixed $value The value.
1663
+ * @return mixed $value The sanitized value.
1664
+ */
1665
+ function aioseop_sanitize( $value ) {
1666
+ switch ( gettype( $value ) ) {
1667
+ case 'boolean':
1668
+ return (bool) $value;
1669
+ case 'string':
1670
+ // This is similar to what sanitize_text_field() does but we want to escape tags instead of strip them.
1671
+ return esc_html( wp_check_invalid_utf8( trim( $value ) ) );
1672
+ case 'integer':
1673
+ return intval( $value );
1674
+ case 'double':
1675
+ return floatval( $value );
1676
+ case 'array':
1677
+ $sanitized = array();
1678
+ foreach ( (array) $value as $child ) {
1679
+ array_push( $sanitized, aioseop_sanitize($child) );
1680
+ }
1681
+ return $sanitized;
1682
+ default:
1683
+ return false;
1684
+ }
1685
+ }
1686
+ }
inc/aioseop_updates_class.php CHANGED
@@ -165,6 +165,10 @@ class AIOSEOP_Updates {
165
  if ( version_compare( $old_version, '3.5.0', '<' ) ) {
166
  $this->add_news_sitemap_post_types();
167
  }
 
 
 
 
168
  }
169
 
170
  /**
@@ -441,4 +445,24 @@ class AIOSEOP_Updates {
441
  $aiosp->update_class_option( $aioseop_options );
442
  }
443
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
444
  }
165
  if ( version_compare( $old_version, '3.5.0', '<' ) ) {
166
  $this->add_news_sitemap_post_types();
167
  }
168
+
169
+ if ( version_compare( $old_version, '3.7.0', '<' ) ) {
170
+ $this->rssContent();
171
+ }
172
  }
173
 
174
  /**
445
  $aiosp->update_class_option( $aioseop_options );
446
  }
447
 
448
+ /**
449
+ * Sets the default values for the RSS Content settings.µ
450
+ *
451
+ * @since 3.7.0
452
+ *
453
+ * @return void
454
+ */
455
+ private function rssContent() {
456
+ global $aioseop_options;
457
+ if ( ! isset( $aioseop_options['aiosp_rss_content_before'] ) && ! isset( $aioseop_options['aiosp_rss_content_after'] ) ) {
458
+ $aioseop_options['aiosp_rss_content_after'] = sprintf(
459
+ /* translators: 1 - The post title, 2 - The site title. */
460
+ __( 'The post %1$s first appeared on %2$s.', 'all-in-one-seo-pack' ),
461
+ '%post_link%',
462
+ '%site_link%'
463
+ );
464
+ }
465
+ update_option( 'aioseop_options', $aioseop_options );
466
+ }
467
+
468
  }
inc/aiosp_common.php CHANGED
@@ -293,30 +293,12 @@ class aiosp_common {
293
  if ( false !== strpos( $url, $uploads_dir['baseurl'] . '/' ) ) {
294
  // Results_1 query looks for URLs with the original guid that is uncropped and unedited.
295
  if ( is_null( $results_1 ) ) {
296
- $results_1 = aiosp_common::attachment_url_to_postid_query_1();
297
  }
298
 
299
  if ( isset( $results_1[ $url_md5 ] ) ) {
300
  $id = intval( $results_1[ $url_md5 ] );
301
  }
302
-
303
- // phpcs:disable Squiz.Commenting.InlineComment.InvalidEndChar
304
- // TODO Add setting to enable; this is TOO MEMORY INTENSE which could result in 1 or more crashes,
305
- // TODO however some may still need custom image URLs.
306
- // TODO NOTE: Transient data does prevent continual crashes.
307
- // else {
308
- // Results_2 query looks for the URL that is cropped and edited. This searches JSON strings
309
- // and returns the original attachment ID (there is no custom attachment IDs).
310
- //
311
- // if ( is_null( $results_2 ) ) {
312
- // $results_2 = aiosp_common::attachment_url_to_postid_query_2();
313
- // }
314
- //
315
- // if ( isset( $results_2[ $url_md5 ] ) ) {
316
- // $id = intval( $results_2[ $url_md5 ] );
317
- // }
318
- // }
319
- // phpcs:enable
320
  }
321
 
322
  self::$attachment_url_postids[ $url_md5 ] = $id;
@@ -362,11 +344,11 @@ class aiosp_common {
362
  *
363
  * @return array
364
  */
365
- public static function attachment_url_to_postid_query_1() {
366
  global $wpdb;
367
 
368
- $results_1 = $wpdb->get_results(
369
- "SELECT ID, MD5(guid) AS guid FROM $wpdb->posts WHERE post_type='attachment' AND post_status='inherit' AND post_mime_type LIKE 'image/%';",
370
  ARRAY_A
371
  );
372
 
@@ -382,87 +364,6 @@ class aiosp_common {
382
  return $results_1;
383
  }
384
 
385
- /**
386
- * Attachment URL to Post ID - Query 2
387
- *
388
- * Unused/Conceptual function. This is intended to work solely with `aiosp_common::attachment_url_to_post_id()`.
389
- * Calling this multiple times is memory intense. It's intended to query for custom images, and data for those types
390
- * of images only exists in the postmeta database table
391
- *
392
- * @todo Investigate unserialize() memory consumption/leak.
393
- * @link https://www.evonide.com/breaking-phps-garbage-collection-and-unserialize/
394
- *
395
- * @see aiosp_common::attachment_url_to_postid()
396
- * @see unserialize()
397
- * @link http://php.net/manual/en/function.unserialize.php
398
- * @see wpdb::get_results()
399
- * @link https://developer.wordpress.org/reference/classes/wpdb/get_results/
400
- * @see wp_upload_dir()
401
- * @link https://developer.wordpress.org/reference/functions/wp_upload_dir/
402
- *
403
- * @return array
404
- */
405
- public static function attachment_url_to_postid_query_2() {
406
- global $wpdb;
407
-
408
- $tmp_arr = array();
409
- // @codingStandardsIgnoreStart WordPress.WP.PreparedSQL.NotPrepared
410
- $results_2 = $wpdb->get_results(
411
- "SELECT post_id, meta_value FROM {$wpdb->postmeta} WHERE `meta_key` = '_wp_attachment_metadata' AND `meta_value` != '" . serialize( array() ) . "';",
412
- ARRAY_A
413
- );
414
- // @codingStandardsIgnoreStop WordPress.WP.PreparedSQL.NotPrepared
415
- if ( $results_2 ) {
416
- for ( $i = 0; $i < count( $results_2 ); $i++ ) {
417
- // TODO Investigate potentual memory leak(s); currently with unserialize.
418
- $meta_value = maybe_unserialize( $results_2[ $i ]['meta_value'] );
419
-
420
- // TODO Needs Discussion: Should this be added? To handle errors better instead of suspecting aioseop is at fault and lessen support threads.
421
- /**
422
- * This currently handles "warning" notices with unserialize which normally can't be handled with a try/catch.
423
- * However, this notice should be identified and corrected; which is seperate from the plugin, but
424
- * can also triggered by the plugin.
425
- *
426
- * @see aiosp_common::error_handle_images()
427
- * @see set_error_handler()
428
- * @link http://php.net/manual/en/function.set-error-handler.php
429
- * @see restore_error_handler()
430
- * @link http://php.net/manual/en/function.restore-error-handler.php
431
- */
432
- /*
433
- set_error_handler( 'aiosp_common::error_handle_images' );
434
- try {
435
- $meta_value = unserialize( $results_2[ $i ]['meta_value'] );
436
- } catch ( Exception $e ) {
437
- unset( $meta_value );
438
- restore_error_handler();
439
- continue;
440
- }
441
- restore_error_handler();
442
- */
443
-
444
- // Images and Videos use different variable structures.
445
- if ( false === $meta_value || ! isset( $meta_value['file'] ) && ! isset( $meta_value['sizes'] ) ) {
446
- continue;
447
- }
448
-
449
- // Set the URL => PostIDs.
450
- $uploads_dir = wp_upload_dir();
451
- $custom_img_base_url = $uploads_dir['baseurl'] . '/' . str_replace( wp_basename( $meta_value['file'] ), '', $meta_value['file'] );
452
- foreach ( $meta_value['sizes'] as $image_size_arr ) {
453
- $tmp_arr[ md5( ( $custom_img_base_url . $image_size_arr['file'] ) ) ] = $results_2[ $i ]['post_id'];
454
- }
455
-
456
- unset( $meta_value );
457
- }
458
- }
459
-
460
- $results_2 = $tmp_arr;
461
- unset( $tmp_arr );
462
-
463
- return $results_2;
464
- }
465
-
466
  /**
467
  * Error Hand Images
468
  *
293
  if ( false !== strpos( $url, $uploads_dir['baseurl'] . '/' ) ) {
294
  // Results_1 query looks for URLs with the original guid that is uncropped and unedited.
295
  if ( is_null( $results_1 ) ) {
296
+ $results_1 = aiosp_common::attachment_url_to_postid_query();
297
  }
298
 
299
  if ( isset( $results_1[ $url_md5 ] ) ) {
300
  $id = intval( $results_1[ $url_md5 ] );
301
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
302
  }
303
 
304
  self::$attachment_url_postids[ $url_md5 ] = $id;
344
  *
345
  * @return array
346
  */
347
+ public static function attachment_url_to_postid_query() {
348
  global $wpdb;
349
 
350
+ $results_1 = $wpdb->get_results(
351
+ $wpdb->prepare( "SELECT ID, MD5(guid) AS guid FROM {$wpdb->posts} WHERE post_type='attachment' AND post_status='inherit' AND post_mime_type LIKE %s;", 'image/%' ),
352
  ARRAY_A
353
  );
354
 
364
  return $results_1;
365
  }
366
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
367
  /**
368
  * Error Hand Images
369
  *
inc/class-aioseop-rss.php ADDED
@@ -0,0 +1,304 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Handles the RSS content.
5
+ *
6
+ * @since 3.7.0
7
+ */
8
+ class AIOSEOP_Rss {
9
+
10
+ /**
11
+ * Class constructor.
12
+ *
13
+ * @since 3.7.0
14
+ */
15
+ public function __construct() {
16
+ global $aioseop_options;
17
+
18
+ add_filter( 'admin_enqueue_scripts', array( $this, 'description' ) );
19
+ if ( ! isset( $aioseop_options['aiosp_rss_content_before'] ) && ! isset( $aioseop_options['aiosp_rss_content_after'] ) ) {
20
+ return;
21
+ }
22
+ $this->hooks();
23
+ }
24
+
25
+ /**
26
+ * Registers our hooks.
27
+ *
28
+ * @since 3.7.0
29
+ *
30
+ * @return void
31
+ */
32
+ private function hooks() {
33
+ add_filter( 'the_content_feed', array( $this, 'addRssContent' ) );
34
+ add_filter( 'the_excerpt_rss', array( $this, 'addRssContentExcerpt' ) );
35
+ }
36
+
37
+ /**
38
+ * Enqueues script to add a description at the top of the RSS Content Settings box in the General Settings menu.
39
+ *
40
+ * @since 3.7.0
41
+ *
42
+ * @return void
43
+ */
44
+ public function description() {
45
+ if ( 'toplevel_page_' . AIOSEOP_PLUGIN_DIRNAME . '/aioseop_class' !== get_current_screen()->id ) {
46
+ return;
47
+ }
48
+
49
+ wp_enqueue_script(
50
+ 'aioseop-rss-content',
51
+ AIOSEOP_PLUGIN_URL . 'js/admin/aioseop-rss-content.js',
52
+ array( 'jquery' ),
53
+ AIOSEOP_VERSION,
54
+ true
55
+ );
56
+
57
+ $feedUrl = trailingslashit( home_url() ) . 'feed';
58
+ wp_localize_script( 'aioseop-rss-content', 'aioseopRssContent', array(
59
+ 'description' => wp_kses(
60
+ sprintf(
61
+ '<div class="aioseop-rss-content-description"><p>%1$s</p></p>%2$s <a href="https://semperplugins.com/documentation/rss-content-settings/" target="_blank">%3$s</a></p></div>',
62
+ sprintf(
63
+ /* translators: 1 - Opening HTML link tag, 2 - Closing HTML link tag. */
64
+ __( 'This feature allows you to automatically add content for each post in your %1$ssite\'s RSS feed%2$s.', 'all-in-one-seo-pack' ),
65
+ "<a href='$feedUrl' target='_blank'>",
66
+ "<a/>"
67
+ ),
68
+ __( 'More specifically, it allows you to add links back to your blog and your blog posts so scrapers will automatically add these links too. This helps search engines identify you as the original source of the content.', 'all-in-one-seo-pack' ),
69
+ __( 'Learn More →', 'all-in-one-seo-pack' )
70
+ ),
71
+ array(
72
+ 'div' => array(
73
+ 'class' => array(),
74
+ ),
75
+ 'p' => array(),
76
+ 'a' => array(
77
+ 'href' => array(),
78
+ 'target' => array(),
79
+ ),
80
+ )
81
+ ),
82
+ 'listOfTags' => wp_kses(
83
+ sprintf(
84
+ '<div class="aioseop-rss-content-tags"><p>%1$s</p>',
85
+ sprintf(
86
+ /* translators: 1 - "Click here". */
87
+ __( '%1$s to view the list of macros that we support for these settings.', 'all-in-one-seo-pack' ),
88
+ sprintf( '%1$s%2$s%3$s',
89
+ '<a href="https://semperplugins.com/documentation/rss-content-settings" target="_blank">',
90
+ __( 'Click here', 'all-in-one-seo-pack' ),
91
+ '</a>'
92
+ )
93
+ )
94
+ ),
95
+ array(
96
+ 'div' => array(
97
+ 'class' => array(),
98
+ ),
99
+ 'p' => array(),
100
+ 'a' => array(
101
+ 'href' => array(),
102
+ 'target' => array(),
103
+ ),
104
+ )
105
+ ),
106
+ ));
107
+ }
108
+
109
+ /**
110
+ * Adds content before or after the RSS post.
111
+ *
112
+ * @since 3.7.0
113
+ *
114
+ * @param string $content The RSS post content.
115
+ * @param string $excerpt Whether the content will be used for the excerpt.
116
+ * @return string $content The modified RSS post content.
117
+ */
118
+ public function addRssContent( $content, $excerpt = false ) {
119
+ $content = trim( $content );
120
+ if ( empty( $content ) ) {
121
+ return '';
122
+ }
123
+
124
+ if ( is_feed() ) {
125
+ global $aioseop_options;
126
+
127
+ $before = isset( $aioseop_options['aiosp_rss_content_before'] ) ? $aioseop_options['aiosp_rss_content_before'] : '';
128
+ $before = $this->replaceTags( $before );
129
+
130
+ $after = isset( $aioseop_options['aiosp_rss_content_after'] ) ? $aioseop_options['aiosp_rss_content_after'] : '';
131
+ $after = $this->replaceTags( $after );
132
+
133
+ if ( $before || $after ) {
134
+ if ( $excerpt ) {
135
+ $content = wpautop( $content );
136
+ }
137
+ $content = htmlspecialchars_decode( $before ) . $content . htmlspecialchars_decode( $after );
138
+ }
139
+ }
140
+
141
+ return $content;
142
+ }
143
+
144
+ /**
145
+ * Adds content before or after the RSS excerpt.
146
+ *
147
+ * @since 3.7.0
148
+ *
149
+ * @param string $content The RSS excerpt content.
150
+ * @return string $content The modified RSS excerpt content.
151
+ */
152
+ public function addRssContentExcerpt( $content ) {
153
+ return $this->addRssContent( $content, true );
154
+ }
155
+
156
+ /**
157
+ * Replaces Smart Tags inside the RSS content with their corresponding values.
158
+ *
159
+ * @since 3.7.0
160
+ *
161
+ * @param string $content The RSS content.
162
+ * @return string The modified RSS content.
163
+ */
164
+ private function replaceTags( $content ) {
165
+ if ( ! $content ) {
166
+ return $content;
167
+ }
168
+
169
+ preg_match_all( '#%[a-zA-Z_]*%#', $content, $tags );
170
+ if ( ! count( $tags[0] ) ) {
171
+ return $content;
172
+ }
173
+
174
+ foreach ( array_unique( $tags[0] ) as $tag ) {
175
+ $content = preg_replace( "#$tag#", $this->getTag( $tag ), $content );
176
+ }
177
+
178
+ return wp_kses(
179
+ '<p>' . trim( $content ) . '</p>',
180
+ array(
181
+ 'p' => array(),
182
+ 'a' => array(
183
+ 'href' => array(),
184
+ 'target' => array(),
185
+ 'title' => array(),
186
+ ),
187
+ ),
188
+ array( 'http', 'https' )
189
+ );
190
+ }
191
+
192
+ /**
193
+ * Returns the value for a given tag.
194
+ *
195
+ * @since 3.7.0
196
+ *
197
+ * @param string $tag The tag.
198
+ * @return string The value.
199
+ */
200
+ private function getTag( $tag ) {
201
+ switch ( $tag ) {
202
+ case '%site_title%':
203
+ return get_bloginfo( 'name' );
204
+ case '%site_link%':
205
+ return $this->siteLink();
206
+ case '%site_link_raw%':
207
+ $url = trailingslashit( home_url() );
208
+ return $this->buildLink( $url, $url );
209
+ case '%post_title%':
210
+ $post = get_post();
211
+ if ( ! $post ) {
212
+ return '';
213
+ }
214
+ return $post->post_title;
215
+ case '%post_link%':
216
+ return $this->postLink();
217
+ case '%post_link_raw%':
218
+ $url = trailingslashit( get_permalink() );
219
+ return $this->buildLink( $url, $url );
220
+ case '%author_name%':
221
+ $post = get_post();
222
+ if ( ! $post ) {
223
+ return '';
224
+ }
225
+ return get_the_author_meta( 'display_name', $post->post_author );
226
+ case '%author_link%':
227
+ return $this->authorLink();
228
+ default:
229
+ return '';
230
+ }
231
+ }
232
+
233
+ /**
234
+ * Returns a link to the site (homepage) with the site title as anchor text.
235
+ *
236
+ * @since 3.7.0
237
+ *
238
+ * @return string The site link.
239
+ */
240
+ private function siteLink() {
241
+ $name = get_bloginfo( 'name' );
242
+ if ( ! $name ) {
243
+ $homeUrl = home_url();
244
+ return $this->buildLink( $homeUrl, $homeUrl );
245
+ }
246
+
247
+ return $this->buildLink( home_url(), $name );
248
+ }
249
+
250
+ /**
251
+ * Returns a link to the current post with the post title as anchor text.
252
+ *
253
+ * @since 3.7.0
254
+ *
255
+ * @return string The post link.
256
+ */
257
+ private function postLink() {
258
+ $post = get_post();
259
+ if ( ! $post || ! $post->post_title ) {
260
+ $permalink = get_permalink();
261
+ return $this->buildLink( $permalink, $permalink );
262
+ }
263
+
264
+ return $this->buildLink( get_permalink(), $post->post_title );
265
+ }
266
+
267
+ /**
268
+ * Returns a link to the archive of the author of a given post with the author name as anchor text.
269
+ *
270
+ * @since 3.7.0
271
+ *
272
+ * @return string The author archive link.
273
+ */
274
+ private function authorLink() {
275
+ $post = get_post();
276
+ if ( ! $post || ! $post->post_author ) {
277
+ return '';
278
+ }
279
+
280
+ $name = get_the_author_meta( 'display_name', $post->post_author );
281
+ if ( ! $name ) {
282
+ $authorUrl = get_author_posts_url( $post->post_author );
283
+ return $this->buildLink( $authorUrl, $authorUrl );
284
+ }
285
+ return $this->buildLink( get_author_posts_url( $post->post_author ), $name );
286
+ }
287
+
288
+ /**
289
+ * Builds the link element.
290
+ *
291
+ * Acts as a helper function for siteLink(), postLink() and authorLink().
292
+ *
293
+ * @param string $url The URL.
294
+ * @param string $anchorText The anchor text.
295
+ * @return string The link element.
296
+ */
297
+ private function buildLink( $url, $anchorText ) {
298
+ return sprintf(
299
+ '<a href="%1$s" target="_blank">%2$s</a>',
300
+ trailingslashit( $url ),
301
+ $anchorText
302
+ );
303
+ }
304
+ }
inc/schema/aioseop-context.php CHANGED
@@ -458,6 +458,8 @@ class AIOSEOP_Context {
458
  // $wp_props['user_login'] = $object->user_login;
459
  $wp_props['site_id'] = $object->site_id;
460
  break;
 
 
461
  }
462
 
463
  // Also get only the object properties that match in $context['wp_props'] | $context->wp_props.
@@ -700,11 +702,6 @@ class AIOSEOP_Context {
700
 
701
  case 'WP_Post':
702
  if ( 'attachment' === $wp_obj->post_type ) {
703
- // Source URL.
704
- // May need to check setting for attachment redirect.
705
- // Use $this->get_images() to get attachment link.
706
- // $url = wp_get_attachment_url( $wp_obj->ID );
707
- // (Attachment) Post URL.
708
  $url = get_permalink( $wp_obj );
709
  } else {
710
  $url = wp_get_canonical_url( $wp_obj );
@@ -868,46 +865,6 @@ class AIOSEOP_Context {
868
  return $desc;
869
  }
870
 
871
- /**
872
- * Get Image Context
873
- *
874
- * Returns Image ID (Context Key) if possible, and Image URL.
875
- *
876
- * This is used to get the Image WP_Post object via $context.
877
- *
878
- * attachment post parent.
879
- * registered images to post.
880
- * post content.
881
- *
882
- * @param string|array
883
- * @return array {
884
- * @type int|string $id
885
- * @type string $url
886
- * }
887
- */
888
- public function get_images( $sources = 'all' ) {
889
- $image = array();
890
- switch ( $this->context_type ) {
891
- case 'WP_Post':
892
- $wp_obj = self::get_object( $this->context_type, $this->context_key );
893
- if ( ! $wp_obj ) {
894
- $this->log_error();
895
- return $image;
896
- }
897
-
898
- if ( 'attachment' === $wp_obj->post_type ) {
899
- $images['attachments'][] = array(
900
- 'id' => $wp_obj->ID,
901
- 'url' => wp_get_attachment_url( $wp_obj->ID ),
902
- );
903
- }
904
-
905
- $media_list = get_attached_media( 'image', $wp_obj );
906
-
907
- break;
908
- }
909
- }
910
-
911
  /**
912
  * Get Breadcrumb
913
  *
@@ -1024,6 +981,8 @@ class AIOSEOP_Context {
1024
  )
1025
  );
1026
  break;
 
 
1027
  }
1028
 
1029
  // Add Homepage as root/base.
458
  // $wp_props['user_login'] = $object->user_login;
459
  $wp_props['site_id'] = $object->site_id;
460
  break;
461
+ default:
462
+ break;
463
  }
464
 
465
  // Also get only the object properties that match in $context['wp_props'] | $context->wp_props.
702
 
703
  case 'WP_Post':
704
  if ( 'attachment' === $wp_obj->post_type ) {
 
 
 
 
 
705
  $url = get_permalink( $wp_obj );
706
  } else {
707
  $url = wp_get_canonical_url( $wp_obj );
865
  return $desc;
866
  }
867
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
868
  /**
869
  * Get Breadcrumb
870
  *
981
  )
982
  );
983
  break;
984
+ default:
985
+ break;
986
  }
987
 
988
  // Add Homepage as root/base.
inc/schema/graphs/graph-article.php CHANGED
@@ -141,7 +141,7 @@ class AIOSEOP_Graph_Article extends AIOSEOP_Graph_CreativeWork {
141
  } else {
142
  $content_image_url = $this->get_image_url_from_content( $post );
143
  if ( ! empty( $content_image_url ) ) {
144
- $rtn_image_data = wp_parse_args( $this->get_image_data_defaults(), array( 'url' => $content_image_url ) );
145
  } else {
146
  $blog_logo = get_theme_mod( 'custom_logo' );
147
  if ( $blog_logo ) {
141
  } else {
142
  $content_image_url = $this->get_image_url_from_content( $post );
143
  if ( ! empty( $content_image_url ) ) {
144
+ $rtn_image_data = wp_parse_args( array( 'url' => $content_image_url ), $this->get_image_data_defaults() );
145
  } else {
146
  $blog_logo = get_theme_mod( 'custom_logo' );
147
  if ( $blog_logo ) {
inc/schema/graphs/graph.php CHANGED
@@ -226,7 +226,10 @@ abstract class AIOSEOP_Graph {
226
  */
227
  protected function get_site_image_data( $image_id ) {
228
  if ( ! is_numeric( $image_id ) ) {
229
- return false;
 
 
 
230
  }
231
 
232
  // Defaults.
226
  */
227
  protected function get_site_image_data( $image_id ) {
228
  if ( ! is_numeric( $image_id ) ) {
229
+ $image_id = attachment_url_to_postid( $image_id );
230
+ if ( ! $image_id ) {
231
+ return false;
232
+ }
233
  }
234
 
235
  // Defaults.
js/admin/aioseop-quickedit.js CHANGED
@@ -138,7 +138,7 @@ var aioseopQuickEdit;
138
  "/": '&#x2F;',
139
  };
140
  const reg = /[&<>"'/]/ig;
141
- return string.replace(reg, (match)=>(map[match]));
142
  }
143
  }
144
 
138
  "/": '&#x2F;',
139
  };
140
  const reg = /[&<>"'/]/ig;
141
+ return string.replace(reg, (match)=>(map[match])).trim();
142
  }
143
  }
144
 
js/admin/aioseop-rss-content.js ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var aioseopRssContentDescription;
2
+
3
+ (function($) {
4
+ aioseopRssContentDescription = {
5
+ init: function() {
6
+ $('#aiosp_rss_content_metabox .inside .aiosp_settings').first().prepend( aioseopRssContent.description );
7
+ $('#aiosp_rss_content_metabox .inside .aiosp_settings').first().append( aioseopRssContent.listOfTags );
8
+ }
9
+ }
10
+ })(jQuery);
11
+
12
+ aioseopRssContentDescription.init();
modules/aioseop_importer_exporter.php CHANGED
@@ -38,8 +38,7 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Importer_Exporter' ) ) {
38
  'name' => __( 'Export Settings', 'all-in-one-seo-pack' ),
39
  'type' => 'multicheckbox',
40
  'initial_options' => array(
41
- 1 => __( 'General Settings', 'all-in-one-seo-pack' ),
42
- 2 => __( 'Post Data', 'all-in-one-seo-pack' ),
43
  ),
44
  ),
45
  'export_post_types' => array(
@@ -56,13 +55,7 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Importer_Exporter' ) ) {
56
  'import_export_help' => array(
57
  'type' => 'html',
58
  'label' => 'none',
59
- 'default' => __(
60
- 'Note: If General Settings is checked, the
61
- General Settings, the Feature Manager settings,
62
- and the following currently active modules will
63
- have their settings data exported:',
64
- 'all-in-one-seo-pack'
65
- ) . '<br />',
66
  ),
67
  );
68
 
@@ -128,34 +121,34 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Importer_Exporter' ) ) {
128
  $post_types,
129
  $rempost
130
  );
131
- global $aioseop_modules;
132
  if ( ! empty( $aioseop_modules ) ) {
133
  $modules = $aioseop_modules->get_loaded_module_list();
134
  if ( ! empty( $modules ) && ! empty( $modules['feature_manager'] ) ) {
135
  unset( $modules['feature_manager'] );
136
  }
137
  if ( ! empty( $modules ) ) {
138
- $this->default_options['import_export_help']['default'] .= "<ul>\n";
139
  foreach ( $modules as $m ) {
 
 
 
 
 
 
 
 
 
140
  $module = $aioseop_modules->return_module( $m );
141
  $this->default_options['import_export_help']['default'] .=
142
  "\t<li>" . $module->name . "</li>\n";
143
  }
144
  $this->default_options['import_export_help']['default'] .= "\n</ul>\n";
145
  } else {
146
- $this->default_options['import_export_help']['default'] .= '<br />'
147
- . __(
148
- 'There are no other modules currently loaded!',
149
- 'all-in-one-seo-pack'
150
- );
151
  }
152
  }
153
- $this->default_options['import_export_help']['default'] .= '<br />'
154
- . __(
155
- 'You may change this by activating or deactivating
156
- modules in the Feature Manager.',
157
- 'all-in-one-seo-pack'
158
- );
159
  $this->update_options();
160
  if ( ! empty( $_REQUEST['export_submit'] ) ) {
161
  $this->do_importer_exporter();
@@ -556,6 +549,8 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Importer_Exporter' ) ) {
556
  echo $buf;
557
  die();
558
  break;
 
 
559
  }
560
  }
561
  }
38
  'name' => __( 'Export Settings', 'all-in-one-seo-pack' ),
39
  'type' => 'multicheckbox',
40
  'initial_options' => array(
41
+ 1 => ''
 
42
  ),
43
  ),
44
  'export_post_types' => array(
55
  'import_export_help' => array(
56
  'type' => 'html',
57
  'label' => 'none',
58
+ 'default' => __( '<strong>Note:</strong> If Export Settings is checked, the General Settings, Feature Manager settings, and the following active modules will have their settings exported:', 'all-in-one-seo-pack' ) . '<br />',
 
 
 
 
 
 
59
  ),
60
  );
61
 
121
  $post_types,
122
  $rempost
123
  );
124
+ global $aioseop_modules, $aioseop_options;
125
  if ( ! empty( $aioseop_modules ) ) {
126
  $modules = $aioseop_modules->get_loaded_module_list();
127
  if ( ! empty( $modules ) && ! empty( $modules['feature_manager'] ) ) {
128
  unset( $modules['feature_manager'] );
129
  }
130
  if ( ! empty( $modules ) ) {
131
+ $this->default_options['import_export_help']['default'] .= "<ul class='aioseop-importer-exporter-active-modules'>\n";
132
  foreach ( $modules as $m ) {
133
+ if (
134
+ ! AIOSEOPPRO ||
135
+ ! isset( $aioseop_options['plan'] ) ||
136
+ ! in_array( $aioseop_options['plan'], array( 'business', 'agency' ) )
137
+ ) {
138
+ if ( in_array( $m, array( 'AIOSEOP_Schema_Local_Business', 'All_in_One_SEO_Pack_Image_Seo' ) ) ) {
139
+ continue;
140
+ }
141
+ }
142
  $module = $aioseop_modules->return_module( $m );
143
  $this->default_options['import_export_help']['default'] .=
144
  "\t<li>" . $module->name . "</li>\n";
145
  }
146
  $this->default_options['import_export_help']['default'] .= "\n</ul>\n";
147
  } else {
148
+ $this->default_options['import_export_help']['default'] .= __( 'There are no other modules currently loaded!', 'all-in-one-seo-pack' );
 
 
 
 
149
  }
150
  }
151
+ $this->default_options['import_export_help']['default'] .= __( 'You may change this by activating or deactivating modules in the Feature Manager.', 'all-in-one-seo-pack' );
 
 
 
 
 
152
  $this->update_options();
153
  if ( ! empty( $_REQUEST['export_submit'] ) ) {
154
  $this->do_importer_exporter();
549
  echo $buf;
550
  die();
551
  break;
552
+ default:
553
+ break;
554
  }
555
  }
556
  }
modules/aioseop_opengraph.php CHANGED
@@ -345,12 +345,12 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Opengraph' ) ) {
345
  ),
346
  'dimgwidth' => array(
347
  'name' => __( 'Default Image Width', 'all-in-one-seo-pack' ),
348
- 'type' => 'text',
349
  'default' => '',
350
  ),
351
  'dimgheight' => array(
352
  'name' => __( 'Default Image Height', 'all-in-one-seo-pack' ),
353
- 'type' => 'text',
354
  'default' => '',
355
  ),
356
  'meta_key' => array(
@@ -371,12 +371,12 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Opengraph' ) ) {
371
  ),
372
  'imagewidth' => array(
373
  'name' => __( 'Specify Image Width', 'all-in-one-seo-pack' ),
374
- 'type' => 'text',
375
  'default' => '',
376
  ),
377
  'imageheight' => array(
378
  'name' => __( 'Specify Image Height', 'all-in-one-seo-pack' ),
379
- 'type' => 'text',
380
  'default' => '',
381
  ),
382
  'video' => array(
@@ -385,7 +385,7 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Opengraph' ) ) {
385
  ),
386
  'videowidth' => array(
387
  'name' => __( 'Specify Video Width', 'all-in-one-seo-pack' ),
388
- 'type' => 'text',
389
  'default' => '',
390
  'condshow' => array(
391
  'aioseop_opengraph_settings_video' => array(
@@ -397,7 +397,7 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Opengraph' ) ) {
397
  ),
398
  'videoheight' => array(
399
  'name' => __( 'Specify Video Height', 'all-in-one-seo-pack' ),
400
- 'type' => 'text',
401
  'default' => '',
402
  'condshow' => array(
403
  'aioseop_opengraph_settings_video' => array(
@@ -1619,6 +1619,8 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Opengraph' ) ) {
1619
  $value = 'website';
1620
  }
1621
  break;
 
 
1622
  }
1623
 
1624
  // TODO Remove when `$tmp_meta_slug` is removed from 'aiosp_opengraph_disable_meta_tag_truncation' filter.
@@ -1655,6 +1657,8 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Opengraph' ) ) {
1655
  case 'twitter:description':
1656
  $value = trim( AIOSEOP_PHP_Functions::substr( $value, 0, 200 ) );
1657
  break;
 
 
1658
  }
1659
  }
1660
 
@@ -2005,9 +2009,7 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Opengraph' ) ) {
2005
  $prefix = $this->get_prefix( $k );
2006
  $options = apply_filters( $prefix . 'filter_term_metabox_options', $options, $k, $term_id );
2007
  foreach ( $options as $option ) {
2008
- if ( is_string( $option ) ) {
2009
- $option = esc_html( $option );
2010
- }
2011
  }
2012
  update_term_meta( $term_id, '_' . $prefix . $k, $options );
2013
  }
345
  ),
346
  'dimgwidth' => array(
347
  'name' => __( 'Default Image Width', 'all-in-one-seo-pack' ),
348
+ 'type' => 'number',
349
  'default' => '',
350
  ),
351
  'dimgheight' => array(
352
  'name' => __( 'Default Image Height', 'all-in-one-seo-pack' ),
353
+ 'type' => 'number',
354
  'default' => '',
355
  ),
356
  'meta_key' => array(
371
  ),
372
  'imagewidth' => array(
373
  'name' => __( 'Specify Image Width', 'all-in-one-seo-pack' ),
374
+ 'type' => 'number',
375
  'default' => '',
376
  ),
377
  'imageheight' => array(
378
  'name' => __( 'Specify Image Height', 'all-in-one-seo-pack' ),
379
+ 'type' => 'number',
380
  'default' => '',
381
  ),
382
  'video' => array(
385
  ),
386
  'videowidth' => array(
387
  'name' => __( 'Specify Video Width', 'all-in-one-seo-pack' ),
388
+ 'type' => 'number',
389
  'default' => '',
390
  'condshow' => array(
391
  'aioseop_opengraph_settings_video' => array(
397
  ),
398
  'videoheight' => array(
399
  'name' => __( 'Specify Video Height', 'all-in-one-seo-pack' ),
400
+ 'type' => 'number',
401
  'default' => '',
402
  'condshow' => array(
403
  'aioseop_opengraph_settings_video' => array(
1619
  $value = 'website';
1620
  }
1621
  break;
1622
+ default:
1623
+ break;
1624
  }
1625
 
1626
  // TODO Remove when `$tmp_meta_slug` is removed from 'aiosp_opengraph_disable_meta_tag_truncation' filter.
1657
  case 'twitter:description':
1658
  $value = trim( AIOSEOP_PHP_Functions::substr( $value, 0, 200 ) );
1659
  break;
1660
+ default:
1661
+ break;
1662
  }
1663
  }
1664
 
2009
  $prefix = $this->get_prefix( $k );
2010
  $options = apply_filters( $prefix . 'filter_term_metabox_options', $options, $k, $term_id );
2011
  foreach ( $options as $option ) {
2012
+ $option = aioseop_sanitize( $option );
 
 
2013
  }
2014
  update_term_meta( $term_id, '_' . $prefix . $k, $options );
2015
  }
modules/aioseop_robots.php CHANGED
@@ -290,6 +290,8 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Robots' ) ) {
290
  $rule[ 'type' ] = $operand;
291
  $rule[ 'path' ] = $array[1];
292
  break;
 
 
293
  }
294
  if ( $rule ) {
295
  $rule = $this->validate_rule( $blog_rules, $rule );
@@ -803,6 +805,8 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Robots' ) ) {
803
  $buf .= $this->do_robots();
804
  $buf .= "</textarea>";
805
  break;
 
 
806
  }
807
 
808
  $args['options']['type'] = 'hidden';
290
  $rule[ 'type' ] = $operand;
291
  $rule[ 'path' ] = $array[1];
292
  break;
293
+ default:
294
+ break;
295
  }
296
  if ( $rule ) {
297
  $rule = $this->validate_rule( $blog_rules, $rule );
805
  $buf .= $this->do_robots();
806
  $buf .= "</textarea>";
807
  break;
808
+ default:
809
+ break;
810
  }
811
 
812
  $args['options']['type'] = 'hidden';
modules/aioseop_sitemap.php CHANGED
@@ -188,7 +188,7 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
188
  ),
189
  'max_posts' => array(
190
  'name' => __( 'Maximum Posts Per Sitemap Page', 'all-in-one-seo-pack' ),
191
- 'type' => 'text',
192
  'default' => 1000,
193
  'condshow' => array(
194
  "{$this->prefix}indexes" => 'on',
@@ -1054,13 +1054,16 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
1054
  $url = aioseop_home_url( '/' . 'video-sitemap.xml' );
1055
  break;
1056
  }
 
 
1057
  }
1058
-
1059
- $rule = $this->get_rewrite_url( $url );
1060
- $rules = $this->get_rewrite_rules();
1061
- // TODO Add `true` in 3rd argument with in_array(); which changes it to a strict comparison.
1062
- if ( ! in_array( $rule, $rules ) ) {
1063
- $options[ $this->prefix . 'link' ] .= '<strong>' . __( 'Dynamic sitemap generation does not appear to be using the correct rewrite rules; please disable any other sitemap plugins or functionality on your site and reset your permalinks.', 'all-in-one-seo-pack' ) . '</strong>';
 
1064
  }
1065
  }
1066
  if ( ! get_option( 'blog_public' ) ) {
@@ -3558,7 +3561,7 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
3558
  $args['numberposts']
3559
  );
3560
 
3561
- $key = md5( $sql_query );
3562
  $last_changed = wp_cache_get_last_changed( 'posts' );
3563
  $key = "aioseop_get_date_archive_data:$key:$last_changed";
3564
  $date_results = wp_cache_get( $key, 'posts' );
@@ -3665,8 +3668,7 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
3665
  continue;
3666
  }
3667
 
3668
- $post_types = array( $post_type );
3669
- if ( ! in_array( $post_type, apply_filters( "{$this->prefix}include_post_types_archives", $post_types ) ) ) {
3670
  continue;
3671
  }
3672
 
@@ -4043,7 +4045,10 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
4043
  if ( is_null( $post_thumbnails ) || defined( 'AIOSEOP_UNIT_TESTING' ) ) {
4044
  global $wpdb;
4045
 
4046
- $post_thumbnails = $wpdb->get_results( "SELECT post_ID, meta_value FROM $wpdb->postmeta WHERE meta_key = '_thumbnail_id'", ARRAY_A );
 
 
 
4047
 
4048
  if ( $post_thumbnails ) {
4049
  $post_thumbnails = array_combine(
188
  ),
189
  'max_posts' => array(
190
  'name' => __( 'Maximum Posts Per Sitemap Page', 'all-in-one-seo-pack' ),
191
+ 'type' => 'number',
192
  'default' => 1000,
193
  'condshow' => array(
194
  "{$this->prefix}indexes" => 'on',
1054
  $url = aioseop_home_url( '/' . 'video-sitemap.xml' );
1055
  break;
1056
  }
1057
+ default:
1058
+ break;
1059
  }
1060
+
1061
+ if ( $url ) {
1062
+ $rule = $this->get_rewrite_url( $url );
1063
+ $rules = $this->get_rewrite_rules();
1064
+ if ( ! in_array( $rule, $rules, true ) ) {
1065
+ $options[ $this->prefix . 'link' ] .= '<strong>' . __( 'Dynamic sitemap generation does not appear to be using the correct rewrite rules; please disable any other sitemap plugins or functionality on your site and reset your permalinks.', 'all-in-one-seo-pack' ) . '</strong>';
1066
+ }
1067
  }
1068
  }
1069
  if ( ! get_option( 'blog_public' ) ) {
3561
  $args['numberposts']
3562
  );
3563
 
3564
+ $key = hash( 'sha256', $sql_query );
3565
  $last_changed = wp_cache_get_last_changed( 'posts' );
3566
  $key = "aioseop_get_date_archive_data:$key:$last_changed";
3567
  $date_results = wp_cache_get( $key, 'posts' );
3668
  continue;
3669
  }
3670
 
3671
+ if ( ! in_array( $post_type, apply_filters( "{$this->prefix}include_post_types_archives", array( $post_type ) ) ) ) {
 
3672
  continue;
3673
  }
3674
 
4045
  if ( is_null( $post_thumbnails ) || defined( 'AIOSEOP_UNIT_TESTING' ) ) {
4046
  global $wpdb;
4047
 
4048
+ $post_thumbnails = $wpdb->get_results(
4049
+ "SELECT post_ID, meta_value FROM {$wpdb->postmeta} WHERE meta_key = '_thumbnail_id'",
4050
+ ARRAY_A
4051
+ );
4052
 
4053
  if ( $post_thumbnails ) {
4054
  $post_thumbnails = array_combine(
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: semperplugins, smub, benjaminprojas
3
  Tags: SEO, Google Search Console, XML Sitemap, meta description, meta title, noindex
4
  Requires at least: 4.9
5
- Tested up to: 5.4.2
6
- Stable tag: 3.6.2
7
  License: GPLv2 or later
8
  Requires PHP: 5.2.4
9
 
2
  Contributors: semperplugins, smub, benjaminprojas
3
  Tags: SEO, Google Search Console, XML Sitemap, meta description, meta title, noindex
4
  Requires at least: 4.9
5
+ Tested up to: 5.5
6
+ Stable tag: 3.7.0
7
  License: GPLv2 or later
8
  Requires PHP: 5.2.4
9