All in One SEO Pack - Version 3.6.1

Version Description

Download this release

Release Info

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

Code changes from version 3.5.2 to 3.6.1

Files changed (38) hide show
  1. admin/aioseop_module_class.php +48 -4
  2. admin/aioseop_module_manager.php +4 -5
  3. admin/class-aioseop-helper.php +6 -4
  4. admin/class-aioseop-notices.php +385 -14
  5. admin/display/aioseop-welcome.php +146 -0
  6. admin/display/credits-content.php +0 -99
  7. admin/display/notice-default.php +1 -1
  8. admin/display/notice-remote.php +51 -0
  9. admin/display/notices/local-business-notice.php +33 -0
  10. admin/display/notices/news-sitemap-notice.php +40 -0
  11. admin/display/welcome-content.php +1 -1
  12. admin/display/welcome.php +0 -172
  13. aioseop_class.php +53 -32
  14. all_in_one_seo_pack.php +1 -1
  15. build/aioseop-link-attributes-gutenberg-editor.asset.php +0 -4
  16. build/aioseop-link-attributes-gutenberg-editor.js +0 -6
  17. class-aioseop-core.php +8 -21
  18. css/admin-toolbar-menu.css +33 -1
  19. css/admin/aioseop-about.css +6 -0
  20. css/aiosp_admin.css +53 -7
  21. css/modules/aioseop_module-rtl.css +1 -1
  22. css/modules/aioseop_module.css +54 -3
  23. images/default-thumbnail.png +0 -0
  24. inc/admin/class-aioseop-education.php +17 -14
  25. inc/admin/views/class-aioseop-about.php +12 -3
  26. inc/aioseop_updates_class.php +17 -8
  27. inc/general/aioseop-robots-meta.php +38 -0
  28. inc/schema/aioseop-context.php +61 -22
  29. inc/schema/graphs/graph-organization.php +13 -2
  30. js/admin-notice.js +68 -1
  31. js/admin/aioseop-preview-snippet.js +5 -1
  32. js/admin/education/aioseop-news-sitemap-upsell.js +4 -3
  33. js/welcome.js +0 -32
  34. modules/aioseop_feature_manager.php +17 -5
  35. modules/aioseop_schema_local_business.php +10 -0
  36. modules/aioseop_sitemap.php +73 -3
  37. public/google-analytics.php +1 -1
  38. readme.txt +2 -2
admin/aioseop_module_class.php CHANGED
@@ -2535,6 +2535,30 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Module' ) ) {
2535
  }
2536
  $buf .= "<textarea name='$name' $attr>$value</textarea>";
2537
  break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2538
  case 'image':
2539
  $buf .= '<input class="aioseop_upload_image_checker" type="hidden" name="' . $name . '_checker" value="0">' .
2540
  "<input class='aioseop_upload_image_button button-primary' type='button' value='";
@@ -2800,6 +2824,11 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Module' ) ) {
2800
  case 'filename':
2801
  $this->options[ $k ] = sanitize_file_name( $this->options[ $k ] );
2802
  break;
 
 
 
 
 
2803
  case 'url':
2804
  // fall through.
2805
  case 'text':
@@ -2889,11 +2918,26 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Module' ) ) {
2889
  /* translators: %s is a placeholder and will be replace with the name of the plugin. */
2890
  $message = sprintf( __( '%s Options Updated.', 'all-in-one-seo-pack' ), AIOSEOP_PLUGIN_NAME );
2891
  $default_options = $this->default_options( $location );
2892
- foreach ( $default_options as $k => $v ) {
2893
- if ( isset( $_POST[ $k ] ) ) {
2894
- $this->options[ $k ] = stripslashes_deep( $_POST[ $k ] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2895
  } else {
2896
- $this->options[ $k ] = '';
2897
  }
2898
  }
2899
  $this->sanitize_options( $location );
2535
  }
2536
  $buf .= "<textarea name='$name' $attr>$value</textarea>";
2537
  break;
2538
+ case 'address':
2539
+ $address_defaults = array(
2540
+ 'street_address' => '',
2541
+ 'address_locality' => '',
2542
+ 'address_region' => '',
2543
+ 'postal_code' => '',
2544
+ 'address_country' => '',
2545
+ );
2546
+ $value = wp_parse_args( $value, $address_defaults );
2547
+
2548
+ $buf .= '
2549
+ <label for="' . $name . '_street_address" class="aioseop_label_street_address">' . __( 'Street Address', 'all-in-one-seo-pack' ) . '</label>
2550
+ <input name="' . $name . '_street_address" class="aioseop_input_street_address" type="text" ' . $attr . ' value="' . $value['street_address'] . '" />
2551
+ <label for="' . $name . '_address_locality" class="aioseop_label_address_locality">' . __( 'City', 'all-in-one-seo-pack' ) . '</label>
2552
+ <input name="' . $name . '_address_locality" class="aioseop_input_address_locality" type="text" ' . $attr . ' value="' . $value['address_locality'] . '" />
2553
+ <label for="' . $name . '_address_region" class="aioseop_label_address_region">' . __( 'State', 'all-in-one-seo-pack' ) . '</label>
2554
+ <input name="' . $name . '_address_region" class="aioseop_input_address_region" type="text" ' . $attr . ' value="' . $value['address_region'] . '" />
2555
+ <label for="' . $name . '_postal_code" class="aioseop_label_postal_code">' . __( 'Zip code', 'all-in-one-seo-pack' ) . '</label>
2556
+ <input name="' . $name . '_postal_code" class="aioseop_input_postal_code" type="text" ' . $attr . ' value="' . $value['postal_code'] . '" />
2557
+ <label for="' . $name . '_address_country" class="aioseop_label_address_country">' . __( 'Country', 'all-in-one-seo-pack' ) . '</label>
2558
+ <input name="' . $name . '_address_country" class="aioseop_input_address_country" type="text" ' . $attr . ' value="' . $value['address_country'] . '" />
2559
+ ';
2560
+ $buf = '<div class="aioseop_postal_address">' . $buf . '</div>';
2561
+ break;
2562
  case 'image':
2563
  $buf .= '<input class="aioseop_upload_image_checker" type="hidden" name="' . $name . '_checker" value="0">' .
2564
  "<input class='aioseop_upload_image_button button-primary' type='button' value='";
2824
  case 'filename':
2825
  $this->options[ $k ] = sanitize_file_name( $this->options[ $k ] );
2826
  break;
2827
+ case 'address':
2828
+ foreach ( $this->options[ $k ] as &$address_value ) {
2829
+ $address_value = wp_kses_post( $address_value );
2830
+ }
2831
+ break;
2832
  case 'url':
2833
  // fall through.
2834
  case 'text':
2918
  /* translators: %s is a placeholder and will be replace with the name of the plugin. */
2919
  $message = sprintf( __( '%s Options Updated.', 'all-in-one-seo-pack' ), AIOSEOP_PLUGIN_NAME );
2920
  $default_options = $this->default_options( $location );
2921
+ $prefix = $this->prefix;
2922
+ foreach ( $this->default_options as $k => $option_arr ) {
2923
+ if ( isset( $option_arr['type'] ) && 'address' === $option_arr['type'] ) {
2924
+ $address_values = array(
2925
+ 'street_address' => '',
2926
+ 'address_locality' => '',
2927
+ 'address_region' => '',
2928
+ 'postal_code' => '',
2929
+ 'address_country' => '',
2930
+ );
2931
+ foreach ( $address_values as $address_key => &$address_value ) {
2932
+ if ( isset( $_POST[ $prefix . $k . '_' . $address_key ] ) ) {
2933
+ $address_value = stripslashes_deep( $_POST[ $prefix . $k . '_' . $address_key ] );
2934
+ }
2935
+ }
2936
+ $this->options[ $prefix . $k ] = $address_values;
2937
+ } elseif ( isset( $_POST[ $prefix . $k ] ) ) {
2938
+ $this->options[ $prefix . $k ] = stripslashes_deep( $_POST[ $prefix . $k ] );
2939
  } else {
2940
+ $this->options[ $prefix . $k ] = '';
2941
  }
2942
  }
2943
  $this->sanitize_options( $location );
admin/aioseop_module_manager.php CHANGED
@@ -261,13 +261,12 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Module_Manager' ) ) {
261
 
262
  // Don't load Pro modules if Pro was previously installed.
263
  switch ( $mod ) {
264
- case 'video_sitemap': // phpcs:ignore PSR2.ControlStructures.SwitchDeclaration
265
- case 'image_seo': { // phpcs:ignore PSR2.ControlStructures.SwitchDeclaration
 
266
  break;
267
- }
268
- default: { // phpcs:ignore PSR2.ControlStructures.SwitchDeclaration
269
  return $this->do_load_module( $mod );
270
- }
271
  }
272
  }
273
 
261
 
262
  // Don't load Pro modules if Pro was previously installed.
263
  switch ( $mod ) {
264
+ case 'schema_local_business':
265
+ case 'video_sitemap':
266
+ case 'image_seo':
267
  break;
268
+ default:
 
269
  return $this->do_load_module( $mod );
 
270
  }
271
  }
272
 
admin/class-aioseop-helper.php CHANGED
@@ -714,8 +714,9 @@ class AIOSEOP_Helper {
714
  'aiosp_sitemap_excl_pages' => __( 'Use page slugs or page IDs, separated by commas, to exclude pages from the sitemap.', 'all-in-one-seo-pack' ),
715
 
716
  // Additional Sitemaps
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
 
720
  // Priorities.
721
  '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' ) ),
@@ -756,7 +757,6 @@ class AIOSEOP_Helper {
756
 
757
  $help_doc_link = array(
758
  // XML Sitemap.
759
- 'aiosp_sitemap_rss_sitemap' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#create-rss_sitemap',
760
  'aiosp_sitemap_daily_cron' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#schedule-updates',
761
  'aiosp_sitemap_indexes' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#enable-sitemap-indexes',
762
  'aiosp_sitemap_max_posts' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#enable-sitemap-indexes',
@@ -769,7 +769,9 @@ class AIOSEOP_Helper {
769
  'aiosp_sitemap_rewrite' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#dynamically-generate-sitemap',
770
 
771
  // Additional Sitemaps
772
- 'aiosp_sitemap_posttypes_news' => 'https://semperplugins.com/documentation/google-news-sitemap/',
 
 
773
 
774
  // Additional Pages.
775
  'aiosp_sitemap_addl_url' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#additional-pages',
714
  'aiosp_sitemap_excl_pages' => __( 'Use page slugs or page IDs, separated by commas, to exclude pages from the sitemap.', 'all-in-one-seo-pack' ),
715
 
716
  // Additional Sitemaps
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' ) ),
757
 
758
  $help_doc_link = array(
759
  // XML Sitemap.
 
760
  'aiosp_sitemap_daily_cron' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#schedule-updates',
761
  'aiosp_sitemap_indexes' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#enable-sitemap-indexes',
762
  'aiosp_sitemap_max_posts' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#enable-sitemap-indexes',
769
  'aiosp_sitemap_rewrite' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#dynamically-generate-sitemap',
770
 
771
  // Additional Sitemaps
772
+ 'aiosp_sitemap_rss_sitemap' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#create-rss_sitemap',
773
+ 'aiosp_sitemap_posttypes_news' => 'https://semperplugins.com/documentation/google-news-sitemap/',
774
+ 'aiosp_sitemap_publication_name' => 'https://semperplugins.com/documentation/google-news-sitemap/',
775
 
776
  // Additional Pages.
777
  'aiosp_sitemap_addl_url' => 'https://semperplugins.com/documentation/xml-sitemaps-module/#additional-pages',
admin/class-aioseop-notices.php CHANGED
@@ -59,6 +59,35 @@ if ( ! class_exists( 'AIOSEOP_Notices' ) ) {
59
  */
60
  public $notices = array();
61
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  /**
63
  * List of notice slugs that are currently active.
64
  * NOTE: Amount is reduced by 1 second in order to display at exactly X amount of time.
@@ -82,11 +111,11 @@ if ( ! class_exists( 'AIOSEOP_Notices' ) ) {
82
  *
83
  * @since 3.0
84
  *
85
- * @var array $dismissed {
86
  * @type boolean $notice_slug => $is_dismissed True if dismissed.
87
  * }
88
  */
89
- public $dismissed = array();
90
 
91
  /**
92
  * The default dismiss time. An anti-nag setting.
@@ -132,6 +161,8 @@ if ( ! class_exists( 'AIOSEOP_Notices' ) ) {
132
  add_action( 'admin_init', array( $this, 'init' ) );
133
  add_action( 'current_screen', array( $this, 'admin_screen' ) );
134
  }
 
 
135
  }
136
 
137
  /**
@@ -179,6 +210,204 @@ if ( ! class_exists( 'AIOSEOP_Notices' ) ) {
179
  */
180
  public function init() {
181
  add_action( 'wp_ajax_aioseop_notice', array( $this, 'ajax_notice_action' ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
182
  }
183
 
184
  /**
@@ -198,6 +427,7 @@ if ( ! class_exists( 'AIOSEOP_Notices' ) ) {
198
  // AIOSEO Notice Content.
199
  add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
200
  add_action( 'all_admin_notices', array( $this, 'display_notice_aioseop' ) );
 
201
  } elseif ( isset( $current_screen->id ) ) {
202
  // Default WP Notice.
203
  add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
@@ -219,8 +449,10 @@ if ( ! class_exists( 'AIOSEOP_Notices' ) ) {
219
  private function obj_load_options() {
220
  $notices_options = $this->obj_get_options();
221
 
222
- $this->notices = $notices_options['notices'];
223
- $this->active_notices = $notices_options['active_notices'];
 
 
224
  }
225
 
226
  /**
@@ -233,8 +465,10 @@ if ( ! class_exists( 'AIOSEOP_Notices' ) ) {
233
  */
234
  private function obj_get_options() {
235
  $defaults = array(
236
- 'notices' => array(),
237
- 'active_notices' => array(),
 
 
238
  );
239
 
240
  // Prevent old data from being loaded instead.
@@ -258,8 +492,10 @@ if ( ! class_exists( 'AIOSEOP_Notices' ) ) {
258
  */
259
  private function obj_update_options() {
260
  $notices_options = array(
261
- 'notices' => $this->notices,
262
- 'active_notices' => $this->active_notices,
 
 
263
  );
264
  $old_notices_options = $this->obj_get_options();
265
  $notices_options = wp_parse_args( $notices_options, $old_notices_options );
@@ -490,7 +726,7 @@ if ( ! class_exists( 'AIOSEOP_Notices' ) ) {
490
  $notice = $this->get_notice( $slug );
491
 
492
  unset( $this->active_notices[ $slug ] );
493
- unset( $this->dismissed[ $slug ] );
494
  delete_metadata(
495
  'user',
496
  0,
@@ -563,7 +799,7 @@ if ( ! class_exists( 'AIOSEOP_Notices' ) ) {
563
  public function set_notice_dismiss( $slug, $dismiss ) {
564
  $notice = $this->get_notice( $slug );
565
  if ( 'site' === $notice['target'] ) {
566
- $this->dismissed[ $slug ] = $dismiss;
567
  } elseif ( 'user' === $notice['target'] ) {
568
  $current_user_id = get_current_user_id();
569
 
@@ -657,9 +893,18 @@ if ( ! class_exists( 'AIOSEOP_Notices' ) ) {
657
  }
658
  }
659
 
 
 
 
 
 
 
 
 
660
  $admin_notice_localize = array(
661
  'notice_nonce' => wp_create_nonce( 'aioseop_ajax_notice' ),
662
  'notice_actions' => $notice_actions,
 
663
  );
664
  wp_localize_script( 'aioseop-admin-notice-js', 'aioseop_notice_data', $admin_notice_localize );
665
 
@@ -754,7 +999,7 @@ if ( ! class_exists( 'AIOSEOP_Notices' ) ) {
754
  continue;
755
  }
756
 
757
- if ( isset( $this->dismissed[ $a_notice_slug ] ) && $this->dismissed[ $a_notice_slug ] ) {
758
  $notice_show = false;
759
  }
760
 
@@ -787,6 +1032,100 @@ if ( ! class_exists( 'AIOSEOP_Notices' ) ) {
787
  }
788
  }
789
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
790
  /**
791
  * AJAX Notice Action
792
  *
@@ -822,10 +1161,10 @@ if ( ! class_exists( 'AIOSEOP_Notices' ) ) {
822
  }
823
  }
824
  if ( empty( $notice_slug ) ) {
825
- /* Translators: Displays the hordcoded slug that missing. */
826
  wp_send_json_error( sprintf( __( 'Missing values from `%s`.', 'all-in-one-seo-pack' ), 'notice_slug' ) );
827
  } elseif ( empty( $action_index ) && 0 !== (int) $action_index ) {
828
- /* Translators: Displays the hordcoded slug that missing. */
829
  wp_send_json_error( sprintf( __( 'Missing values from `%s`.', 'all-in-one-seo-pack' ), 'action_index' ) );
830
  }
831
 
@@ -850,9 +1189,41 @@ if ( ! class_exists( 'AIOSEOP_Notices' ) ) {
850
  wp_send_json_success( __( 'Notice updated successfully.', 'all-in-one-seo-pack' ) );
851
  }
852
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
853
  }
 
854
  // CLASS INITIALIZATION.
855
  // Should this be a singleton class instead of a global?
856
  global $aioseop_notices;
857
  $aioseop_notices = new AIOSEOP_Notices();
858
- }
59
  */
60
  public $notices = array();
61
 
62
+ /**
63
+ * Collection of remote notices.
64
+ *
65
+ * @since 3.6.0
66
+ *
67
+ * @var array $remote_notices => {
68
+ * @type array $id => {
69
+ * @type int $id Notice ID
70
+ * @type string $title The notification title.
71
+ * @type string $content Content of notification.
72
+ * @type array $type License levels/type.
73
+ * @type array $btns Notice buttons.
74
+ * @type string $start Time/Date to show notification.
75
+ * @type string $end Time/Date to hide notification.
76
+ * @type string $notification_type Notification type class.
77
+ * }
78
+ * }
79
+ */
80
+ public $remote_notices = array();
81
+
82
+ /**
83
+ * Source of remote notifications.
84
+ *
85
+ * @since 3.6.0
86
+ *
87
+ * @var string
88
+ */
89
+ public $remote_url = 'https://plugin-cdn.aioseo.com/wp-content/notifications.json';
90
+
91
  /**
92
  * List of notice slugs that are currently active.
93
  * NOTE: Amount is reduced by 1 second in order to display at exactly X amount of time.
111
  *
112
  * @since 3.0
113
  *
114
+ * @var array $dismissed_notices {
115
  * @type boolean $notice_slug => $is_dismissed True if dismissed.
116
  * }
117
  */
118
+ public $dismissed_notices = array();
119
 
120
  /**
121
  * The default dismiss time. An anti-nag setting.
161
  add_action( 'admin_init', array( $this, 'init' ) );
162
  add_action( 'current_screen', array( $this, 'admin_screen' ) );
163
  }
164
+
165
+ add_action( 'aioseop_cron_check_remote_notices', array( $this, 'cron_check_remote_notices' ) );
166
  }
167
 
168
  /**
210
  */
211
  public function init() {
212
  add_action( 'wp_ajax_aioseop_notice', array( $this, 'ajax_notice_action' ) );
213
+ add_action( 'wp_ajax_aioseop_remote_notice', array( $this, 'ajax_remote_notice_action' ) );
214
+
215
+ if ( ! wp_next_scheduled( 'aioseop_cron_check_remote_notices' ) ) {
216
+ wp_schedule_event( time(), 'daily', 'aioseop_cron_check_remote_notices' );
217
+ }
218
+ }
219
+
220
+ /**
221
+ * Check Remote Notices.
222
+ *
223
+ * @since 3.6.0
224
+ */
225
+ public function cron_check_remote_notices() {
226
+ $remote_notices = $this->get_remote_notices();
227
+
228
+ // Replace existing notices in case they were updated.
229
+ for ( $i = 0; $i < count( $this->remote_notices ); $i++ ) {
230
+ foreach ( $remote_notices as $remote_notice ) {
231
+ if ( $this->remote_notices[ $i ]['id'] === $remote_notice['id'] ) {
232
+ unset( $this->remote_notices[ $i ] );
233
+ }
234
+ }
235
+ }
236
+
237
+ $this->remote_notices = array_merge( $this->remote_notices, $remote_notices );
238
+
239
+ $this->obj_update_options();
240
+ }
241
+
242
+ /**
243
+ * Get Remote URL.
244
+ *
245
+ * Checks is a constant is defined (dev purposes), if not, then use URL in `$this->remote_url`.
246
+ *
247
+ * @since 3.6.0
248
+ *
249
+ * @return string
250
+ */
251
+ public function get_remote_url() {
252
+ if ( defined( 'AIOSEO_NOTIFICATIONS_URL' ) ) {
253
+ return AIOSEO_NOTIFICATIONS_URL;
254
+ }
255
+
256
+ return $this->remote_url;
257
+ }
258
+
259
+ /**
260
+ * Get Remote Notices.
261
+ *
262
+ * @since 3.6.0
263
+ *
264
+ * @return array
265
+ */
266
+ private function get_remote_notices() {
267
+ $res = wp_remote_get( $this->get_remote_url() );
268
+
269
+ if ( is_wp_error( $res ) ) {
270
+ return array();
271
+ }
272
+
273
+ $body = wp_remote_retrieve_body( $res );
274
+
275
+ if ( empty( $body ) ) {
276
+ return array();
277
+ }
278
+
279
+ return $this->validate_remote_notices( json_decode( $body, true ) );
280
+ }
281
+
282
+ /**
283
+ * Validate Remote Notices.
284
+ *
285
+ * @since 3.6.0
286
+ *
287
+ * @param $remote_notices
288
+ * @return array
289
+ */
290
+ private function validate_remote_notices( $remote_notices ) {
291
+ if ( ! is_array( $remote_notices ) || empty( $remote_notices ) ) {
292
+ return array();
293
+ }
294
+
295
+ $data = array();
296
+ $obj_options = $this->obj_get_options();
297
+ foreach ( $remote_notices as $remote_notice ) {
298
+ // Invalid notice if required variables have no value.
299
+ if (
300
+ empty( $remote_notice['content'] ) ||
301
+ empty( $remote_notice['type'] )
302
+ ) {
303
+ continue;
304
+ }
305
+
306
+ // If no 'start' time exists, set start to current time.
307
+ if ( ! isset( $remote_notice['start'] ) || empty( $remote_notice['start'] ) ) {
308
+ $remote_notice['start'] = date( 'Y-m-d H:i:s' );
309
+ }
310
+ // Skip if already expired.
311
+ if ( ! empty( $remote_notice['end'] ) && time() > strtotime( $remote_notice['end'] ) ) {
312
+ continue;
313
+ }
314
+
315
+ // Skip if already dismissed.
316
+ if ( in_array( 'remote_' . $remote_notice['id'], array_keys( $obj_options['dismissed_notices'] ) ) ) {
317
+ continue;
318
+ }
319
+
320
+ // Store notice if version matches.
321
+ if ( $this->version_match( AIOSEOP_VERSION, $remote_notice['type'] ) ) {
322
+ $data[ 'remote_' . $remote_notice['id'] ] = $remote_notice;
323
+ continue;
324
+ }
325
+
326
+ // Store notice if plan matches.
327
+ if ( AIOSEOPPRO ) {
328
+ if (
329
+ 'pro' === $remote_notice['type'] ||
330
+ in_array( $this->get_license_plan(), $remote_notice['type'], true )
331
+ ) {
332
+ $data[ 'remote_' . $remote_notice['id'] ] = $remote_notice;
333
+ }
334
+ } else {
335
+ if ( 'lite' === $remote_notice['type'] ) {
336
+ $data[ 'remote_' . $remote_notice['id'] ] = $remote_notice;
337
+ }
338
+ }
339
+ }
340
+ return $data;
341
+ }
342
+
343
+ /**
344
+ * Get License Level.
345
+ *
346
+ * @since 3.6.0
347
+ *
348
+ * @return string Type of license level being used.
349
+ */
350
+ public function get_license_plan() {
351
+ global $aioseop_options;
352
+
353
+ if ( ! isset( $aioseop_options['plan'] ) || empty( $aioseop_options['plan'] ) ) {
354
+ return AIOSEOPPRO ? 'unlicensed' : 'lite';
355
+ }
356
+ return $aioseop_options['plan'];
357
+ }
358
+
359
+ /**
360
+ * Version Compare.
361
+ *
362
+ * @since 3.6.0
363
+ *
364
+ * @param string $current_version The current version being used.
365
+ * @param string|array $compare_version The version to compare with.
366
+ * @return bool
367
+ */
368
+ public function version_match( $current_version, $compare_version ) {
369
+ if ( is_array( $compare_version ) ) {
370
+ foreach ( $compare_version as $compare_single ) {
371
+ $recursive_result = $this->version_match( $current_version, $compare_single );
372
+ if ( $recursive_result ) {
373
+ return true;
374
+ }
375
+ }
376
+
377
+ return false;
378
+ }
379
+
380
+ $current_parse = explode( '.', $current_version );
381
+
382
+ if ( strpos( $compare_version, '-' ) ) {
383
+ $compare_parse = explode( '-', $compare_version );
384
+ } elseif ( strpos( $compare_version, '.' ) ) {
385
+ $compare_parse = explode( '.', $compare_version );
386
+ } else {
387
+ return false;
388
+ }
389
+
390
+ $current_count = count( $current_parse );
391
+ $compare_count = count( $compare_parse );
392
+ for ( $i = 0; $i < $current_count || $i < $compare_count; $i++ ) {
393
+ if ( isset( $compare_parse[ $i ] ) && 'x' === strtolower( $compare_parse[ $i ] ) ) {
394
+ unset( $compare_parse[ $i ] );
395
+ }
396
+
397
+ if ( ! isset( $current_parse[ $i ] ) ) {
398
+ unset( $compare_parse[ $i ] );
399
+ } elseif ( ! isset( $compare_parse[ $i ] ) ) {
400
+ unset( $current_parse[ $i ] );
401
+ }
402
+ }
403
+
404
+ foreach ( $compare_parse as $index => $sub_number ) {
405
+ if ( $current_parse[ $index ] !== $sub_number ) {
406
+ return false;
407
+ }
408
+ }
409
+
410
+ return true;
411
  }
412
 
413
  /**
427
  // AIOSEO Notice Content.
428
  add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
429
  add_action( 'all_admin_notices', array( $this, 'display_notice_aioseop' ) );
430
+ add_action( 'all_admin_notices', array( $this, 'display_remote_notice' ) );
431
  } elseif ( isset( $current_screen->id ) ) {
432
  // Default WP Notice.
433
  add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
449
  private function obj_load_options() {
450
  $notices_options = $this->obj_get_options();
451
 
452
+ $this->notices = $notices_options['notices'];
453
+ $this->remote_notices = $this->validate_remote_notices( $notices_options['remote_notices'] );
454
+ $this->active_notices = $notices_options['active_notices'];
455
+ $this->dismissed_notices = $notices_options['dismissed_notices'];
456
  }
457
 
458
  /**
465
  */
466
  private function obj_get_options() {
467
  $defaults = array(
468
+ 'notices' => array(),
469
+ 'remote_notices' => array(),
470
+ 'active_notices' => array(),
471
+ 'dismissed_notices' => array(),
472
  );
473
 
474
  // Prevent old data from being loaded instead.
492
  */
493
  private function obj_update_options() {
494
  $notices_options = array(
495
+ 'notices' => $this->notices,
496
+ 'remote_notices' => $this->remote_notices,
497
+ 'active_notices' => $this->active_notices,
498
+ 'dismissed_notices' => $this->dismissed_notices,
499
  );
500
  $old_notices_options = $this->obj_get_options();
501
  $notices_options = wp_parse_args( $notices_options, $old_notices_options );
726
  $notice = $this->get_notice( $slug );
727
 
728
  unset( $this->active_notices[ $slug ] );
729
+ unset( $this->dismissed_notices[ $slug ] );
730
  delete_metadata(
731
  'user',
732
  0,
799
  public function set_notice_dismiss( $slug, $dismiss ) {
800
  $notice = $this->get_notice( $slug );
801
  if ( 'site' === $notice['target'] ) {
802
+ $this->dismissed_notices[ $slug ] = $dismiss;
803
  } elseif ( 'user' === $notice['target'] ) {
804
  $current_user_id = get_current_user_id();
805
 
893
  }
894
  }
895
 
896
+ $loc_remote_notices = array();
897
+ foreach ( $this->remote_notices as $remote_notice ) {
898
+ if ( ! isset( $remote_notice['btns'] ) ) {
899
+ continue;
900
+ }
901
+ array_push( $loc_remote_notices, $remote_notice['id'] );
902
+ }
903
+
904
  $admin_notice_localize = array(
905
  'notice_nonce' => wp_create_nonce( 'aioseop_ajax_notice' ),
906
  'notice_actions' => $notice_actions,
907
+ 'remote_notices' => $loc_remote_notices,
908
  );
909
  wp_localize_script( 'aioseop-admin-notice-js', 'aioseop_notice_data', $admin_notice_localize );
910
 
999
  continue;
1000
  }
1001
 
1002
+ if ( isset( $this->dismissed_notices[ $a_notice_slug ] ) && $this->dismissed_notices[ $a_notice_slug ] ) {
1003
  $notice_show = false;
1004
  }
1005
 
1032
  }
1033
  }
1034
 
1035
+ /**
1036
+ * Display Remote Notices
1037
+ *
1038
+ * @since 3.6.0
1039
+ */
1040
+ public function display_remote_notice() {
1041
+ if ( ! current_user_can( 'aiosp_manage_seo' ) ) {
1042
+ return;
1043
+ }
1044
+
1045
+ $current_screen = get_current_screen();
1046
+ if ( in_array( $current_screen->id, $this->excluded_screens, true ) ) {
1047
+ return;
1048
+ }
1049
+
1050
+ foreach ( $this->remote_notices as $remote_notice_slug => $remote_notice ) {
1051
+ if (
1052
+ time() < strtotime( $remote_notice['start'] ) ||
1053
+ ( ! empty( $remote_notice['end'] ) && time() > strtotime( $remote_notice['end'] ) )
1054
+ ) {
1055
+ continue;
1056
+ }
1057
+ if ( isset( $this->dismissed_notices[ $remote_notice_slug ] ) && $this->dismissed_notices[ $remote_notice_slug ] ) {
1058
+ continue;
1059
+ }
1060
+
1061
+ if ( isset( $remote_notice['btns'] ) ) {
1062
+ foreach ( $remote_notice['btns'] as $btn_slug => $btn ) {
1063
+ $remote_notice['btns'][ $btn_slug ]['url'] = $this->format_url( $btn['url'] );
1064
+ }
1065
+ }
1066
+
1067
+ // Display/Render.
1068
+ $important_admin_notices = array(
1069
+ 'error',
1070
+ 'warning',
1071
+ 'do-nag',
1072
+ );
1073
+ if ( defined( 'DISABLE_NAG_NOTICES' ) && true === DISABLE_NAG_NOTICES && ( ! in_array( $remote_notice['notification_type'], $important_admin_notices, true ) ) ) {
1074
+ continue;
1075
+ } else {
1076
+ include AIOSEOP_PLUGIN_DIR . 'admin/display/notice-remote.php';
1077
+ }
1078
+ }
1079
+ }
1080
+
1081
+ /**
1082
+ * Format URL
1083
+ *
1084
+ * @since 3.6.0
1085
+ *
1086
+ * @param string $url
1087
+ * @return string
1088
+ */
1089
+ public function format_url( $url ) {
1090
+ $replace = array(
1091
+ '(http://dismiss)' => '#dismiss',
1092
+ '(http://route)' => admin_url() . 'admin.php',
1093
+ '(#aioseo-settings)' => '?page=' . AIOSEOP_PLUGIN_DIRNAME . '/aioseop_class.php',
1094
+ '(#aioseo-general-settings)' => '?page=' . AIOSEOP_PLUGIN_DIRNAME . '/aioseop_class.php',
1095
+ '(#aioseo-performance)' => '?page=' . AIOSEOP_PLUGIN_DIRNAME . '/modules/aioseop_performance.php',
1096
+ '(#aioseo-sitemap)' => '?page=' . AIOSEOP_PLUGIN_DIRNAME . '/modules/aioseop_sitemap.php',
1097
+ '(#aioseo-opengraph)' => '?page=aiosp_opengraph',
1098
+ '(#aioseo-robots)' => '?page=' . AIOSEOP_PLUGIN_DIRNAME . '/modules/aioseop_robots.php',
1099
+ '(#aioseo-file-editor)' => '?page=' . AIOSEOP_PLUGIN_DIRNAME . '/modules/aioseop_file_editor.php',
1100
+ '(#aioseo-importer-exporter)' => '?page=' . AIOSEOP_PLUGIN_DIRNAME . '/modules/aioseop_importer_exporter.php',
1101
+ '(#aioseo-bad-robots)' => '?page=' . AIOSEOP_PLUGIN_DIRNAME . '/modules/aioseop_bad_robots.php',
1102
+ '(#aioseo-feature-manager)' => '?page=' . AIOSEOP_PLUGIN_DIRNAME . '/modules/aioseop_feature_manager.php',
1103
+ '(#aioseo-about)' => '?page=aioseop-about',
1104
+ '(#aioseo-video-sitemap)' => '#',
1105
+ '(#aioseo-image-seo)' => '#',
1106
+ '(#aioseo-local-business)' => '#',
1107
+ '(:[0-9a-zA-Z-_]+)' => '#',
1108
+ );
1109
+ if ( AIOSEOPPRO ) {
1110
+ $replace['(#aioseo-sitemap)'] = '?page=' . AIOSEOP_PLUGIN_DIRNAME . '/pro/class-aioseop-pro-sitemap.php';
1111
+ $replace['(#aioseo-video-sitemap)'] = '?page=' . AIOSEOP_PLUGIN_DIRNAME . '/pro/video_sitemap.php';
1112
+ if ( aioseop_is_addon_allowed( 'image_seo' ) ) {
1113
+ $replace['(#aioseo-image-seo)'] = '?page=aiosp_image_seo';
1114
+ }
1115
+ if ( aioseop_is_addon_allowed( 'schema_local_business' ) ) {
1116
+ $replace['(#aioseo-local-business)'] = '?page=' . AIOSEOP_PLUGIN_DIRNAME . '/pro/modules/class-aioseop-schema-local-business.php';
1117
+ }
1118
+ }
1119
+ $search = array_keys( $replace );
1120
+
1121
+ $tmp_url = preg_replace( $search, $replace, $url );
1122
+ if ( ! empty( $tmp_url ) ) {
1123
+ $url = $tmp_url;
1124
+ }
1125
+
1126
+ return $url;
1127
+ }
1128
+
1129
  /**
1130
  * AJAX Notice Action
1131
  *
1161
  }
1162
  }
1163
  if ( empty( $notice_slug ) ) {
1164
+ /* Translators: Displays the hardcoded slug that is missing. */
1165
  wp_send_json_error( sprintf( __( 'Missing values from `%s`.', 'all-in-one-seo-pack' ), 'notice_slug' ) );
1166
  } elseif ( empty( $action_index ) && 0 !== (int) $action_index ) {
1167
+ /* Translators: Displays the hardcoded action index that is missing. */
1168
  wp_send_json_error( sprintf( __( 'Missing values from `%s`.', 'all-in-one-seo-pack' ), 'action_index' ) );
1169
  }
1170
 
1189
  wp_send_json_success( __( 'Notice updated successfully.', 'all-in-one-seo-pack' ) );
1190
  }
1191
 
1192
+ /**
1193
+ * AJAX Remote Notice
1194
+ *
1195
+ * @since 3.6.0
1196
+ */
1197
+ public function ajax_remote_notice_action() {
1198
+ check_ajax_referer( 'aioseop_ajax_notice' );
1199
+ if ( ! current_user_can( 'aiosp_manage_seo' ) ) {
1200
+ wp_send_json_error( __( "User doesn't have `aiosp_manage_seo` capabilities.", 'all-in-one-seo-pack' ) );
1201
+ }
1202
+
1203
+ $remote_notice_id = null;
1204
+ if ( isset( $_POST['remote_notice_id'] ) ) {
1205
+ $remote_notice_id = filter_input( INPUT_POST, 'remote_notice_id', FILTER_SANITIZE_STRING );
1206
+
1207
+ // When PHPUnit is unable to use filter_input.
1208
+ if ( defined( 'AIOSEOP_UNIT_TESTING' ) && null === $remote_notice_id && ! empty( $_POST['remote_notice_id'] ) ) {
1209
+ $remote_notice_id = $_POST['remote_notice_id'];
1210
+ }
1211
+ }
1212
+ if ( empty( $remote_notice_id ) ) {
1213
+ /* Translators: Displays the hardcoded ID that is missing. */
1214
+ wp_send_json_error( sprintf( __( 'Missing values from `%s`.', 'all-in-one-seo-pack' ), 'remote_notice_id' ) );
1215
+ }
1216
+
1217
+ $this->dismissed_notices[ 'remote_' . $remote_notice_id ] = time();
1218
+
1219
+ $this->obj_update_options();
1220
+ wp_send_json_success( __( 'Notice updated successfully.', 'all-in-one-seo-pack' ) );
1221
+ }
1222
+
1223
  }
1224
+
1225
  // CLASS INITIALIZATION.
1226
  // Should this be a singleton class instead of a global?
1227
  global $aioseop_notices;
1228
  $aioseop_notices = new AIOSEOP_Notices();
1229
+ }
admin/display/aioseop-welcome.php ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( ! class_exists( 'AIOSEOP_Welcome' ) ) {
4
+
5
+ /**
6
+ * Handles the Welcome page.
7
+ *
8
+ * @since 3.6.0
9
+ */
10
+ class AIOSEOP_Welcome {
11
+
12
+ /**
13
+ * Registers our hooks.
14
+ *
15
+ * @since 3.6.0
16
+ *
17
+ * @return void
18
+ */
19
+ public static function hooks() {
20
+ if ( AIOSEOPPRO ) {
21
+ return;
22
+ }
23
+ add_action( 'admin_menu', array( 'AIOSEOP_Welcome', 'registerPage' ) );
24
+ add_action( 'admin_enqueue_scripts', array( 'AIOSEOP_Welcome', 'loadAssets' ) );
25
+ }
26
+
27
+ /**
28
+ * Registers our the Welcome page and removes it from our menu.
29
+ *
30
+ * @since 3.6.0
31
+ *
32
+ * @return void
33
+ */
34
+ public static function registerPage() {
35
+ /* 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. */
36
+ $welcome_text = sprintf( __( 'Welcome to %s', 'all-in-one-seo-pack' ), AIOSEOP_PLUGIN_NAME );
37
+ add_dashboard_page(
38
+ $welcome_text,
39
+ $welcome_text,
40
+ 'manage_options',
41
+ 'aioseop-welcome',
42
+ array( 'AIOSEOP_Welcome', 'output' )
43
+ );
44
+ remove_submenu_page( 'index.php', 'aioseop-welcome' );
45
+ }
46
+
47
+ /**
48
+ * Loads the required assets for the welcome page.
49
+ *
50
+ * @since 3.6.0
51
+ *
52
+ * @param string $page The page ID.
53
+ * @return void
54
+ */
55
+ public static function loadAssets( $page ) {
56
+ if ( 'dashboard_page_aioseop-welcome' === $page ) {
57
+ wp_enqueue_style( 'aioseop-welcome', AIOSEOP_PLUGIN_URL . 'css/aioseop-welcome.css', array(), AIOSEOP_VERSION );
58
+ if ( function_exists( 'is_rtl' ) && is_rtl() ) {
59
+ wp_enqueue_style( 'aioseop-welcome-rtl', AIOSEOP_PLUGIN_URL . 'css/aioseop-welcome-rtl.css', array( 'aioseop-welcome' ), AIOSEOP_VERSION );
60
+ }
61
+ }
62
+ }
63
+
64
+ /**
65
+ * Shows the Welcome page if all conditions are met.
66
+ *
67
+ * @since 3.6.0
68
+ *
69
+ * @return void
70
+ */
71
+ public function showPage() {
72
+ if (
73
+ AIOSEOPPRO ||
74
+ ! is_admin() ||
75
+ is_network_admin() ||
76
+ isset( $_GET['activate-multi'] ) ||
77
+ ! current_user_can( 'manage_options' )
78
+ ) {
79
+ return;
80
+ }
81
+
82
+ delete_transient( '_aioseop_activation_redirect' );
83
+
84
+ // Compare major versions so we don't show the welcome screen for minor versions.
85
+ $lastSeenVersion = get_user_meta( get_current_user_id(), 'aioseop_seen_about_page', true );
86
+ if (
87
+ $lastSeenVersion &&
88
+ ( get_major_version( AIOSEOP_VERSION ) === get_major_version( $lastSeenVersion ) )
89
+ ) {
90
+ return;
91
+ }
92
+
93
+ wp_safe_redirect(
94
+ add_query_arg(
95
+ array( 'page' => 'aioseop-welcome' ), admin_url( 'index.php' )
96
+ )
97
+ );
98
+ exit;
99
+ }
100
+
101
+ /**
102
+ * Outputs the Welcome page.
103
+ *
104
+ * @since 3.6.0
105
+ *
106
+ * @return void
107
+ */
108
+ public static function output() {
109
+ // Update user meta once page has been shown.
110
+ update_user_meta( get_current_user_id(), 'aioseop_seen_about_page', AIOSEOP_VERSION );
111
+ ?>
112
+
113
+ <div class="wrap about-wrap">
114
+ <div class="aioseop-welcome-logo">
115
+ <?php echo aioseop_get_logo( 180, 180, '#44619A' ); ?>
116
+ </div>
117
+ <h1>
118
+ <?php
119
+ /* translators: %1$s and %2$s are placeholders, which means that these should not be translated. These will be replaced with the name of the plugin, All in One SEO Pack, and the current version number. */
120
+ printf( esc_html__( 'Welcome to %1$s %2$s', 'all-in-one-seo-pack' ), AIOSEOP_PLUGIN_NAME, AIOSEOP_VERSION );
121
+ ?>
122
+ </h1>
123
+ <div class="about-text">
124
+ <?php
125
+ /* translators: %1$s and %2$s are placeholders, which means that these should not be translated. These will be replaced with the name of the plugin, All in One SEO Pack, and the current version number. */
126
+ printf( esc_html__( '%1$s %2$s contains new features, bug fixes, increased security, and tons of under the hood performance improvements.', 'all-in-one-seo-pack' ), AIOSEOP_PLUGIN_NAME, AIOSEOP_VERSION );
127
+ ?>
128
+ </div>
129
+
130
+ <h2 class="nav-tab-wrapper">
131
+ <a
132
+ class="nav-tab nav-tab-active" id="aioseop-welcome"
133
+ href="<?php echo esc_url( admin_url( add_query_arg( array( 'page' => 'aioseop-welcome' ), 'index.php' ) ) ); ?>">
134
+ <?php esc_html_e( 'What&#8217;s New', 'all-in-one-seo-pack' ); ?>
135
+ </a>
136
+ </h2>
137
+
138
+ <div id='sections'>
139
+ <section><?php include_once( AIOSEOP_PLUGIN_DIR . 'admin/display/welcome-content.php' ); ?></section>
140
+ </div>
141
+
142
+ </div>
143
+ <?php
144
+ }
145
+ }
146
+ }
admin/display/credits-content.php DELETED
@@ -1,99 +0,0 @@
1
- <?php
2
- /**
3
- * Credits Content
4
- *
5
- * Displays AIOSEOP's team and additional individuals who have contributed.
6
- *
7
- * @link https://wordpress.org/plugins/all-in-one-seo-pack/
8
- *
9
- * @package All_in_One_SEO_Pack
10
- * @since ?
11
- */
12
-
13
- ?>
14
- <div class="wrap credits-wrap">
15
-
16
- <p class="about-description">
17
- <?php
18
- /* translators: %s is a placeholder so it should not be translated. It will be replaced with the name of the plugin, All in One SEO Pack. */
19
- printf( __( '%s is created by a worldwide network of friendly folks like these.', 'all-in-one-seo-pack' ), AIOSEOP_PLUGIN_NAME );
20
- ?>
21
- </p>
22
-
23
- <h3 class="wp-people-group"><?php _e( 'Project Leaders', 'all-in-one-seo-pack' ); ?></h3>
24
- <ul class="wp-people-group " id="wp-people-group-project-leaders">
25
- <li class="wp-person" id="wp-person-stevemortiboy">
26
- <a class="web" target="_blank" href="https://twitter.com/wpsmort"><img alt="" class="gravatar" src="https://www.gravatar.com/avatar/40e33d813c16a63500675d851b0cbf3a?s=60">
27
- Steve Mortiboy</a>
28
- <span class="title"><?php _e( 'Project Manager', 'all-in-one-seo-pack' ); ?></span>
29
- </li>
30
- </ul>
31
-
32
- <h3 class="wp-people-group"><?php printf( __( 'Core Team', 'all-in-one-seo-pack' ) ); ?></h3>
33
- <ul class="wp-people-group " id="wp-people-group-contributors">
34
- <li class="wp-person" id="wp-person-arnaudbroes">
35
- <a class="web" target="_blank" href="https://profiles.wordpress.org/arnaudbroes"><img alt="" class="gravatar" src="https://www.gravatar.com/avatar/0ce0d554c2b0bd61d326e15c8dcde756?s=60">
36
- Arnaud Broes</a>
37
- <span class="title"><?php _e( 'Team Lead', 'all-in-one-seo-pack' ); ?></span>
38
- </li>
39
- <li class="wp-person" id="EkoJR">
40
- <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">
41
- Ben Reames</a>
42
- <span class="title"><?php _e( 'Development Team', 'all-in-one-seo-pack' ); ?></span>
43
- </li>
44
-
45
- </ul>
46
-
47
- <h3 class="wp-people-group dashicons-before dashicons-translation">
48
- <?php
49
- /* translators: In this context, "translation contributors" are translators who submit strings on translate.wordpress.org and "translation editors" are those who proofread and approve them (also known as PTEs - Project Translation Editors).*/
50
- printf( _e( 'Translation contributors and translation editors', 'all-in-one-seo-pack' ), '1.2' );
51
- ?>
52
- </h3>
53
- <p class="wp-credits-list">
54
- <a href="https://profiles.wordpress.org/pierrelannoy/" target="_blank">Pierre Lannoy</a>,
55
- <a href="https://profiles.wordpress.org/sonjanyc/" target="_blank">Sonja Leix</a>,
56
- <a href="https://profiles.wordpress.org/dev-ide/" target="_blank">Adil El hallaoui</a>,
57
- <a href="https://profiles.wordpress.org/simonie/" target="_blank">simonie</a>,
58
- <a href="https://profiles.wordpress.org/lenasterg/" target="_blank">lenasterg</a>,
59
- <a href="https://profiles.wordpress.org/arnaudbroes/" target="_blank">Arnaud Broes</a>,
60
- <a href="https://profiles.wordpress.org/pixolin/" target="_blank">Bego Mario Garde</a>,
61
- <a href="https://profiles.wordpress.org/wp-yogi/" target="_blank">wp-yogi</a>,
62
- <a href="https://profiles.wordpress.org/wpsmort/" target="_blank">Steve Mortiboy</a>,
63
- <a href="https://profiles.wordpress.org/webaware/" target="_blank">webaware</a>,
64
- <a href="https://profiles.wordpress.org/escribirelmundo/" target="_blank">escribirelmundo</a>,
65
- <a href="https://profiles.wordpress.org/casiepa/" target="_blank">Pascal Casier</a>,
66
- <a href="https://profiles.wordpress.org/shoheitanaka/" target="_blank">Shohei Tanaka</a>,
67
- <a href="https://profiles.wordpress.org/nurron/" target="_blank">Nurron Shodiqin</a>,
68
- <a href="https://profiles.wordpress.org/aprmndr/" target="_blank">Alyssa Primandaru</a>,
69
- <a href="https://profiles.wordpress.org/facestoro/" target="_blank">facestoro</a>,
70
- <a href="https://profiles.wordpress.org/yuqianl/" target="_blank">Dawa Torbert</a>,
71
- <a href="https://profiles.wordpress.org/hallsofmontezuma/" target="_blank">Michael Torbert</a>,
72
- <a href="https://profiles.wordpress.org/istvanzseller/" target="_blank">Istvan Zseller</a>,
73
- <a href="https://profiles.wordpress.org/paaljoachim" target="_blank">Paal Joachim Romdahl</a>,
74
- <a href="https://profiles.wordpress.org/almaz/" target="_blank">Almaz Mannanov</a>,
75
- <a href="https://profiles.wordpress.org/vide13 /" target="_blank">vide13</a>,
76
- <a href="https://profiles.wordpress.org/yuraz/" target="_blank">Jurica Zuanovic</a>,
77
- <a href="https://profiles.wordpress.org/arhipaiva/" target="_blank">arhipaiva</a>,
78
- <a href="https://profiles.wordpress.org/maximanikin/" target="_blank">Maxim Anikin</a>,
79
- <a href="https://profiles.wordpress.org/petya/" target="_blank">Petya Raykovska</a>,
80
- <a href="https://profiles.wordpress.org/hathanh0809/" target="_blank">hathanh0809</a>,
81
- <a href="https://profiles.wordpress.org/cedric3131/" target="_blank">Cédric Valmary</a>,
82
- <a href="https://profiles.wordpress.org/smitka/" target="_blank">Vladimir Smitka</a>,
83
- <a href="https://profiles.wordpress.org/brewtal/" target="_blank">Paul P.</a>,
84
- <a href="https://profiles.wordpress.org/wpaleks/" target="_blank">Aleksander Savkovic</a>,
85
- <a href="https://profiles.wordpress.org/diogosanches/" target="_blank">Diogo Sanches</a>,
86
- <a href="https://profiles.wordpress.org/klemenfajs/" target="_blank">Klemen Fajs</a>,
87
- <a href="https://profiles.wordpress.org/adriancastellanos/" target="_blank">Adrian Castellanos</a>,
88
- <a href="https://profiles.wordpress.org/exilhamburger/" target="_blank">exilhamburger</a>,
89
- <a href="https://profiles.wordpress.org/garyj/" target="_blank">Gary Jones</a>,
90
- <a href="https://profiles.wordpress.org/fernandot/" target="_blank">Fernando Tellado</a>,
91
- <a href="https://profiles.wordpress.org/hiwhatsup/" target="_blank">Carlos Zuniga</a>,
92
- <a href="https://profiles.wordpress.org/fxbenard/" target="_blank">François Bernard</a>,
93
- <a href="https://profiles.wordpress.org/jack0falltrades/" target="_blank">jack0falltrades</a>,
94
- <a href="https://profiles.wordpress.org/dancaragea/" target="_blank">Dan Caragea</a>,
95
- <a href="https://profiles.wordpress.org/kyla81975/" target="_blank">kyla81975</a>,
96
- <a href="https://profiles.wordpress.org/arildknudsen1/" target="_blank">Arild Knudsen</a>.
97
- </p>
98
-
99
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/display/notice-default.php CHANGED
@@ -69,7 +69,7 @@ $dismissible = ! isset( $notice['dismissible'] ) || $notice['dismissible'] ? ' i
69
  id="<?php echo esc_attr( $id ); ?>"
70
  class="aioseop-notice-delay <?php echo esc_attr( $class ); ?>"
71
  <?php
72
- if ( $action_option['new_tab'] ) {
73
  echo 'target="_blank" rel="noopener"';}
74
  ?>
75
  >
69
  id="<?php echo esc_attr( $id ); ?>"
70
  class="aioseop-notice-delay <?php echo esc_attr( $class ); ?>"
71
  <?php
72
+ if ( isset( $action_option['new_tab'] ) && $action_option['new_tab'] ) {
73
  echo 'target="_blank" rel="noopener"';}
74
  ?>
75
  >
admin/display/notice-remote.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Remote Notice Template.
4
+ *
5
+ * @since 3.6.0
6
+ *
7
+ * @see AIOSEOP_Notice::display_remote_notice();
8
+ * @uses $remote_notice in AIOSEOP_Notice::remote_notices
9
+ * @package All-in-One-SEO-Pack
10
+ * @subpackage AIOSEOP_Notices
11
+ */
12
+
13
+ $notice_class = 'info';
14
+ if ( isset( $remote_notice['notification_type'] ) && ! empty( $remote_notice['notification_type'] ) ) {
15
+ $notice_class = $remote_notice['notification_type'];
16
+ }
17
+
18
+ add_filter( 'safe_style_css', 'aioseop_filter_styles' );
19
+
20
+ $dismissible = ! isset( $remote_notice['dismissible'] ) || $remote_notice['dismissible'] ? ' is-dismissible' : '';
21
+
22
+ ?>
23
+ <div class="notice notice-<?php echo esc_attr( $notice_class ); ?><?php echo $dismissible; ?> aioseop-notice-container aioseop-remote-notice-<?php echo esc_attr( $remote_notice['id'] ); ?>">
24
+ <h3><?php echo esc_html( $remote_notice['title'] ); ?></h3>
25
+ <p><?php echo wp_kses_post( $remote_notice['content'] ); ?></p>
26
+ <?php if ( isset( $remote_notice['btns'] ) ) : ?>
27
+ <p class="aioseo-action-buttons">
28
+ <?php foreach ( $remote_notice['btns'] as $btn_slug => $btn ) : ?>
29
+ <?php
30
+ $link = $btn['url'];
31
+ $id = 'aioseop-remote-notice-btn-' . $remote_notice['id'] . '-' . $btn_slug;
32
+ $btn_class = ( 'main' === $btn_slug ) ? 'button-primary' : 'button-secondary';
33
+ $class = "aioseop-remote-notice-btn {$btn_class}";
34
+
35
+ $homeUrl = home_url();
36
+ preg_match( "#$homeUrl.*#", $link, $ownDomain );
37
+ preg_match( "#.*?doNotDismiss=true.*#", $link, $noDismiss );
38
+ ?>
39
+ <a
40
+ href="<?php echo esc_url( $link ); ?>"
41
+ id="<?php echo esc_attr( $id ); ?>"
42
+ class="aioseop-notice-delay <?php echo esc_attr( $class ); ?>"
43
+ <?php if ( $noDismiss ) echo 'data-dismiss="false"'?>
44
+ <?php if ( ! $ownDomain ) echo 'target="_blank"'; ?>
45
+ >
46
+ <?php echo esc_textarea( $btn['text'] ); ?>
47
+ </a>
48
+ <?php endforeach; ?>
49
+ </p>
50
+ <?php endif; ?>
51
+ </div>
admin/display/notices/local-business-notice.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Configures the Local Business schema 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 aioseoLocalBusinessNotice() {
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',
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-error',
20
+ 'target' => 'site',
21
+ 'screens' => array(),
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
+ 'dismiss' => false,
28
+ 'class' => 'button-primary',
29
+ )
30
+ ),
31
+ );
32
+ }
33
+ add_filter( 'aioseop_admin_notice-local_business', 'aioseoLocalBusinessNotice' );
admin/display/notices/news-sitemap-notice.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Contains all data for the Google News sitemap notice.
4
+ *
5
+ * @since 3.6.0
6
+ *
7
+ * @return void
8
+ */
9
+ function aioseop_notice_news_sitemap() {
10
+ $dirname = dirname( plugin_basename( AIOSEO_PLUGIN_FILE ) );
11
+ $menu_path = admin_url( "admin.php?page=$dirname/pro/class-aioseop-pro-sitemap.php" );
12
+ return array(
13
+ 'slug' => 'news_sitemap',
14
+ 'delay_time' => 0,
15
+ 'target' => 'user',
16
+ 'screens' => array(),
17
+ 'class' => 'notice-error',
18
+ 'dismissible' => false,
19
+ 'message' => sprintf( __( 'You have not set the Google News Publication Name or the Site Title. %s requires at least one of these for the Google News sitemap to be valid.', 'all-in-one-seo-pack' ), AIOSEOP_PLUGIN_NAME ),
20
+ 'action_options' => array(
21
+ array(
22
+ 'time' => 0,
23
+ 'link' => $menu_path,
24
+ 'new_tab' => false,
25
+ 'text' => __( 'Go to XML Sitemap settings', 'all-in-one-seo-pack' ),
26
+ 'dismiss' => false,
27
+ 'class' => 'button-primary',
28
+ ),
29
+ array(
30
+ 'time' => 0,
31
+ 'link' => admin_url( 'options-general.php' ),
32
+ 'new_tab' => false,
33
+ 'text' => __( 'Go to Settings > General', 'all-in-one-seo-pack' ),
34
+ 'dismiss' => false,
35
+ 'class' => 'button-secondary',
36
+ ),
37
+ ),
38
+ );
39
+ }
40
+ add_filter( 'aioseop_admin_notice-news_sitemap', 'aioseop_notice_news_sitemap' );
admin/display/welcome-content.php CHANGED
@@ -11,7 +11,7 @@
11
  <div class="welcome-panel-content">
12
  <div class="welcome-panel-column-container">
13
  <div>
14
- <h3><a href="https://semperplugins.com/all-in-one-seo-pack-3-4/" target="_blank"><?php echo esc_html( __( "Check out what's new in our latest release post!", 'all-in-one-seo-pack' ) ); ?></a></h3>
15
  </div>
16
  <div class="welcome-panel-column">
17
  <h3>
11
  <div class="welcome-panel-content">
12
  <div class="welcome-panel-column-container">
13
  <div>
14
+ <h3><a href="https://semperplugins.com/new-local-business-schema/" target="_blank"><?php echo esc_html( __( "Check out what's new in our latest release post!", 'all-in-one-seo-pack' ) ); ?></a></h3>
15
  </div>
16
  <div class="welcome-panel-column">
17
  <h3>
admin/display/welcome.php DELETED
@@ -1,172 +0,0 @@
1
- <?php
2
- /**
3
- * Welcome
4
- *
5
- * @package All_in_One_SEO_Pack
6
- * @since ?
7
- */
8
-
9
- if ( ! class_exists( 'aioseop_welcome' ) ) {
10
-
11
- /**
12
- * Class aioseop_welcome
13
- */
14
- // @codingStandardsIgnoreStart
15
- class aioseop_welcome {
16
- // @codingStandardsIgnoreEnd
17
- /**
18
- * Constructor to add the actions.
19
- */
20
- function __construct() {
21
-
22
- if ( AIOSEOPPRO ) {
23
- return;
24
- }
25
-
26
- add_action( 'admin_menu', array( $this, 'add_menus' ) );
27
- add_action( 'admin_menu', array( $this, 'remove_pages' ), 999 );
28
- add_action( 'admin_enqueue_scripts', array( $this, 'welcome_screen_assets' ) );
29
-
30
- }
31
-
32
- /**
33
- * Enqueues style and script.
34
- *
35
- * @param $hook
36
- */
37
- function welcome_screen_assets( $hook ) {
38
-
39
- if ( 'dashboard_page_aioseop-about' === $hook ) {
40
-
41
- wp_enqueue_style( 'aioseop_welcome_css', AIOSEOP_PLUGIN_URL . 'css/aioseop-welcome.css', array(), AIOSEOP_VERSION );
42
- if ( function_exists( 'is_rtl' ) && is_rtl() ) {
43
- wp_enqueue_style( 'aioseop_welcome_css_rtl', AIOSEOP_PLUGIN_URL . 'css/aioseop-welcome-rtl.css', array( 'aioseop_welcome_css' ), AIOSEOP_VERSION );
44
- }
45
- wp_enqueue_script( 'aioseop_welcome_js', AIOSEOP_PLUGIN_URL . 'js/welcome.js', array( 'jquery' ), AIOSEOP_VERSION, true );
46
- }
47
- }
48
-
49
- /**
50
- * Removes unneeded pages.
51
- *
52
- * @since 2.3.12 Called via admin_menu action instead of admin_head.
53
- */
54
- function remove_pages() {
55
- remove_submenu_page( 'index.php', 'aioseop-about' );
56
- remove_submenu_page( 'index.php', 'aioseop-credits' );
57
- }
58
-
59
- /**
60
- * Adds (hidden) menu.
61
- */
62
- function add_menus() {
63
- /* 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. */
64
- $welcome_text = sprintf( __( 'Welcome to %s', 'all-in-one-seo-pack' ), AIOSEOP_PLUGIN_NAME );
65
- add_dashboard_page(
66
- $welcome_text,
67
- $welcome_text,
68
- 'manage_options',
69
- 'aioseop-about',
70
- array( $this, 'about_screen' )
71
- );
72
-
73
- }
74
-
75
- /**
76
- * Initial stuff.
77
- *
78
- * @param bool $activate
79
- */
80
- function init( $activate = false ) {
81
-
82
- if ( ! is_admin() ) {
83
- return;
84
- }
85
-
86
- // Bail if activating from network, or bulk.
87
- if ( is_network_admin() || isset( $_GET['activate-multi'] ) ) {
88
- return;
89
- }
90
-
91
- if ( ! current_user_can( 'manage_options' ) ) {
92
- return;
93
- }
94
-
95
- wp_cache_flush();
96
- aiosp_common::clear_wpe_cache();
97
-
98
- delete_transient( '_aioseop_activation_redirect' );
99
-
100
- $seen = 0;
101
- $seen = get_user_meta( get_current_user_id(), 'aioseop_seen_about_page', true );
102
-
103
- update_user_meta( get_current_user_id(), 'aioseop_seen_about_page', AIOSEOP_VERSION );
104
-
105
- if ( AIOSEOPPRO ) {
106
- return;
107
- }
108
-
109
- // Compare the major versions so we don't show the welcome screen on minor versions.
110
- if ( ( get_major_version( AIOSEOP_VERSION ) === get_major_version( $seen ) ) || ( true !== $activate ) ) {
111
- return;
112
- }
113
-
114
- wp_safe_redirect( add_query_arg( array( 'page' => 'aioseop-about' ), admin_url( 'index.php' ) ) );
115
- exit;
116
- }
117
-
118
- /**
119
- * Outputs the about screen.
120
- */
121
- function about_screen() {
122
- aiosp_common::clear_wpe_cache();
123
- $version = AIOSEOP_VERSION;
124
-
125
- ?>
126
-
127
- <div class="wrap about-wrap">
128
- <div class="aioseop-welcome-logo">
129
- <?php echo aioseop_get_logo( 180, 180, '#44619A' ); ?>
130
- </div>
131
- <h1>
132
- <?php
133
- /* translators: %1$s and %2$s are placeholders, which means that these should not be translated. These will be replaced with the name of the plugin, All in One SEO Pack, and the current version number. */
134
- printf( esc_html__( 'Welcome to %1$s %2$s', 'all-in-one-seo-pack' ), AIOSEOP_PLUGIN_NAME, $version );
135
- ?>
136
- </h1>
137
- <div class="about-text">
138
- <?php
139
- /* translators: %1$s and %2$s are placeholders, which means that these should not be translated. These will be replaced with the name of the plugin, All in One SEO Pack, and the current version number. */
140
- printf( esc_html__( '%1$s %2$s contains new features, bug fixes, increased security, and tons of under the hood performance improvements.', 'all-in-one-seo-pack' ), AIOSEOP_PLUGIN_NAME, $version );
141
- ?>
142
- </div>
143
-
144
- <h2 class="nav-tab-wrapper">
145
- <a
146
- class="nav-tab nav-tab-active" id="aioseop-about"
147
- href="<?php echo esc_url( admin_url( add_query_arg( array( 'page' => 'aioseop-about' ), 'index.php' ) ) ); ?>">
148
- <?php esc_html_e( 'What&#8217;s New', 'all-in-one-seo-pack' ); ?>
149
- </a>
150
- <!--a
151
- class="nav-tab" id="aioseop-credits"
152
- href="<?php echo esc_url( admin_url( add_query_arg( array( 'page' => 'aioseop-credits' ), 'index.php' ) ) ); ?>">
153
- <?php esc_html_e( 'Credits', 'all-in-one-seo-pack' ); ?>
154
- </a-->
155
- </h2>
156
-
157
-
158
- <div id='sections'>
159
- <section><?php include_once( AIOSEOP_PLUGIN_DIR . 'admin/display/welcome-content.php' ); ?></section>
160
- <section><?php include_once( AIOSEOP_PLUGIN_DIR . 'admin/display/credits-content.php' ); ?></section>
161
- </div>
162
-
163
- </div>
164
-
165
-
166
- <?php
167
-
168
- }
169
-
170
- }
171
-
172
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
aioseop_class.php CHANGED
@@ -229,6 +229,8 @@ class All_in_One_SEO_Pack extends All_in_One_SEO_Pack_Module {
229
  $blog_name = esc_attr( get_bloginfo( 'name' ) );
230
  parent::__construct();
231
 
 
 
232
  $this->default_options = array(
233
  'license_key' => array(
234
  /* translators: This is a setting where users can enter their license code for All in One SEO Pack Pro. */
@@ -5102,21 +5104,9 @@ class All_in_One_SEO_Pack extends All_in_One_SEO_Pack_Module {
5102
  $optlist = array_diff( $optlist, array( 'sitemap_priority', 'sitemap_frequency' ) );
5103
  }
5104
 
5105
- foreach ( $optlist as $field_name ) {
5106
- $field = "aiosp_$field_name";
5107
- if ( isset( $_POST[ $field ] ) ) {
5108
- $$field = $_POST[ $field ];
5109
- }
5110
-
5111
- delete_post_meta( $id, "_aioseop_{$field_name}" );
5112
- }
5113
-
5114
- foreach ( $optlist as $field_name ) {
5115
- $var = "aiosp_$field_name";
5116
- $field = "_aioseop_$field_name";
5117
- if ( isset( $$var ) && ! empty( $$var ) ) {
5118
- add_post_meta( $id, $field, $$var );
5119
- }
5120
  }
5121
  }
5122
  }
@@ -5213,13 +5203,32 @@ class All_in_One_SEO_Pack extends All_in_One_SEO_Pack_Module {
5213
  $url = esc_url( admin_url( 'admin.php?page=' . $menu_slug ) );
5214
  }
5215
 
 
 
 
 
 
 
 
 
5216
  $wp_admin_bar->add_menu(
5217
  array(
5218
  'id' => AIOSEOP_PLUGIN_DIRNAME,
5219
- 'title' => '<span class="ab-icon aioseop-admin-bar-logo"></span>' . __( 'SEO', 'all-in-one-seo-pack' ),
5220
  )
5221
  );
5222
 
 
 
 
 
 
 
 
 
 
 
 
5223
  if ( ! is_admin() ) {
5224
  $wp_admin_bar->add_menu(
5225
  array(
@@ -5239,6 +5248,10 @@ class All_in_One_SEO_Pack extends All_in_One_SEO_Pack_Module {
5239
  )
5240
  );
5241
 
 
 
 
 
5242
  $aioseop_admin_menu = 1;
5243
  if ( ! empty( $post ) ) {
5244
 
@@ -5380,22 +5393,10 @@ class All_in_One_SEO_Pack extends All_in_One_SEO_Pack_Module {
5380
  $optlist = array_diff( $optlist, array( 'sitemap_priority', 'sitemap_frequency' ) );
5381
  }
5382
 
5383
- foreach ( $optlist as $field_name ) {
5384
- $field = "aiosp_$field_name";
5385
- if ( isset( $_POST[ $field ] ) ) {
5386
- $$field = $_POST[ $field ];
5387
- }
5388
-
5389
- delete_term_meta( $id, "_aioseop_{$field_name}" );
5390
- }
5391
-
5392
- foreach ( $optlist as $field_name ) {
5393
- $var = "aiosp_$field_name";
5394
- $field = "_aioseop_$field_name";
5395
-
5396
- if ( isset( $$var ) && ! empty( $$var ) ) {
5397
- add_term_meta( $id, $field, $$var );
5398
- }
5399
  }
5400
  }
5401
  }
@@ -5794,4 +5795,24 @@ class All_in_One_SEO_Pack extends All_in_One_SEO_Pack_Module {
5794
  }
5795
  }
5796
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5797
  }
229
  $blog_name = esc_attr( get_bloginfo( 'name' ) );
230
  parent::__construct();
231
 
232
+ $this->checkIfLicensed();
233
+
234
  $this->default_options = array(
235
  'license_key' => array(
236
  /* translators: This is a setting where users can enter their license code for All in One SEO Pack Pro. */
5104
  $optlist = array_diff( $optlist, array( 'sitemap_priority', 'sitemap_frequency' ) );
5105
  }
5106
 
5107
+ foreach ( $optlist as $optionName ) {
5108
+ $value = isset( $_POST[ "aiosp_$optionName" ] ) ? $_POST[ "aiosp_$optionName" ] : '';
5109
+ update_post_meta( $id, "_aioseop_$optionName", $value );
 
 
 
 
 
 
 
 
 
 
 
 
5110
  }
5111
  }
5112
  }
5203
  $url = esc_url( admin_url( 'admin.php?page=' . $menu_slug ) );
5204
  }
5205
 
5206
+ // Check if there are new notifications.
5207
+ $notifications = '';
5208
+ $notices = new AIOSEOP_Notices();
5209
+ if ( count( $notices->remote_notices ) ) {
5210
+ $count = count( $notices->remote_notices ) < 10 ? count( $notices->remote_notices ) : '!';
5211
+ $notifications = ' <div class="aioseo-menu-notification-counter"><span>' . $count . '</span></div>';
5212
+ }
5213
+
5214
  $wp_admin_bar->add_menu(
5215
  array(
5216
  'id' => AIOSEOP_PLUGIN_DIRNAME,
5217
+ 'title' => '<span class="ab-icon aioseop-admin-bar-logo"></span>' . __( 'SEO', 'all-in-one-seo-pack' ) . $notifications,
5218
  )
5219
  );
5220
 
5221
+ if ( $notifications ) {
5222
+ $wp_admin_bar->add_menu(
5223
+ array(
5224
+ 'id' => 'aioseop-notifications',
5225
+ 'parent' => AIOSEOP_PLUGIN_DIRNAME,
5226
+ 'title' => __( 'Notifications', 'all-in-one-seo-pack' ) . $notifications,
5227
+ 'href' => $url,
5228
+ )
5229
+ );
5230
+ }
5231
+
5232
  if ( ! is_admin() ) {
5233
  $wp_admin_bar->add_menu(
5234
  array(
5248
  )
5249
  );
5250
 
5251
+ if ( ! is_admin() ) {
5252
+ AIOSEOP_Education::external_tools( $wp_admin_bar );
5253
+ }
5254
+
5255
  $aioseop_admin_menu = 1;
5256
  if ( ! empty( $post ) ) {
5257
 
5393
  $optlist = array_diff( $optlist, array( 'sitemap_priority', 'sitemap_frequency' ) );
5394
  }
5395
 
5396
+
5397
+ foreach ( $optlist as $optionName ) {
5398
+ $value = isset( $_POST[ "aiosp_$optionName" ] ) ? $_POST[ "aiosp_$optionName" ] : '';
5399
+ update_term_meta( $id, "_aioseop_$optionName", $value );
 
 
 
 
 
 
 
 
 
 
 
 
5400
  }
5401
  }
5402
  }
5795
  }
5796
  }
5797
  }
5798
+
5799
+ /**
5800
+ * Checks if the plugin has a license key set, and otherwise wipes the addons/plan settings.
5801
+ *
5802
+ * @since 3.6.0
5803
+ *
5804
+ * @return void
5805
+ */
5806
+ private function checkIfLicensed() {
5807
+ global $aioseop_options;
5808
+ if ( ! $aioseop_options['aiosp_license_key'] ) {
5809
+ if ( isset( $aioseop_options['addons'] ) ) {
5810
+ $aioseop_options['addons'] = '';
5811
+ }
5812
+ if ( isset( $aioseop_options['plan'] ) ) {
5813
+ $aioseop_options['plan'] = 'unlicensed';
5814
+ }
5815
+ }
5816
+ update_option( 'aioseop_options', $aioseop_options );
5817
+ }
5818
  }
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.5.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
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.1
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
build/aioseop-link-attributes-gutenberg-editor.asset.php DELETED
@@ -1,4 +0,0 @@
1
- <?php return array(
2
- 'dependencies' => array( 'lodash', 'wp-element', 'wp-polyfill' ),
3
- 'version' => '30786cf55e346e4068908edbdfda65d1',
4
- );
 
 
 
 
build/aioseop-link-attributes-gutenberg-editor.js DELETED
@@ -1,6 +0,0 @@
1
- !function(e){var t={};function n(o){if(t[o])return t[o].exports;var r=t[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(o,r,function(t){return e[t]}.bind(null,r));return o},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=15)}([function(e,t){!function(){e.exports=this.wp.element}()},function(e,t){e.exports=function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}},function(e,t,n){var o;
2
- /*!
3
- Copyright (c) 2017 Jed Watson.
4
- Licensed under the MIT License (MIT), see
5
- http://jedwatson.github.io/classnames
6
- */!function(){"use strict";var n={}.hasOwnProperty;function r(){for(var e=[],t=0;t<arguments.length;t++){var o=arguments[t];if(o){var i=typeof o;if("string"===i||"number"===i)e.push(o);else if(Array.isArray(o)&&o.length){var s=r.apply(null,o);s&&e.push(s)}else if("object"===i)for(var a in o)n.call(o,a)&&o[a]&&e.push(a)}}return e.join(" ")}e.exports?(r.default=r,e.exports=r):void 0===(o=function(){return r}.apply(t,[]))||(e.exports=o)}()},function(e,t,n){var o=n(12);e.exports=function(e,t){if(null==e)return{};var n,r,i=o(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r<s.length;r++)n=s[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}},function(e,t){e.exports=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}},function(e,t){function n(e,t){for(var n=0;n<t.length;n++){var o=t[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}e.exports=function(e,t,o){return t&&n(e.prototype,t),o&&n(e,o),e}},function(e,t,n){var o=n(13),r=n(1);e.exports=function(e,t){return!t||"object"!==o(t)&&"function"!=typeof t?r(e):t}},function(e,t){function n(t){return e.exports=n=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},n(t)}e.exports=n},function(e,t,n){var o=n(14);e.exports=function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&o(e,t)}},function(e,t){!function(){e.exports=this.lodash}()},function(e,t){function n(){return e.exports=n=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var o in n)Object.prototype.hasOwnProperty.call(n,o)&&(e[o]=n[o])}return e},n.apply(this,arguments)}e.exports=n},function(e,t){e.exports=function(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}},function(e,t){e.exports=function(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o<i.length;o++)n=i[o],t.indexOf(n)>=0||(r[n]=e[n]);return r}},function(e,t){function n(t){return"function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?e.exports=n=function(e){return typeof e}:e.exports=n=function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},n(t)}e.exports=n},function(e,t){function n(t,o){return e.exports=n=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},n(t,o)}e.exports=n},function(e,t,n){"use strict";n.r(t);var o=n(3),r=n.n(o),i=n(11),s=n.n(i),a=n(4),l=n.n(a),u=n(5),c=n.n(u),p=n(6),f=n.n(p),d=n(7),h=n.n(d),g=n(1),v=n.n(g),b=n(8),m=n.n(b),y=n(0),w=n(9),k=n(10),O=n.n(k),S=wp.url,L=S.getProtocol,j=S.isValidProtocol,E=S.getAuthority,C=S.isValidAuthority,P=S.getPath,x=S.isValidPath,_=S.getQueryString,N=S.isValidQueryString,R=S.getFragment,F=S.isValidFragment,T=wp.i18n,W=T.__,A=T.sprintf;function D(e){if(!e)return!1;var t=e.trim();if(!t)return!1;if(/^\S+:/.test(t)){var n=L(t);if(!j(n))return!1;if(Object(w.startsWith)(n,"http")&&!/^https?:\/\/[^\/\s]/i.test(t))return!1;var o=E(t);if(!C(o))return!1;var r=P(t);if(r&&!x(r))return!1;var i=_(t);if(i&&!N(i))return!1;var s=R(t);if(s&&!F(s))return!1}return!(Object(w.startsWith)(t,"#")&&!F(t))}function I(e){var t=e.url,n=e.opensInNewWindow,o=e.noFollow,r=e.sponsored,i=e.text,s={type:"aioseop/link",attributes:{url:t}},a=[];if(n){var l=A(W("%s (opens in a new tab)","all-in-one-seo-pack"),i);s.attributes.target="_blank",s.attributes["aria-label"]=l,a.push("noreferrer noopener")}return o&&a.push("nofollow"),r&&a.push("sponsored"),a.length>0&&(s.attributes.rel=a.join(" ")),s}var V=wp.element.Component,M=wp.dom,U=M.getOffsetParent,K=M.getRectangleFromRange;function B(){var e=window.getSelection();if(0===e.rangeCount)return{};var t=K(e.getRangeAt(0)),n=t.top+t.height,o=t.left+t.width/2,r=U(e.anchorNode);if(r){var i=r.getBoundingClientRect();n-=i.top,o-=i.left}return{top:n,left:o}}var H=function(e){function t(){var e;return l()(this,t),(e=f()(this,h()(t).apply(this,arguments))).state={style:B()},e}return m()(t,e),c()(t,[{key:"render",value:function(){var e=this.props.children,t=this.state.style;return Object(y.createElement)("div",{className:"editor-format-toolbar__selection-position",style:t},e)}}]),t}(V),z=n(2),q=n.n(z);function Q(e){return(Q="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function $(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function G(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function X(e,t){var n=e["page".concat(t?"Y":"X","Offset")],o="scroll".concat(t?"Top":"Left");if("number"!=typeof n){var r=e.document;"number"!=typeof(n=r.documentElement[o])&&(n=r.body[o])}return n}function Y(e){return X(e)}function J(e){return X(e,!0)}function Z(e){var t=function(e){var t,n,o,r=e.ownerDocument,i=r.body,s=r&&r.documentElement;return n=(t=e.getBoundingClientRect()).left,o=t.top,{left:n-=s.clientLeft||i.clientLeft||0,top:o-=s.clientTop||i.clientTop||0}}(e),n=e.ownerDocument,o=n.defaultView||n.parentWindow;return t.left+=Y(o),t.top+=J(o),t}var ee,te=new RegExp("^(".concat(/[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source,")(?!px)[a-z%]+$"),"i"),ne=/^(top|right|bottom|left)$/;function oe(e,t){for(var n=0;n<e.length;n++)t(e[n])}function re(e){return"border-box"===ee(e,"boxSizing")}"undefined"!=typeof window&&(ee=window.getComputedStyle?function(e,t,n){var o="",r=e.ownerDocument,i=n||r.defaultView.getComputedStyle(e,null);return i&&(o=i.getPropertyValue(t)||i[t]),o}:function(e,t){var n=e.currentStyle&&e.currentStyle[t];if(te.test(n)&&!ne.test(t)){var o=e.style,r=o.left,i=e.runtimeStyle.left;e.runtimeStyle.left=e.currentStyle.left,o.left="fontSize"===t?"1em":n||0,n=o.pixelLeft+"px",o.left=r,e.runtimeStyle.left=i}return""===n?"auto":n});var ie=["margin","border","padding"];function se(e,t,n){var o,r={},i=e.style;for(o in t)t.hasOwnProperty(o)&&(r[o]=i[o],i[o]=t[o]);for(o in n.call(e),t)t.hasOwnProperty(o)&&(i[o]=r[o])}function ae(e,t,n){var o,r,i,s=0;for(r=0;r<t.length;r++)if(o=t[r])for(i=0;i<n.length;i++){var a=void 0;a="border"===o?"".concat(o+n[i],"Width"):o+n[i],s+=parseFloat(ee(e,a))||0}return s}function le(e){return null!=e&&e==e.window}var ue={};function ce(e,t,n){if(le(e))return"width"===t?ue.viewportWidth(e):ue.viewportHeight(e);if(9===e.nodeType)return"width"===t?ue.docWidth(e):ue.docHeight(e);var o="width"===t?["Left","Right"]:["Top","Bottom"],r="width"===t?e.offsetWidth:e.offsetHeight,i=(ee(e),re(e)),s=0;(null==r||r<=0)&&(r=void 0,(null==(s=ee(e,t))||Number(s)<0)&&(s=e.style[t]||0),s=parseFloat(s)||0),void 0===n&&(n=i?1:-1);var a=void 0!==r||i,l=r||s;if(-1===n)return a?l-ae(e,["border","padding"],o):s;if(a){var u=2===n?-ae(e,["border"],o):ae(e,["margin"],o);return l+(1===n?0:u)}return s+ae(e,ie.slice(n),o)}oe(["Width","Height"],(function(e){ue["doc".concat(e)]=function(t){var n=t.document;return Math.max(n.documentElement["scroll".concat(e)],n.body["scroll".concat(e)],ue["viewport".concat(e)](n))},ue["viewport".concat(e)]=function(t){var n="client".concat(e),o=t.document,r=o.body,i=o.documentElement[n];return"CSS1Compat"===o.compatMode&&i||r&&r[n]||i}}));var pe={position:"absolute",visibility:"hidden",display:"block"};function fe(e){var t,n=arguments;return 0!==e.offsetWidth?t=ce.apply(void 0,n):se(e,pe,(function(){t=ce.apply(void 0,n)})),t}function de(e,t,n){var o=n;if("object"!==Q(t))return void 0!==o?("number"==typeof o&&(o+="px"),void(e.style[t]=o)):ee(e,t);for(var r in t)t.hasOwnProperty(r)&&de(e,r,t[r])}oe(["width","height"],(function(e){var t=e.charAt(0).toUpperCase()+e.slice(1);ue["outer".concat(t)]=function(t,n){return t&&fe(t,e,n?0:1)};var n="width"===e?["Left","Right"]:["Top","Bottom"];ue[e]=function(t,o){if(void 0===o)return t&&fe(t,e,-1);if(t){ee(t);return re(t)&&(o+=ae(t,["padding","border"],n)),de(t,e,o)}}}));var he=function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?G(n,!0).forEach((function(t){$(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):G(n).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}({getWindow:function(e){var t=e.ownerDocument||e;return t.defaultView||t.parentWindow},offset:function(e,t){if(void 0===t)return Z(e);!function(e,t){"static"===de(e,"position")&&(e.style.position="relative");var n,o,r=Z(e),i={};for(o in t)t.hasOwnProperty(o)&&(n=parseFloat(de(e,o))||0,i[o]=n+t[o]-r[o]);de(e,i)}(e,t)},isWindow:le,each:oe,css:de,clone:function(e){var t={};for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n]);if(e.overflow)for(var o in e)e.hasOwnProperty(o)&&(t.overflow[o]=e.overflow[o]);return t},scrollLeft:function(e,t){if(le(e)){if(void 0===t)return Y(e);window.scrollTo(t,J(e))}else{if(void 0===t)return e.scrollLeft;e.scrollLeft=t}},scrollTop:function(e,t){if(le(e)){if(void 0===t)return J(e);window.scrollTo(Y(e),t)}else{if(void 0===t)return e.scrollTop;e.scrollTop=t}},viewportWidth:0,viewportHeight:0},ue);var ge=function(e,t,n){n=n||{},9===t.nodeType&&(t=he.getWindow(t));var o=n.allowHorizontalScroll,r=n.onlyScrollIfNeeded,i=n.alignWithTop,s=n.alignWithLeft,a=n.offsetTop||0,l=n.offsetLeft||0,u=n.offsetBottom||0,c=n.offsetRight||0;o=void 0===o||o;var p,f,d,h,g,v,b,m,y,w,k=he.isWindow(t),O=he.offset(e),S=he.outerHeight(e),L=he.outerWidth(e);k?(b=t,w=he.height(b),y=he.width(b),m={left:he.scrollLeft(b),top:he.scrollTop(b)},g={left:O.left-m.left-l,top:O.top-m.top-a},v={left:O.left+L-(m.left+y)+c,top:O.top+S-(m.top+w)+u},h=m):(p=he.offset(t),f=t.clientHeight,d=t.clientWidth,h={left:t.scrollLeft,top:t.scrollTop},g={left:O.left-(p.left+(parseFloat(he.css(t,"borderLeftWidth"))||0))-l,top:O.top-(p.top+(parseFloat(he.css(t,"borderTopWidth"))||0))-a},v={left:O.left+L-(p.left+d+(parseFloat(he.css(t,"borderRightWidth"))||0))+c,top:O.top+S-(p.top+f+(parseFloat(he.css(t,"borderBottomWidth"))||0))+u}),g.top<0||v.top>0?!0===i?he.scrollTop(t,h.top+g.top):!1===i?he.scrollTop(t,h.top+v.top):g.top<0?he.scrollTop(t,h.top+g.top):he.scrollTop(t,h.top+v.top):r||((i=void 0===i||!!i)?he.scrollTop(t,h.top+g.top):he.scrollTop(t,h.top+v.top)),o&&(g.left<0||v.left>0?!0===s?he.scrollLeft(t,h.left+g.left):!1===s?he.scrollLeft(t,h.left+v.left):g.left<0?he.scrollLeft(t,h.left+g.left):he.scrollLeft(t,h.left+v.left):r||((s=void 0===s||!!s)?he.scrollLeft(t,h.left+g.left):he.scrollLeft(t,h.left+v.left)))},ve=wp.i18n,be=ve.__,me=ve.sprintf,ye=ve._n,we=wp.element,ke=we.Component,Oe=we.createRef,Se=wp.htmlEntities.decodeEntities,Le=wp.keycodes,je=Le.UP,Ee=Le.DOWN,Ce=Le.ENTER,Pe=Le.TAB,xe=wp.components,_e=xe.Spinner,Ne=xe.withSpokenMessages,Re=xe.Popover,Fe=wp.compose.withInstanceId,Te=wp.apiFetch,We=wp.url.addQueryArgs,Ae=function(e){return e.stopPropagation()},De=Ne(Fe(function(e){function t(e){var n,o=e.autocompleteRef;return l()(this,t),(n=f()(this,h()(t).apply(this,arguments))).onChange=n.onChange.bind(v()(n)),n.onKeyDown=n.onKeyDown.bind(v()(n)),n.autocompleteRef=o||Oe(),n.inputRef=Oe(),n.updateSuggestions=Object(w.throttle)(n.updateSuggestions.bind(v()(n)),200),n.suggestionNodes=[],n.state={posts:[],showSuggestions:!1,selectedSuggestion:null},n}return m()(t,e),c()(t,[{key:"componentDidUpdate",value:function(){var e=this,t=this.state,n=t.showSuggestions,o=t.selectedSuggestion;n&&null!==o&&!this.scrollingIntoView&&(this.scrollingIntoView=!0,ge(this.suggestionNodes[o],this.autocompleteRef.current,{onlyScrollIfNeeded:!0}),setTimeout((function(){e.scrollingIntoView=!1}),100))}},{key:"componentWillUnmount",value:function(){delete this.suggestionsRequest}},{key:"bindSuggestionNode",value:function(e){var t=this;return function(n){t.suggestionNodes[e]=n}}},{key:"updateSuggestions",value:function(e){var t=this;if(e.length<2||/^https?:/.test(e))this.setState({showSuggestions:!1,selectedSuggestion:null,loading:!1});else{this.setState({showSuggestions:!0,selectedSuggestion:null,loading:!0});var n=Te({path:We("/wp/v2/search",{search:e,per_page:20,type:"post"})});n.then((function(e){t.suggestionsRequest===n&&(t.setState({posts:e,loading:!1}),e.length?t.props.debouncedSpeak(me(ye("%d result found, use up and down arrow keys to navigate.","%d results found, use up and down arrow keys to navigate.",e.length),e.length),"assertive"):t.props.debouncedSpeak(be("No results.","all-in-one-seo-pack"),"assertive"))})).catch((function(){t.suggestionsRequest===n&&t.setState({loading:!1})})),this.suggestionsRequest=n}}},{key:"onChange",value:function(e){var t=e.target.value;this.props.onChange(t),this.updateSuggestions(t)}},{key:"onKeyDown",value:function(e){var t=this.state,n=t.showSuggestions,o=t.selectedSuggestion,r=t.posts,i=t.loading;if(n&&r.length&&!i){var s=this.state.posts[this.state.selectedSuggestion];switch(e.keyCode){case je:e.stopPropagation(),e.preventDefault();var a=o?o-1:r.length-1;this.setState({selectedSuggestion:a});break;case Ee:e.stopPropagation(),e.preventDefault();var l=null===o||o===r.length-1?0:o+1;this.setState({selectedSuggestion:l});break;case Pe:null!==this.state.selectedSuggestion&&(this.selectLink(s),this.props.speak(be("Link selected.","all-in-one-seo-pack")));break;case Ce:null!==this.state.selectedSuggestion&&(e.stopPropagation(),this.selectLink(s))}}else switch(e.keyCode){case je:0!==e.target.selectionStart&&(e.stopPropagation(),e.preventDefault(),e.target.setSelectionRange(0,0));break;case Ee:this.props.value.length!==e.target.selectionStart&&(e.stopPropagation(),e.preventDefault(),e.target.setSelectionRange(this.props.value.length,this.props.value.length))}}},{key:"selectLink",value:function(e){this.props.onChange(e.url,e),this.setState({selectedSuggestion:null,showSuggestions:!1})}},{key:"handleOnClick",value:function(e){this.selectLink(e),this.inputRef.current.focus()}},{key:"render",value:function(){var e=this,t=this.props,n=t.value,o=void 0===n?"":n,r=t.autoFocus,i=void 0===r||r,s=t.instanceId,a=t.className,l=this.state,u=l.showSuggestions,c=l.posts,p=l.selectedSuggestion,f=l.loading;return Object(y.createElement)("div",{className:q()("editor-url-input block-editor-url-input",a)},Object(y.createElement)("input",{autoFocus:i,type:"text","aria-label":be("URL","all-in-one-seo-pack"),required:!0,value:o,onChange:this.onChange,onInput:Ae,placeholder:be("Paste URL or type to search","all-in-one-seo-pack"),onKeyDown:this.onKeyDown,role:"combobox","aria-expanded":u,"aria-autocomplete":"list","aria-owns":"editor-url-input-suggestions-".concat(s),"aria-activedescendant":null!==p?"editor-url-input-suggestion-".concat(s,"-").concat(p):void 0,ref:this.inputRef}),f&&Object(y.createElement)(_e,null),u&&!!c.length&&Object(y.createElement)(Re,{position:"bottom",noArrow:!0,focusOnMount:!1},Object(y.createElement)("div",{className:q()("editor-url-input__suggestions","block-editor-url-input__suggestions","".concat(a,"__suggestions")),id:"editor-url-input-suggestions-".concat(s),ref:this.autocompleteRef,role:"listbox"},c.map((function(t,n){return Object(y.createElement)("button",{key:t.id,role:"option",tabIndex:"-1",id:"editor-url-input-suggestion-".concat(s,"-").concat(n),ref:e.bindSuggestionNode(n),className:q()("editor-url-input__suggestion block-editor-url-input__suggestion",{"is-selected":n===p}),onClick:function(){return e.handleOnClick(t)},"aria-selected":n===p},Se(t.title)||be("(no title)","all-in-one-seo-pack"))})))))}}]),t}(ke))),Ie=wp.i18n.__,Ve=wp.components.IconButton;function Me(e){var t=e.autocompleteRef,n=e.className,o=e.onChangeInputValue,i=e.value,s=r()(e,["autocompleteRef","className","onChangeInputValue","value"]);return Object(y.createElement)("form",O()({className:q()("block-editor-url-popover__link-editor",n)},s),Object(y.createElement)(De,{value:i,onChange:o,autocompleteRef:t}),Object(y.createElement)(Ve,{icon:"editor-break",label:Ie("Apply","all-in-one-seo-pack"),type:"submit"}))}var Ue=wp.i18n.__,Ke=wp.components,Be=Ke.ExternalLink,He=Ke.IconButton,ze=wp.url,qe=ze.safeDecodeURI,Qe=ze.filterURLForDisplay;function $e(e){var t=e.url,n=e.urlLabel,o=e.className,r=q()(o,"block-editor-url-popover__link-viewer-url");return t?Object(y.createElement)(Be,{className:r,href:t},n||Qe(qe(t))):Object(y.createElement)("span",{className:r})}function Ge(e){var t=e.className,n=e.linkClassName,o=e.onEditLinkClick,i=e.url,s=e.urlLabel,a=r()(e,["className","linkClassName","onEditLinkClick","url","urlLabel"]);return Object(y.createElement)("div",O()({className:q()("block-editor-url-popover__link-viewer",t)},a),Object(y.createElement)($e,{url:i,urlLabel:s,className:n}),o&&Object(y.createElement)(He,{icon:"edit",label:Ue("Edit","all-in-one-seo-pack"),onClick:o}))}var Xe=wp.i18n.__,Ye=wp.element,Je=Ye.Component,Ze=Ye.createRef,et=Ye.useMemo,tt=Ye.Fragment,nt=wp.components,ot=nt.ToggleControl,rt=nt.withSpokenMessages,it=wp.keycodes,st=it.LEFT,at=it.RIGHT,lt=it.UP,ut=it.DOWN,ct=it.BACKSPACE,pt=it.ENTER,ft=it.ESCAPE,dt=wp.dom.getRectangleFromRange,ht=wp.url.prependHTTP,gt=wp.richText,vt=gt.create,bt=gt.insert,mt=gt.isCollapsed,yt=gt.applyFormat,wt=gt.getTextContent,kt=gt.slice,Ot=wp.blockEditor.URLPopover,St=function(e){return e.stopPropagation()};function Lt(e,t){return e.addingLink||t.editLink}var jt=function(e){var t=e.isActive,n=e.addingLink,o=e.value,i=e.resetOnMount,s=r()(e,["isActive","addingLink","value","resetOnMount"]),a=et((function(){var e=window.getSelection(),t=e.rangeCount>0?e.getRangeAt(0):null;if(t){if(n)return dt(t);var o=t.startContainer;for(o=o.nextElementSibling||o;o.nodeType!==window.Node.ELEMENT_NODE;)o=o.parentNode;var r=o.closest("a");return r?r.getBoundingClientRect():void 0}}),[t,n,o.start,o.end]);return a?(i(a),Object(y.createElement)(Ot,O()({anchorRect:a},s))):null},Et=rt(function(e){function t(){var e;return l()(this,t),(e=f()(this,h()(t).apply(this,arguments))).editLink=e.editLink.bind(v()(e)),e.submitLink=e.submitLink.bind(v()(e)),e.onKeyDown=e.onKeyDown.bind(v()(e)),e.onChangeInputValue=e.onChangeInputValue.bind(v()(e)),e.setLinkTarget=e.setLinkTarget.bind(v()(e)),e.setNoFollow=e.setNoFollow.bind(v()(e)),e.setSponsored=e.setSponsored.bind(v()(e)),e.onFocusOutside=e.onFocusOutside.bind(v()(e)),e.resetState=e.resetState.bind(v()(e)),e.autocompleteRef=Ze(),e.resetOnMount=e.resetOnMount.bind(v()(e)),e.state={opensInNewWindow:!1,noFollow:!1,sponsored:!1,inputValue:"",anchorRect:!1},e}return m()(t,e),c()(t,[{key:"onKeyDown",value:function(e){[st,ut,at,lt,ct,pt].indexOf(e.keyCode)>-1&&e.stopPropagation(),[ft].indexOf(e.keyCode)>-1&&this.resetState()}},{key:"onChangeInputValue",value:function(e){this.setState({inputValue:e})}},{key:"setLinkTarget",value:function(e){var t=this.props,n=t.activeAttributes.url,o=void 0===n?"":n,r=t.value,i=t.onChange;if(this.setState({opensInNewWindow:e}),!Lt(this.props,this.state)){var s=wt(kt(r));i(yt(r,I({url:o,opensInNewWindow:e,noFollow:this.state.noFollow,sponsored:this.state.sponsored,text:s})))}}},{key:"setNoFollow",value:function(e){var t=this.props,n=t.activeAttributes.url,o=void 0===n?"":n,r=t.value,i=t.onChange;if(this.setState({noFollow:e}),!Lt(this.props,this.state)){var s=wt(kt(r));i(yt(r,I({url:o,opensInNewWindow:this.state.opensInNewWindow,noFollow:e,sponsored:this.state.sponsored,text:s})))}}},{key:"setSponsored",value:function(e){var t=this.props,n=t.activeAttributes.url,o=void 0===n?"":n,r=t.value,i=t.onChange;if(this.setState({sponsored:e}),!Lt(this.props,this.state)){var s=wt(kt(r));i(yt(r,I({url:o,opensInNewWindow:this.state.opensInNewWindow,noFollow:this.state.noFollow,sponsored:e,text:s})))}}},{key:"editLink",value:function(e){this.setState({editLink:!0}),e.preventDefault()}},{key:"submitLink",value:function(e){var t=this.props,n=t.isActive,o=t.value,r=t.onChange,i=t.speak,s=this.state,a=s.inputValue,l=s.opensInNewWindow,u=s.noFollow,c=s.sponsored,p=ht(a),f=I({url:p,opensInNewWindow:l,noFollow:u,sponsored:c,text:wt(kt(o))});if(e.preventDefault(),mt(o)&&!n){var d=yt(vt({text:p}),f,0,p.length);r(bt(o,d))}else r(yt(o,f));this.resetState(),D(p)?i(Xe(n?"Link edited.":"Link inserted.","all-in-one-seo-pack"),"assertive"):i(Xe("Warning: the link has been inserted but could have errors. Please test it.","all-in-one-seo-pack"),"assertive")}},{key:"onFocusOutside",value:function(){var e=this.autocompleteRef.current;e&&e.contains(event.target)||this.resetState()}},{key:"resetState",value:function(){this.props.stopAddingLink(),this.setState({editLink:!1})}},{key:"resetOnMount",value:function(e){this.state.anchorRect!==e&&this.setState({opensInNewWindow:!1,noFollow:!1,sponsored:!1,anchorRect:e})}},{key:"render",value:function(){var e=this,t=this.props,n=t.isActive,o=t.activeAttributes,r=o.url,i=o.target,s=o.rel,a=t.addingLink,l=t.value;if(!n&&!a)return null;var u=this.state,c=u.inputValue,p=u.opensInNewWindow,f=u.noFollow,d=u.sponsored,h=Lt(this.props,this.state);if(p||"_blank"!==i||this.setState({opensInNewWindow:!0}),"string"==typeof s){var g=s.split(" ").includes("nofollow"),v=s.split(" ").includes("sponsored");g!==f&&this.setState({noFollow:g}),v!==d&&this.setState({sponsored:v})}return Object(y.createElement)(H,{key:"".concat(l.start).concat(l.end)},Object(y.createElement)(jt,{resetOnMount:this.resetOnMount,value:l,isActive:n,addingLink:a,onFocusOutside:this.onFocusOutside,onClose:function(){c||e.resetState()},focusOnMount:!!h&&"firstElement",renderSettings:function(){return Object(y.createElement)(tt,null,Object(y.createElement)(ot,{label:Xe("Open in New Tab","all-in-one-seo-pack"),checked:p,onChange:e.setLinkTarget}),Object(y.createElement)(ot,{label:Xe('Add "nofollow" to link',"all-in-one-seo-pack"),checked:f,onChange:e.setNoFollow}),Object(y.createElement)(ot,{label:Xe('Add "sponsored" to link',"all-in-one-seo-pack"),checked:d,onChange:e.setSponsored}))}},h?Object(y.createElement)(Me,{className:"editor-format-toolbar__link-container-content block-editor-format-toolbar__link-container-content",value:c,onChangeInputValue:this.onChangeInputValue,onKeyDown:this.onKeyDown,onKeyPress:St,onSubmit:this.submitLink,autocompleteRef:this.autocompleteRef}):Object(y.createElement)(Ge,{className:"editor-format-toolbar__link-container-content block-editor-format-toolbar__link-container-content",onKeyPress:St,url:r,onEditLinkClick:this.editLink,linkClassName:D(ht(r))?void 0:"has-invalid-link"})))}}],[{key:"getDerivedStateFromProps",value:function(e,t){var n=e.activeAttributes,o=n.url,r=n.target,i=n.rel,s="_blank"===r;if(!Lt(e,t)){if(o!==t.inputValue)return{inputValue:o};if(s!==t.opensInNewWindow)return{opensInNewWindow:s};if("string"==typeof i){var a=i.split(" ").includes("nofollow"),l=i.split(" ").includes("sponsored");if(a!==t.noFollow)return{noFollow:a};if(l!==t.sponsored)return{sponsored:l}}}return null}}]),t}(Je));function Ct(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function Pt(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?Ct(Object(n),!0).forEach((function(t){s()(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Ct(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}var xt=wp.i18n.__,_t=wp.element,Nt=_t.Component,Rt=_t.Fragment,Ft=wp.data,Tt=Ft.select,Wt=Ft.withSelect,At=Ft.dispatch,Dt=wp.blockEditor,It=Dt.BlockControls,Vt=Dt.RichTextToolbarButton,Mt=Dt.RichTextShortcut,Ut=wp.richText,Kt=Ut.getTextContent,Bt=Ut.applyFormat,Ht=Ut.removeFormat,zt=Ut.slice,qt=Ut.getActiveFormat,Qt=wp.url.isURL,$t=wp.components,Gt=$t.Toolbar,Xt=$t.withSpokenMessages,Yt=wp.compose,Jt=Yt.compose,Zt=Yt.ifCondition,en=xt("Add Link","all-in-one-seo-pack"),tn=/^(mailto:)?[a-z0-9._%+-]+@[a-z0-9][a-z0-9.-]*\.[a-z]{2,63}$/i,nn=function(e){function t(){var e;return l()(this,t),(e=f()(this,h()(t).apply(this,arguments))).isEmail=e.isEmail.bind(v()(e)),e.addLink=e.addLink.bind(v()(e)),e.stopAddingLink=e.stopAddingLink.bind(v()(e)),e.onRemoveFormat=e.onRemoveFormat.bind(v()(e)),e.state={addingLink:!1},e}return m()(t,e),c()(t,[{key:"componentDidMount",value:function(){var e=Tt("core/rich-text").getFormatType("core/link");e&&(e.edit=null,At("core/rich-text").addFormatTypes(e))}},{key:"isEmail",value:function(e){return tn.test(e)}},{key:"addLink",value:function(){var e=this.props,t=e.value,n=e.onChange,o=Kt(zt(t));o&&Qt(o)?n(Bt(t,{type:"aioseop/link",attributes:{url:o}})):o&&this.isEmail(o)?n(Bt(t,{type:"aioseop/link",attributes:{url:"mailto:".concat(o)}})):this.setState({addingLink:!0})}},{key:"stopAddingLink",value:function(){this.setState({addingLink:!1})}},{key:"onRemoveFormat",value:function(){var e=this.props,t=e.value,n=e.onChange,o=e.speak,r=t;Object(w.map)(["core/link","aioseop/link"],(function(e){r=Ht(r,e)})),n(Pt({},r)),o(xt("Link removed.","all-in-one-seo-pack"),"assertive")}},{key:"render",value:function(){var e=this.props,t=e.activeAttributes,n=e.onChange,o=this.props,r=o.isActive,i=o.value,s=qt(i,"core/link");if(s){s.type="aioseop/link";var a=i;a=Bt(a,s),n(Pt({},a=Ht(a,"core/link"))),i=a,r=!0}return Object(y.createElement)(Rt,null,Object(y.createElement)(It,null,Object(y.createElement)(Gt,{className:"editorskit-components-toolbar"},Object(y.createElement)(Mt,{type:"primary",character:"k",onUse:this.addLink}),Object(y.createElement)(Mt,{type:"primaryShift",character:"k",onUse:this.onRemoveFormat}),r&&Object(y.createElement)(Vt,{name:"link",icon:"editor-unlink",title:xt("Unlink","all-in-one-seo-pack"),onClick:this.onRemoveFormat,isActive:r,shortcutType:"primaryShift",shortcutCharacter:"k"}),!r&&Object(y.createElement)(Vt,{name:"link",icon:"admin-links",title:en,onClick:this.addLink,isActive:r,shortcutType:"primary",shortcutCharacter:"k"}),Object(y.createElement)(Et,{addingLink:this.state.addingLink,stopAddingLink:this.stopAddingLink,isActive:r,activeAttributes:t,value:i,onChange:n}))))}}]),t}(Nt),on=Jt(Wt((function(){return{isDisabled:Tt("core/edit-post").isFeatureActive("disableEditorsKitLinkFormats")}})),Zt((function(e){return!e.isDisabled})),Xt)(nn);n.d(t,"link",(function(){return fn}));var rn=wp.i18n.__,sn=wp.richText,an=sn.registerFormatType,ln=sn.applyFormat,un=sn.isCollapsed,cn=wp.htmlEntities.decodeEntities,pn=wp.url.isURL,fn={name:"aioseop/link",title:rn("Link","all-in-one-seo-pack"),tagName:"a",className:"aioseop-link",attributes:{url:"href",target:"target",rel:"rel"},__unstablePasteRule:function(e,t){var n=t.html,o=t.plainText;if(un(e))return e;var r=(n||o).replace(/<[^>]+>/g,"").trim();return pn(r)?ln(e,{type:"aioseop/link",attributes:{url:cn(r)}}):e},edit:on};[fn].forEach((function(e){var t=e.name,n=r()(e,["name"]);t&&an(t,n)}))}]);
 
 
 
 
 
 
class-aioseop-core.php CHANGED
@@ -61,6 +61,7 @@ class AIOSEOP_Core {
61
  'bad_robots',
62
  'performance',
63
  'video_sitemap',
 
64
  'image_seo',
65
  );
66
 
@@ -136,14 +137,9 @@ class AIOSEOP_Core {
136
  }
137
  // ^^ TODO Should this be moved to (Pro) updater class?
138
 
139
- // TODO Move this to updates file.
140
- // FIXME This is executed in AIOSEOP_Core::aioseop_welcome() on admin_init hook.
141
- new aioseop_welcome();
142
  AIOSEOP_Education::init();
143
  AIOSEOP_Flyout::init();
144
 
145
- add_action( 'admin_init', array( $this, 'aioseop_welcome' ) );
146
-
147
  // TODO Move this add_action to All_in_One_SEO_Pack::__construct().
148
  add_action( 'init', array( $aiosp, 'add_hooks' ) );
149
 
@@ -331,7 +327,7 @@ class AIOSEOP_Core {
331
  require_once AIOSEOP_PLUGIN_DIR . 'inc/compatibility/class-aioseop-php-functions.php';
332
  require_once AIOSEOP_PLUGIN_DIR . 'public/front.php';
333
  require_once AIOSEOP_PLUGIN_DIR . 'public/google-analytics.php';
334
- require_once AIOSEOP_PLUGIN_DIR . 'admin/display/welcome.php';
335
  require_once AIOSEOP_PLUGIN_DIR . 'admin/display/dashboard_widget.php';
336
  require_once AIOSEOP_PLUGIN_DIR . 'admin/display/menu.php';
337
  require_once AIOSEOP_PLUGIN_DIR . 'admin/class-aioseop-notices.php';
@@ -403,6 +399,8 @@ class AIOSEOP_Core {
403
  public function add_hooks() {
404
  global $wp_version;
405
 
 
 
406
  add_action( 'plugins_loaded', array( $this, 'add_cap' ) );
407
 
408
  add_action( 'init', 'aioseop_load_modules', 1 );
@@ -707,19 +705,6 @@ class AIOSEOP_Core {
707
  return $actions;
708
  }
709
 
710
- /**
711
- * AIOSEOP's Welcome Page
712
- *
713
- * @since ?
714
- */
715
- public function aioseop_welcome() {
716
- if ( get_transient( '_aioseop_activation_redirect' ) ) {
717
- $aioseop_welcome = new aioseop_welcome();
718
- delete_transient( '_aioseop_activation_redirect' );
719
- $aioseop_welcome->init( true );
720
- }
721
- }
722
-
723
  /**
724
  * Admin Notices Already Defined
725
  *
@@ -788,10 +773,12 @@ class AIOSEOP_Core {
788
  /**
789
  * Enqueues stylesheets used on the frontend.
790
  *
791
- * @since 3.4.0
 
 
792
  */
793
  function front_enqueue_styles() {
794
- if ( ! is_user_logged_in() ) {
795
  return;
796
  }
797
  wp_enqueue_style( 'aioseop-toolbar-menu', AIOSEOP_PLUGIN_URL . 'css/admin-toolbar-menu.css', null, AIOSEOP_VERSION, 'all' );
61
  'bad_robots',
62
  'performance',
63
  'video_sitemap',
64
+ 'schema_local_business',
65
  'image_seo',
66
  );
67
 
137
  }
138
  // ^^ TODO Should this be moved to (Pro) updater class?
139
 
 
 
 
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
 
327
  require_once AIOSEOP_PLUGIN_DIR . 'inc/compatibility/class-aioseop-php-functions.php';
328
  require_once AIOSEOP_PLUGIN_DIR . 'public/front.php';
329
  require_once AIOSEOP_PLUGIN_DIR . 'public/google-analytics.php';
330
+ require_once AIOSEOP_PLUGIN_DIR . 'admin/display/aioseop-welcome.php';
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';
399
  public function add_hooks() {
400
  global $wp_version;
401
 
402
+ AIOSEOP_Welcome::hooks();
403
+
404
  add_action( 'plugins_loaded', array( $this, 'add_cap' ) );
405
 
406
  add_action( 'init', 'aioseop_load_modules', 1 );
705
  return $actions;
706
  }
707
 
 
 
 
 
 
 
 
 
 
 
 
 
 
708
  /**
709
  * Admin Notices Already Defined
710
  *
773
  /**
774
  * Enqueues stylesheets used on the frontend.
775
  *
776
+ * @since 3.4.0
777
+ *
778
+ * @return void
779
  */
780
  function front_enqueue_styles() {
781
+ if ( ! current_user_can( 'aiosp_manage_seo' ) ) {
782
  return;
783
  }
784
  wp_enqueue_style( 'aioseop-toolbar-menu', AIOSEOP_PLUGIN_URL . 'css/admin-toolbar-menu.css', null, AIOSEOP_VERSION, 'all' );
css/admin-toolbar-menu.css CHANGED
@@ -11,4 +11,36 @@
11
  background-size: 20px;
12
  color: #a0a5aa;
13
  content: url("data:image/svg+xml,%3Csvg width='20px' height='20px' viewBox='0 0 516 516' xmlns='http://www.w3.org/2000/svg' fill-rule='evenodd' clip-rule='evenodd' stroke-linejoin='round' stroke-miterlimit='2' fill='%23a0a5aa'%3E%3Cpath d='M313.09629 56.767c15.572 4.282 30.418 10.326 44.308 17.903l49.035-35.771 68.022 68.023-35.24 48.172c7.827 13.776 14.13 28.529 18.681 44.029l57.95 9.064v96.198l-56.968 8.832c-4.446 16.178-10.792 31.571-18.785 45.925l36.485 49.874-68.022 68.023-50.057-36.517c-13.54 7.493-28 13.523-43.166 17.878l-8.92 57.538h-96.199l-8.949-57.218c-15.633-4.394-30.525-10.565-44.443-18.282l-47.249 34.468-68.023-68.022 34.305-46.894c-7.89-14.015-14.206-29.031-18.71-44.81l-57.151-8.86v-96.199l56.983-8.912c4.331-15.347 10.377-29.979 17.916-43.674l-35.466-48.48 68.023-68.023 48.061 35.061c13.641-7.693 28.234-13.895 43.554-18.384L208.09729 0h96.198l8.801 56.767zm-38.657 342.655c70.789-8.277 125.797-68.527 125.797-141.523 0-78.644-63.849-142.493-142.493-142.493s-142.493 63.849-142.493 142.493c0 73.293 55.457 133.737 126.663 141.621v-44.549c-36.12-7.515-63.294-39.554-63.294-77.89v-48.998h33.367v-50.298c0-5.447 4.423-9.87 9.871-9.87 5.447 0 9.87 4.423 9.87 9.87v50.298h52.726v-50.298c0-5.447 4.423-9.87 9.87-9.87 5.448 0 9.87 4.423 9.87 9.87v50.298h33.54v48.998c0 38.336-27.174 70.375-63.294 77.89v44.451z'/%3E%3C/svg%3E%0A");
14
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  background-size: 20px;
12
  color: #a0a5aa;
13
  content: url("data:image/svg+xml,%3Csvg width='20px' height='20px' viewBox='0 0 516 516' xmlns='http://www.w3.org/2000/svg' fill-rule='evenodd' clip-rule='evenodd' stroke-linejoin='round' stroke-miterlimit='2' fill='%23a0a5aa'%3E%3Cpath d='M313.09629 56.767c15.572 4.282 30.418 10.326 44.308 17.903l49.035-35.771 68.022 68.023-35.24 48.172c7.827 13.776 14.13 28.529 18.681 44.029l57.95 9.064v96.198l-56.968 8.832c-4.446 16.178-10.792 31.571-18.785 45.925l36.485 49.874-68.022 68.023-50.057-36.517c-13.54 7.493-28 13.523-43.166 17.878l-8.92 57.538h-96.199l-8.949-57.218c-15.633-4.394-30.525-10.565-44.443-18.282l-47.249 34.468-68.023-68.022 34.305-46.894c-7.89-14.015-14.206-29.031-18.71-44.81l-57.151-8.86v-96.199l56.983-8.912c4.331-15.347 10.377-29.979 17.916-43.674l-35.466-48.48 68.023-68.023 48.061 35.061c13.641-7.693 28.234-13.895 43.554-18.384L208.09729 0h96.198l8.801 56.767zm-38.657 342.655c70.789-8.277 125.797-68.527 125.797-141.523 0-78.644-63.849-142.493-142.493-142.493s-142.493 63.849-142.493 142.493c0 73.293 55.457 133.737 126.663 141.621v-44.549c-36.12-7.515-63.294-39.554-63.294-77.89v-48.998h33.367v-50.298c0-5.447 4.423-9.87 9.871-9.87 5.447 0 9.87 4.423 9.87 9.87v50.298h52.726v-50.298c0-5.447 4.423-9.87 9.87-9.87 5.448 0 9.87 4.423 9.87 9.87v50.298h33.54v48.998c0 38.336-27.174 70.375-63.294 77.89v44.451z'/%3E%3C/svg%3E%0A");
14
+ }
15
+
16
+ #wpadminbar .aioseo-menu-notification-counter {
17
+ display: inline-block !important;
18
+ vertical-align: top !important;
19
+ box-sizing: border-box !important;
20
+ margin: 7px 0 0 2px !important;
21
+ padding: 0 5px !important;
22
+ min-width: 18px !important;
23
+ height: 18px !important;
24
+ border-radius: 9px !important;
25
+ background-color: #ca4a1f !important;
26
+ color: #fff !important;
27
+ font-size: 11px !important;
28
+ line-height: 1.6 !important;
29
+ text-align: center !important;
30
+ }
31
+
32
+ #wpadminbar .aioseo-menu-notification-counter span {
33
+ line-height: 1 !important;
34
+ font-size: 11px !important;
35
+ }
36
+
37
+ #wpadminbar .aioseo-menu-notification-indicator {
38
+ float: right;
39
+ margin: 10px 0 0;
40
+ width: 8px !important;
41
+ height: 8px !important;
42
+ border-radius: 50% !important;
43
+ background-color: #ca4a1f !important;
44
+ line-height: 1.6 !important;
45
+ animation: aioseo-menu-notification-indicator-pulse 1.5s infinite !important;
46
+ }
css/admin/aioseop-about.css CHANGED
@@ -3458,6 +3458,7 @@ body.rtl #aioseop-entries-list .wp-list-table div[data-field-type="phone"] {
3458
  font-size: 16px;
3459
  }
3460
 
 
3461
  #aioseop-admin-about .aioseop-admin-about-section p {
3462
  margin-bottom: 20px;
3463
  }
@@ -3474,6 +3475,11 @@ body.rtl #aioseop-entries-list .wp-list-table div[data-field-type="phone"] {
3474
  margin-bottom: 0;
3475
  }
3476
 
 
 
 
 
 
3477
  #aioseop-admin-about .aioseop-admin-about-section hr {
3478
  margin: 30px 0;
3479
  }
3458
  font-size: 16px;
3459
  }
3460
 
3461
+
3462
  #aioseop-admin-about .aioseop-admin-about-section p {
3463
  margin-bottom: 20px;
3464
  }
3475
  margin-bottom: 0;
3476
  }
3477
 
3478
+ #aioseop-admin-about .aioseop-admin-about-section ul {
3479
+ list-style: disc;
3480
+ list-style-position: inside;
3481
+ }
3482
+
3483
  #aioseop-admin-about .aioseop-admin-about-section hr {
3484
  margin: 30px 0;
3485
  }
css/aiosp_admin.css CHANGED
@@ -207,6 +207,7 @@ label[for=aioseop_edit_profile_header] {
207
  /** Taxonomies upsell **/
208
 
209
  .aioseop-preview-wrapper {
 
210
  max-width: 800px;
211
  margin-top: 30px;
212
  }
@@ -480,12 +481,57 @@ label[for=aioseop_edit_profile_header] {
480
 
481
  /* Fixes the default CSS for the Classic Editor link modal. */
482
 
483
- #wp-link-wrap {
484
- height: 530px !important;
485
- margin-top: -265px !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
486
  }
487
 
488
- #search-results,
489
- #most-recent-results {
490
- margin-top: 55px !important;
491
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
207
  /** Taxonomies upsell **/
208
 
209
  .aioseop-preview-wrapper {
210
+ clear: both;
211
  max-width: 800px;
212
  margin-top: 30px;
213
  }
481
 
482
  /* Fixes the default CSS for the Classic Editor link modal. */
483
 
484
+ body #most-recent-results {
485
+ margin-top: 0 !important;
486
+ }
487
+ body #wp-link .query-results {
488
+ position: initial;
489
+ }
490
+ body #wp-link .query-results ul {
491
+ max-height: 200px;
492
+ overflow: scroll;
493
+ }
494
+ body #wp-link-wrap #link-selector {
495
+ overflow: auto;
496
+ }
497
+
498
+ @media (max-width: 782px) {
499
+ body #wp-link-wrap {
500
+ top: 30%;
501
+ }
502
+ body #wp-link .link-target label {
503
+ line-height: 30px;
504
+ }
505
  }
506
 
507
+ #wpadminbar .aioseo-menu-notification-counter {
508
+ display: inline-block !important;
509
+ vertical-align: top !important;
510
+ box-sizing: border-box !important;
511
+ margin: 7px 0 0 2px !important;
512
+ padding: 0 5px !important;
513
+ min-width: 18px !important;
514
+ height: 18px !important;
515
+ border-radius: 9px !important;
516
+ background-color: #ca4a1f !important;
517
+ color: #fff !important;
518
+ font-size: 11px !important;
519
+ line-height: 1.6 !important;
520
+ text-align: center !important;
521
+ }
522
+
523
+ #wpadminbar .aioseo-menu-notification-counter span {
524
+ line-height: 1 !important;
525
+ font-size: 11px !important;
526
+ }
527
+
528
+ #wpadminbar .aioseo-menu-notification-indicator {
529
+ float: right;
530
+ margin: 10px 0 0;
531
+ width: 8px !important;
532
+ height: 8px !important;
533
+ border-radius: 50% !important;
534
+ background-color: #ca4a1f !important;
535
+ line-height: 1.6 !important;
536
+ animation: aioseo-menu-notification-indicator-pulse 1.5s infinite !important;
537
+ }
css/modules/aioseop_module-rtl.css CHANGED
@@ -305,7 +305,7 @@ form#aiosp_settings_form,
305
  margin-bottom: 5px !important;
306
  }
307
 
308
- #aioseop-about .aioseop_metabox_text ul {
309
  padding-right: 15px;
310
  }
311
 
305
  margin-bottom: 5px !important;
306
  }
307
 
308
+ #aioseop-welcome .aioseop_metabox_text ul {
309
  padding-right: 15px;
310
  }
311
 
css/modules/aioseop_module.css CHANGED
@@ -132,6 +132,14 @@
132
  max-width: 600px;
133
  }
134
 
 
 
 
 
 
 
 
 
135
  .aioseop textarea {
136
  color: #515151;
137
  padding: 10px;
@@ -357,12 +365,12 @@
357
  line-height: 29px;
358
  }
359
 
360
- #aioseop-about {
361
  width: 443px;
362
  margin-bottom: 20px;
363
  }
364
 
365
- #aioseop-about .aioseop_metabox_text #mc-embedded-subscribe-form h2 {
366
  font-size: 13px;
367
  }
368
 
@@ -370,7 +378,7 @@
370
  padding: 0px 10px;
371
  }
372
 
373
- #aioseop-about .aioseop_metabox_text ul {
374
  list-style-type: disc;
375
  padding-left: 15px;
376
  }
@@ -1642,3 +1650,46 @@ body[class*="all-in-one-seo_page_all-in-one-seo-pack"] #ui-datepicker-div table.
1642
  border: 1px solid #8d96a0;
1643
  padding: 5px 7px;
1644
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  max-width: 600px;
133
  }
134
 
135
+ .aioseop input:disabled {
136
+ background: #3f3e3e1a;
137
+ }
138
+
139
+ .aioseop_input input[type="checkbox"]:disabled:before {
140
+ display: none !important;
141
+ }
142
+
143
  .aioseop textarea {
144
  color: #515151;
145
  padding: 10px;
365
  line-height: 29px;
366
  }
367
 
368
+ #aioseop-welcome {
369
  width: 443px;
370
  margin-bottom: 20px;
371
  }
372
 
373
+ #aioseop-welcome .aioseop_metabox_text #mc-embedded-subscribe-form h2 {
374
  font-size: 13px;
375
  }
376
 
378
  padding: 0px 10px;
379
  }
380
 
381
+ #aioseop-welcome .aioseop_metabox_text ul {
382
  list-style-type: disc;
383
  padding-left: 15px;
384
  }
1650
  border: 1px solid #8d96a0;
1651
  padding: 5px 7px;
1652
  }
1653
+
1654
+ .aioseop_label_street_address,
1655
+ .aioseop_label_address_locality,
1656
+ .aioseop_label_address_region,
1657
+ .aioseop_label_postal_code,
1658
+ .aioseop_label_address_country {
1659
+ float: left;
1660
+ width: 90px;
1661
+ margin-left: 9px;
1662
+ padding-top: 12px;
1663
+ }
1664
+
1665
+ .aioseop_label_street_address,
1666
+ .aioseop_label_address_locality,
1667
+ .aioseop_label_address_region,
1668
+ .aioseop_label_address_country {
1669
+ clear: left;
1670
+ }
1671
+
1672
+ .aioseop_label_postal_code {
1673
+
1674
+ }
1675
+
1676
+ .aioseop_postal_address input.aioseop_input_street_address,
1677
+ .aioseop_postal_address input.aioseop_input_address_locality,
1678
+ .aioseop_postal_address input.aioseop_input_address_region,
1679
+ .aioseop_postal_address input.aioseop_input_postal_code,
1680
+ .aioseop_postal_address input.aioseop_input_address_country {
1681
+ float: left;
1682
+ }
1683
+
1684
+ .aioseop_postal_address input.aioseop_input_street_address,
1685
+ .aioseop_postal_address input.aioseop_input_address_locality,
1686
+ .aioseop_postal_address input.aioseop_input_address_country {
1687
+ width: calc( 95% - 99px );
1688
+ max-width: 510px;
1689
+ }
1690
+
1691
+ .aioseop_postal_address input.aioseop_input_address_region,
1692
+ .aioseop_postal_address input.aioseop_input_postal_code {
1693
+ width: calc( 47% - 98px );
1694
+ max-width: 209px;
1695
+ }
images/default-thumbnail.png ADDED
Binary file
inc/admin/class-aioseop-education.php CHANGED
@@ -37,8 +37,6 @@ class AIOSEOP_Education {
37
 
38
  return;
39
  }
40
-
41
- add_filter( 'admin_bar_menu', array( 'AIOSEOP_Education', 'wp_admin_bar_menu' ) );
42
  }
43
 
44
  /**
@@ -161,7 +159,7 @@ class AIOSEOP_Education {
161
  * @since 3.4.0
162
  */
163
  private static function enqueue_news_sitemap_upsell_script() {
164
- if (
165
  'all-in-one-seo_page_' . AIOSEOP_PLUGIN_DIRNAME . '/modules/aioseop_sitemap' !== get_current_screen()->id &&
166
  'all-in-one-seo_page_' . AIOSEOP_PLUGIN_DIRNAME . '/pro/class-aioseop-pro-sitemap' !== get_current_screen()->id
167
  ) {
@@ -431,7 +429,7 @@ class AIOSEOP_Education {
431
  $link = __( 'Upgrade to Pro to unlock this feature.', 'all-in-one-seo-pack' );
432
  if( AIOSEOPPRO && !aioseop_is_addon_allowed('news_sitemap') ) {
433
  $message = __( 'Did you know that Business & Agency plan users also have access to Google News sitemaps?&nbsp;', 'all-in-one-seo-pack' );
434
- $link = __( 'Upgrade to a higher tier to unlock this feature.', 'all-in-one-seo-pack' );
435
  }
436
 
437
  printf(
@@ -594,8 +592,9 @@ class AIOSEOP_Education {
594
  *
595
  * @param Object $wp_admin_bar
596
  */
597
- public static function wp_admin_bar_menu( $wp_admin_bar ) {
598
- $url = get_permalink();
 
599
 
600
  if ( ! $url ) {
601
  return;
@@ -625,12 +624,12 @@ class AIOSEOP_Education {
625
  array(
626
  'id' => 'aioseop-external-tools-structureddata',
627
  'title' => __( 'Google Structured Data Test', 'all-in-one-seo-pack' ),
628
- 'href' => 'https://search.google.com/structured-data/testing-tool#url=' . $url,
629
  ),
630
  array(
631
  'id' => 'aioseop-external-tools-facebookdebug',
632
  'title' => __( 'Facebook Debugger', 'all-in-one-seo-pack' ),
633
- 'href' => '//developers.facebook.com/tools/debug/og/object?q=' . $url,
634
  ),
635
  array(
636
  'id' => 'aioseop-external-tools-pinterestvalidator',
@@ -657,6 +656,11 @@ class AIOSEOP_Education {
657
  'title' => __( 'Mobile-Friendly Test', 'all-in-one-seo-pack' ),
658
  'href' => 'https://www.google.com/webmasters/tools/mobile-friendly/?url=' . $url,
659
  ),
 
 
 
 
 
660
  );
661
 
662
  foreach ( $submenu_items as $menu_item ) {
@@ -742,16 +746,16 @@ class AIOSEOP_Education {
742
 
743
  /**
744
  * Checks if new conflicting plugins were found and resets notice status.
745
- *
746
  * @since 3.4.3
747
- *
748
  * @param array $conflicting_plugins
749
  */
750
  private static function check_new_conflicting_plugins( $conflicting_plugins ) {
751
  // get_option() doesn't work here because it returns false if the option is blank, and we need to know if it exists.
752
  global $wpdb;
753
  $count = (int) $wpdb->get_var( "select count(*) from {$wpdb->prefix}options where option_name = 'aioseop_detected_conflicting_plugins'");
754
-
755
  $stored = array();
756
  if( 0 !== $count ) {
757
  $stored = get_option( 'aioseop_detected_conflicting_plugins' );
@@ -759,7 +763,7 @@ class AIOSEOP_Education {
759
  } else {
760
  add_option( 'aioseop_detected_conflicting_plugins', $conflicting_plugins );
761
  }
762
-
763
  if ( count( $stored ) < count( $conflicting_plugins ) ) {
764
  if( get_user_meta( get_current_user_id(), 'aioseop_notice_display_time_conflicting_plugin' ) ) {
765
  delete_user_meta( get_current_user_id(), 'aioseop_notice_display_time_conflicting_plugin' );
@@ -814,8 +818,7 @@ class AIOSEOP_Education {
814
 
815
  sprintf(
816
  __(
817
- '<strong>Warning</strong>: %s has detected other active SEO or sitemap plugins.
818
- We recommend that you deactivate the following plugins to prevent any conflicts:',
819
  'all-in-one-seo-pack'
820
  ),
821
  AIOSEOP_PLUGIN_NAME
37
 
38
  return;
39
  }
 
 
40
  }
41
 
42
  /**
159
  * @since 3.4.0
160
  */
161
  private static function enqueue_news_sitemap_upsell_script() {
162
+ if (
163
  'all-in-one-seo_page_' . AIOSEOP_PLUGIN_DIRNAME . '/modules/aioseop_sitemap' !== get_current_screen()->id &&
164
  'all-in-one-seo_page_' . AIOSEOP_PLUGIN_DIRNAME . '/pro/class-aioseop-pro-sitemap' !== get_current_screen()->id
165
  ) {
429
  $link = __( 'Upgrade to Pro to unlock this feature.', 'all-in-one-seo-pack' );
430
  if( AIOSEOPPRO && !aioseop_is_addon_allowed('news_sitemap') ) {
431
  $message = __( 'Did you know that Business & Agency plan users also have access to Google News sitemaps?&nbsp;', 'all-in-one-seo-pack' );
432
+ $link = __( 'Upgrade to our Business or Agency plans to unlock this feature.', 'all-in-one-seo-pack' );
433
  }
434
 
435
  printf(
592
  *
593
  * @param Object $wp_admin_bar
594
  */
595
+ public static function external_tools( $wp_admin_bar ) {
596
+ global $wp;
597
+ $url = home_url( $wp->request );
598
 
599
  if ( ! $url ) {
600
  return;
624
  array(
625
  'id' => 'aioseop-external-tools-structureddata',
626
  'title' => __( 'Google Structured Data Test', 'all-in-one-seo-pack' ),
627
+ 'href' => 'https://search.google.com/test/rich-results?url=' . $url,
628
  ),
629
  array(
630
  'id' => 'aioseop-external-tools-facebookdebug',
631
  'title' => __( 'Facebook Debugger', 'all-in-one-seo-pack' ),
632
+ 'href' => 'https://developers.facebook.com/tools/debug/?q=' . $url,
633
  ),
634
  array(
635
  'id' => 'aioseop-external-tools-pinterestvalidator',
656
  'title' => __( 'Mobile-Friendly Test', 'all-in-one-seo-pack' ),
657
  'href' => 'https://www.google.com/webmasters/tools/mobile-friendly/?url=' . $url,
658
  ),
659
+ array(
660
+ 'id' => 'aioseo-external-tools-linkedin-post-inspector',
661
+ 'title' => __( 'LinkedIn Post Inspector', 'all-in-one-seo-pack' ),
662
+ 'href' => "https://www.linkedin.com/post-inspector/inspect/$url"
663
+ )
664
  );
665
 
666
  foreach ( $submenu_items as $menu_item ) {
746
 
747
  /**
748
  * Checks if new conflicting plugins were found and resets notice status.
749
+ *
750
  * @since 3.4.3
751
+ *
752
  * @param array $conflicting_plugins
753
  */
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' );
763
  } else {
764
  add_option( 'aioseop_detected_conflicting_plugins', $conflicting_plugins );
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' );
818
 
819
  sprintf(
820
  __(
821
+ '<strong>Warning</strong>: %s has detected other active SEO or sitemap plugins. We recommend that you deactivate the following plugins to prevent any conflicts:',
 
822
  'all-in-one-seo-pack'
823
  ),
824
  AIOSEOP_PLUGIN_NAME
inc/admin/views/class-aioseop-about.php CHANGED
@@ -610,7 +610,7 @@ class AIOSEOP_About {
610
  'pro' => array(
611
  'status' => 'full',
612
  'text' => array(
613
- '<strong>' . esc_html__( 'Submit Your Latest News Stories to Google News (Business & Agency tier only)', 'all-in-one-seo-pack' ) . '</strong>',
614
  ),
615
  ),
616
  ),
@@ -624,7 +624,7 @@ class AIOSEOP_About {
624
  'pro' => array(
625
  'status' => 'full',
626
  'text' => array(
627
- '<strong>' . esc_html__( 'Control The Title & Alt Tag Attribute of Your Images', 'all-in-one-seo-pack' ) . '</strong>',
628
  ),
629
  ),
630
  ),
@@ -654,7 +654,16 @@ class AIOSEOP_About {
654
  'status' => 'full',
655
  'text' => array(
656
  '<strong>' . esc_html__( 'Complete Support', 'all-in-one-seo-pack' ) . '</strong>',
657
- esc_html__( 'Posts, Pages, Categories, Tags + Breadcrumb Navigation', 'all-in-one-seo-pack' ),
 
 
 
 
 
 
 
 
 
658
  ),
659
  ),
660
  ),
610
  'pro' => array(
611
  'status' => 'full',
612
  'text' => array(
613
+ '<strong>' . esc_html__( 'Submit Your Latest News Stories to Google News (Business & Agency plans only)', 'all-in-one-seo-pack' ) . '</strong>',
614
  ),
615
  ),
616
  ),
624
  'pro' => array(
625
  'status' => 'full',
626
  'text' => array(
627
+ '<strong>' . esc_html__( 'Control The Title & Alt Tag Attribute of Your Images (Business & Agency plans only)', 'all-in-one-seo-pack' ) . '</strong>',
628
  ),
629
  ),
630
  ),
654
  'status' => 'full',
655
  'text' => array(
656
  '<strong>' . esc_html__( 'Complete Support', 'all-in-one-seo-pack' ) . '</strong>',
657
+ sprintf(
658
+ '<ul><li>%1$s</li><li>%2$s</li><li>%3$s</li></ul>',
659
+ esc_html__( 'Posts, Pages, Categories, Tags', 'all-in-one-seo-pack' ),
660
+ esc_html__( 'Breadcrumb Navigation', 'all-in-one-seo-pack' ),
661
+ sprintf(
662
+ '%1$s <strong>%2$s</strong>',
663
+ esc_html__( 'Local Business schema', 'all-in-one-seo-pack' ),
664
+ esc_html__( '(Business & Agency plans only)', 'all-in-one-seo-pack' )
665
+ )
666
+ ),
667
  ),
668
  ),
669
  ),
inc/aioseop_updates_class.php CHANGED
@@ -66,9 +66,8 @@ class AIOSEOP_Updates {
66
  set_transient( '_aioseop_activation_redirect', true, 30 ); // Sets 30 second transient for welcome screen redirect on activation.
67
  }
68
  delete_transient( 'aioseop_feed' );
69
- // add_action( 'admin_init', array( $this, 'aioseop_welcome' ) ); //Uncomment for welcome screen.
70
-
71
  }
 
72
 
73
  /**
74
  * Perform updates that are dependent on external factors, not
@@ -77,13 +76,23 @@ class AIOSEOP_Updates {
77
  $this->do_feature_updates();
78
  }
79
 
80
- function aioseop_welcome() {
81
- if ( get_transient( '_aioseop_activation_redirect' ) ) {
82
- delete_transient( '_aioseop_activation_redirect' );
83
- $aioseop_welcome = new aioseop_welcome();
84
- $aioseop_welcome->init( true );
 
 
 
 
 
 
 
 
 
85
  }
86
-
 
87
  }
88
 
89
  /**
66
  set_transient( '_aioseop_activation_redirect', true, 30 ); // Sets 30 second transient for welcome screen redirect on activation.
67
  }
68
  delete_transient( 'aioseop_feed' );
 
 
69
  }
70
+ add_action( 'current_screen', array( $this, 'showWelcomePage' ) );
71
 
72
  /**
73
  * Perform updates that are dependent on external factors, not
76
  $this->do_feature_updates();
77
  }
78
 
79
+ /**
80
+ * Shows the Welcome page if the transient exists.
81
+ *
82
+ * @since 3.6.0
83
+ *
84
+ * @return void
85
+ */
86
+ function showWelcomePage() {
87
+ if (
88
+ ! get_transient( '_aioseop_activation_redirect' ) ||
89
+ wp_doing_ajax() ||
90
+ ! in_array( get_current_screen()->id, aioseop_get_admin_screens(), true )
91
+ ) {
92
+ return;
93
  }
94
+ $aioseop_welcome = new AIOSEOP_Welcome();
95
+ $aioseop_welcome->showPage();
96
  }
97
 
98
  /**
inc/general/aioseop-robots-meta.php CHANGED
@@ -52,6 +52,10 @@ class AIOSEOP_Robots_Meta {
52
  return '';
53
  }
54
 
 
 
 
 
55
  if ( is_front_page() && 0 === $page_number ) {
56
  return $this->get_robots_meta_tag_helper( false, false );
57
  }
@@ -163,6 +167,40 @@ class AIOSEOP_Robots_Meta {
163
  return $meta_value;
164
  }
165
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
166
  /**
167
  * The is_static_page() function.
168
  *
52
  return '';
53
  }
54
 
55
+ if ( $this->isNoindexedWooCommercePage() ) {
56
+ return '';
57
+ }
58
+
59
  if ( is_front_page() && 0 === $page_number ) {
60
  return $this->get_robots_meta_tag_helper( false, false );
61
  }
167
  return $meta_value;
168
  }
169
 
170
+ /**
171
+ * Checks whether the current page is a noindexed WooCommerce page.
172
+ *
173
+ * WooCommerce noindexes the Cart, Checkout and My Account pages by default. In this case we don't need to output another robots meta tag.
174
+ *
175
+ * @since 3.6.0
176
+ *
177
+ * @return boolean Whether or not the current page is an noindexed WooCommerce page.
178
+ */
179
+ private function isNoindexedWooCommercePage() {
180
+ if (
181
+ ! aioseop_is_woocommerce_active() ||
182
+ ! is_singular() ||
183
+ 'page' !== get_post_type() ||
184
+ ! has_action( 'wp_head', 'wc_page_noindex' )
185
+ ) {
186
+ return false;
187
+ }
188
+
189
+ $pages = array(
190
+ wc_get_cart_url(),
191
+ wc_get_checkout_url(),
192
+ wc_get_page_permalink( 'myaccount' )
193
+ );
194
+
195
+ $url = get_permalink();
196
+ foreach ( $pages as $page ) {
197
+ if ( $url === $page ) {
198
+ return true;
199
+ }
200
+ }
201
+ return false;
202
+ }
203
+
204
  /**
205
  * The is_static_page() function.
206
  *
inc/schema/aioseop-context.php CHANGED
@@ -115,15 +115,17 @@ class AIOSEOP_Context {
115
  }
116
 
117
  /**
118
- * Logs Error when WP_DEBUG(_LOG) is Enabled.
119
  *
120
  * @since 3.5.2
 
 
121
  */
122
- public function log_error() {
123
  global $aioseop_options;
124
  if ( 'on' === $aioseop_options['aiosp_do_log'] ) {
125
  $e = new Exception;
126
- error_log( $e->getTraceAsString() );
127
  }
128
  }
129
 
@@ -579,42 +581,52 @@ class AIOSEOP_Context {
579
  */
580
  public function get_display_name() {
581
  $display_name = '';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
582
  switch ( $this->context_type ) {
583
  case 'var_site':
584
  $display_name = get_bloginfo( 'name' );
585
  break;
586
 
587
  case 'WP_Site':
588
- $wp_obj = self::get_object( $this->context_type, $this->context_key );
589
  $display_name = $wp_obj->blogname;
590
  break;
591
 
592
  case 'WP_Post':
593
- $wp_obj = self::get_object( $this->context_type, $this->context_key );
594
- if ( ! $wp_obj ) {
595
- $this->log_error();
596
- return $display_name;
597
- }
598
  $display_name = $wp_obj->post_title;
599
  break;
600
 
601
  case 'WP_Post_Type':
602
- $wp_obj = self::get_object( $this->context_type, $this->context_key );
603
  $display_name = $wp_obj->label;
604
  break;
605
 
606
  case 'WP_Taxonomy':
607
- $wp_obj = self::get_object( $this->context_type, $this->context_key );
608
  $display_name = $wp_obj->label;
609
  break;
610
 
611
  case 'WP_Term':
612
- $wp_obj = self::get_object( $this->context_type, $this->context_key, $this->wp_props );
613
  $display_name = $wp_obj->name;
614
  break;
615
 
616
  case 'WP_User':
617
- $wp_obj = self::get_object( $this->context_type, $this->context_key, $this->wp_props );
618
  $display_name = $wp_obj->display_name;
619
  break;
620
 
@@ -661,6 +673,22 @@ class AIOSEOP_Context {
661
  }
662
 
663
  $url = '';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
664
  switch ( $this->context_type ) {
665
  case 'var_site':
666
  $url = home_url();
@@ -671,13 +699,6 @@ class AIOSEOP_Context {
671
  break;
672
 
673
  case 'WP_Post':
674
- $wp_obj = self::get_object( $this->context_type, $this->context_key );
675
- if ( ! $wp_obj ) {
676
- $s_url[ $this->context_type ][ $this->context_key ] = $url;
677
- $this->log_error();
678
- return $url;
679
- }
680
-
681
  if ( 'attachment' === $wp_obj->post_type ) {
682
  // Source URL.
683
  // May need to check setting for attachment redirect.
@@ -705,7 +726,6 @@ class AIOSEOP_Context {
705
  break;
706
 
707
  case 'WP_Term':
708
- $wp_obj = self::get_object( $this->context_type, $this->context_key );
709
  $taxonomy = isset( $this->wp_props['taxonomy'] ) ? $this->wp_props['taxonomy'] : '';
710
  $url = get_term_link( $wp_obj, $taxonomy );
711
 
@@ -750,6 +770,23 @@ class AIOSEOP_Context {
750
  $desc = '';
751
  global $aioseop_options;
752
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
753
  switch ( $this->context_type ) {
754
  case 'var_site':
755
  if ( ! empty( $aioseop_options['aiosp_home_description'] ) ) {
@@ -941,7 +978,9 @@ class AIOSEOP_Context {
941
  );
942
 
943
  $object = self::get_object( $context->context_type, $object->parent, $context->wp_props );
944
- $context = self::get_instance( $context );
 
 
945
  } while ( $object );
946
  break;
947
 
115
  }
116
 
117
  /**
118
+ * Logs Error when General Settings > 'Log important events' is Enabled.
119
  *
120
  * @since 3.5.2
121
+ *
122
+ * @param string $message Message to prepend at the beginning of a Stack Trace.
123
  */
124
+ public function log_error( $message = 'An error has occurred.' ) {
125
  global $aioseop_options;
126
  if ( 'on' === $aioseop_options['aiosp_do_log'] ) {
127
  $e = new Exception;
128
+ error_log( $message . "\n" . $e->getTraceAsString() );
129
  }
130
  }
131
 
581
  */
582
  public function get_display_name() {
583
  $display_name = '';
584
+
585
+ // Set object, and validate WP types.
586
+ $wp_obj = false;
587
+ $wp_object_types = array(
588
+ 'WP_Site',
589
+ 'WP_Post',
590
+ 'WP_Post_Type',
591
+ 'WP_Taxonomy',
592
+ 'WP_Term',
593
+ 'WP_User',
594
+ );
595
+ if ( in_array( $this->context_type, $wp_object_types ) ) {
596
+ // Get object, and check if it exists (false value if it does not).
597
+ $wp_obj = self::get_object( $this->context_type, $this->context_key, $this->wp_props );
598
+ if ( ! $wp_obj ) {
599
+ $this->log_error( "AIOSEOP_Context: Object '" . $this->context_type . "' Key '" . $this->context_key . "' doesn't exist." );
600
+ return $display_name;
601
+ }
602
+ }
603
+
604
  switch ( $this->context_type ) {
605
  case 'var_site':
606
  $display_name = get_bloginfo( 'name' );
607
  break;
608
 
609
  case 'WP_Site':
 
610
  $display_name = $wp_obj->blogname;
611
  break;
612
 
613
  case 'WP_Post':
 
 
 
 
 
614
  $display_name = $wp_obj->post_title;
615
  break;
616
 
617
  case 'WP_Post_Type':
 
618
  $display_name = $wp_obj->label;
619
  break;
620
 
621
  case 'WP_Taxonomy':
 
622
  $display_name = $wp_obj->label;
623
  break;
624
 
625
  case 'WP_Term':
 
626
  $display_name = $wp_obj->name;
627
  break;
628
 
629
  case 'WP_User':
 
630
  $display_name = $wp_obj->display_name;
631
  break;
632
 
673
  }
674
 
675
  $url = '';
676
+
677
+ // Set object, and validate WP types.
678
+ $wp_obj = false;
679
+ $wp_object_types = array(
680
+ 'WP_Post',
681
+ 'WP_Term',
682
+ );
683
+ if ( in_array( $this->context_type, $wp_object_types ) ) {
684
+ // Get object, and check if it exists (false value if it does not).
685
+ $wp_obj = self::get_object( $this->context_type, $this->context_key, $this->wp_props );
686
+ if ( ! $wp_obj ) {
687
+ $this->log_error( "AIOSEOP_Context: Object '" . $this->context_type . "' Key '" . $this->context_key . "' doesn't exist." );
688
+ return $url;
689
+ }
690
+ }
691
+
692
  switch ( $this->context_type ) {
693
  case 'var_site':
694
  $url = home_url();
699
  break;
700
 
701
  case 'WP_Post':
 
 
 
 
 
 
 
702
  if ( 'attachment' === $wp_obj->post_type ) {
703
  // Source URL.
704
  // May need to check setting for attachment redirect.
726
  break;
727
 
728
  case 'WP_Term':
 
729
  $taxonomy = isset( $this->wp_props['taxonomy'] ) ? $this->wp_props['taxonomy'] : '';
730
  $url = get_term_link( $wp_obj, $taxonomy );
731
 
770
  $desc = '';
771
  global $aioseop_options;
772
 
773
+ // Set object, and validate WP types.
774
+ $wp_obj = false;
775
+ $wp_object_types = array(
776
+ 'WP_Post',
777
+ 'WP_Post_Type',
778
+ 'WP_Taxonomy',
779
+ 'WP_Term',
780
+ );
781
+ if ( in_array( $this->context_type, $wp_object_types ) ) {
782
+ // Get object, and check if it exists (false value if it does not).
783
+ $wp_obj = self::get_object( $this->context_type, $this->context_key, $this->wp_props );
784
+ if ( ! $wp_obj ) {
785
+ $this->log_error( "AIOSEOP_Context: Object '" . $this->context_type . "' Key '" . $this->context_key . "' doesn't exist." );
786
+ return $desc;
787
+ }
788
+ }
789
+
790
  switch ( $this->context_type ) {
791
  case 'var_site':
792
  if ( ! empty( $aioseop_options['aiosp_home_description'] ) ) {
978
  );
979
 
980
  $object = self::get_object( $context->context_type, $object->parent, $context->wp_props );
981
+ if ( $object ) {
982
+ $context->context_key = $object->term_id;
983
+ }
984
  } while ( $object );
985
  break;
986
 
inc/schema/graphs/graph-organization.php CHANGED
@@ -134,9 +134,20 @@ class AIOSEOP_Graph_Organization extends AIOSEOP_Graph {
134
  * @return array
135
  */
136
  protected function prepare_logo() {
137
- $rtn_data = array();
 
 
 
 
 
 
 
 
 
 
138
 
139
- $logo_id = $this->get_logo_id();
 
140
  if ( ! empty( $logo_id ) ) {
141
  $rtn_data = array(
142
  '@type' => 'ImageObject',
134
  * @return array
135
  */
136
  protected function prepare_logo() {
137
+ global $aioseop_options;
138
+
139
+ $homeUrl = home_url();
140
+ $logoUrl = isset( $aioseop_options['aiosp_schema_organization_logo'] ) ? $aioseop_options['aiosp_schema_organization_logo'] : '';
141
+ if ( $logoUrl && ! preg_match( "#$homeUrl.*#", $logoUrl ) ) {
142
+ return array(
143
+ '@type' => 'ImageObject',
144
+ '@id' => home_url() . '/#logo',
145
+ 'url' => $aioseop_options['aiosp_schema_organization_logo'],
146
+ );
147
+ }
148
 
149
+ $rtn_data = array();
150
+ $logo_id = $this->get_logo_id();
151
  if ( ! empty( $logo_id ) ) {
152
  $rtn_data = array(
153
  '@type' => 'ImageObject',
js/admin-notice.js CHANGED
@@ -99,12 +99,74 @@
99
  });
100
  }
101
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  /**
103
  * INITIALIZE NOTICE JS
104
  *
105
  * Constructs the actions the user may perform.
106
  */
107
- var noticeDelays = aioseop_notice_data.notice_actions;
 
108
 
109
  $.each( noticeDelays, function ( k1NoticeSlug, v1DelayArr ) {
110
  $.each( v1DelayArr, function ( k2I, v2DelayIndex ) {
@@ -114,5 +176,10 @@
114
  // Default WP action for Dismiss Button on Upper-Right.
115
  aioseop_notice_delay_wp_default_dismiss_ajax_action( k1NoticeSlug );
116
  });
 
 
 
 
 
117
  }(jQuery));
118
  // phpcs:enable
99
  });
100
  }
101
 
102
+ function aioseop_remote_notice_button_dismiss( noticeId ) {
103
+ let noticeNonce = aioseop_notice_data.notice_nonce;
104
+ $( `.aioseop-remote-notice-${noticeId} .aioseo-action-buttons a` ).on( "click", function( event ) {
105
+
106
+ let doNotDismiss = $( this ).attr( "data-dismiss" );
107
+ let href = $( this ).attr( "href" );
108
+
109
+ if (
110
+ ( 'undefined' !== typeof doNotDismiss && "false" === doNotDismiss ) &&
111
+ "#dismiss" !== href
112
+ ) {
113
+ return;
114
+ }
115
+
116
+ let formData = new FormData();
117
+ formData.append( "remote_notice_id", noticeId );
118
+
119
+ formData.append( "action", "aioseop_remote_notice" );
120
+ formData.append( "_ajax_nonce", noticeNonce );
121
+ $.ajax({
122
+ url: ajaxurl,
123
+ type: "POST",
124
+ data: formData,
125
+ cache: false,
126
+ dataType: "json",
127
+ processData: false,
128
+ contentType: false,
129
+
130
+ success: function( data, textStatus, jqXHR ){
131
+ var noticeContainer = ".aioseop-remote-notice-" + noticeId;
132
+ $( noticeContainer ).remove();
133
+ }
134
+ });
135
+ });
136
+ }
137
+
138
+ function aioseop_remote_notice_wp_default_dismiss( noticeID ) {
139
+ let noticeNonce = aioseop_notice_data.notice_nonce;
140
+ let noticeContainer = ".aioseop-remote-notice-" + noticeID;
141
+ $( noticeContainer ).on( "click", "button.notice-dismiss ", function( event ) {
142
+ // Prevents any unwanted actions.
143
+ event.stopPropagation();
144
+ event.preventDefault();
145
+
146
+ let formData = new FormData();
147
+ formData.append( "remote_notice_id", noticeID );
148
+
149
+ formData.append( "action", "aioseop_remote_notice" );
150
+ formData.append( "_ajax_nonce", noticeNonce );
151
+ $.ajax({
152
+ url: ajaxurl,
153
+ type: "POST",
154
+ data: formData,
155
+ cache: false,
156
+ dataType: "json",
157
+ processData: false,
158
+ contentType: false
159
+ });
160
+ });
161
+ }
162
+
163
  /**
164
  * INITIALIZE NOTICE JS
165
  *
166
  * Constructs the actions the user may perform.
167
  */
168
+ let noticeDelays = aioseop_notice_data.notice_actions;
169
+ let remoteNotices = aioseop_notice_data.remote_notices;
170
 
171
  $.each( noticeDelays, function ( k1NoticeSlug, v1DelayArr ) {
172
  $.each( v1DelayArr, function ( k2I, v2DelayIndex ) {
176
  // Default WP action for Dismiss Button on Upper-Right.
177
  aioseop_notice_delay_wp_default_dismiss_ajax_action( k1NoticeSlug );
178
  });
179
+
180
+ $.each( remoteNotices, function( index, noticeId ) {
181
+ aioseop_remote_notice_button_dismiss( noticeId );
182
+ aioseop_remote_notice_wp_default_dismiss( noticeId );
183
+ });
184
  }(jQuery));
185
  // phpcs:enable
js/admin/aioseop-preview-snippet.js CHANGED
@@ -139,7 +139,11 @@ jQuery(function($){
139
  * @param string postContent
140
  * @return string description
141
  */
142
- function aioseopGetDescription(postContent) {
 
 
 
 
143
  if( 'on' === dontShortenDescriptions ) {
144
  return aioseopStripMarkup(postContent);
145
  }
139
  * @param string postContent
140
  * @return string description
141
  */
142
+ function aioseopGetDescription(postContent) {
143
+ if('undefined' === typeof postContent) {
144
+ return postContent;
145
+ }
146
+
147
  if( 'on' === dontShortenDescriptions ) {
148
  return aioseopStripMarkup(postContent);
149
  }
js/admin/education/aioseop-news-sitemap-upsell.js CHANGED
@@ -8,12 +8,13 @@ jQuery(function($) {
8
  newsSitemapSetting: $('#aiosp_sitemap_posttypes_news_wrapper .aioseop_option_input'),
9
 
10
  init: function() {
11
- aioseopNewsSitemapUpsell.disableCheckboxes();
12
  aioseopNewsSitemapUpsell.getNewsSitemapUpsell();
13
  },
14
 
15
- disableCheckboxes: function() {
16
- $('#aiosp_sitemap_posttypes_news_wrapper .aioseop_option_input input').attr('disabled', true);
 
17
  },
18
 
19
  getNewsSitemapUpsell: function() {
8
  newsSitemapSetting: $('#aiosp_sitemap_posttypes_news_wrapper .aioseop_option_input'),
9
 
10
  init: function() {
11
+ aioseopNewsSitemapUpsell.disableSettings();
12
  aioseopNewsSitemapUpsell.getNewsSitemapUpsell();
13
  },
14
 
15
+ disableSettings: function() {
16
+ $('#aiosp_sitemap_publication_name_wrapper .aioseop_option_input input').attr('disabled', 'disabled');
17
+ $('#aiosp_sitemap_posttypes_news_wrapper .aioseop_option_input input').attr('disabled', 'disabled');
18
  },
19
 
20
  getNewsSitemapUpsell: function() {
js/welcome.js DELETED
@@ -1,32 +0,0 @@
1
- (function($) {
2
-
3
- $( document ).on(
4
- 'click', '.nav-tab-wrapper a', function() {
5
- $( 'section' ).hide();
6
- $( 'section' ).eq( $( this ).index() ).show();
7
-
8
- // alert($('section'));
9
- if ($( this ).attr( 'className' ) === 'nav-tab-active') {
10
- // $(this).removeClass('nav-tab-active');
11
- // $(this).addClass('nav-tab-active');
12
- } else {
13
- // $(this).addClass('nav-tab-active');
14
- // $(this).removeClass('nav-tab-active');
15
- }
16
- // $(this).addClass('nav-tab-active');
17
- // $(this).eq($(this).index()).removeClass('nav-tab-active');
18
- // $(this).removeClass('nav-tab-active');
19
- return false;
20
- }
21
- );
22
-
23
- $( "a.nav-tab" ).click(
24
- function() {
25
-
26
- $( "a.nav-tab" ).removeClass( 'nav-tab-active' );
27
- $( this ).addClass( 'nav-tab-active' );
28
-
29
- }
30
- );
31
-
32
- }( jQuery ));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
modules/aioseop_feature_manager.php CHANGED
@@ -91,9 +91,21 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Feature_Manager' ) ) {
91
  'is_pro_feature' => true,
92
  'can_activate' => AIOSEOPPRO,
93
  ),
 
 
 
 
 
 
 
 
 
94
  'image_seo' => array(
95
  'name' => __( 'Image SEO', 'all-in-one-seo-pack' ),
96
- 'description' => __( 'Manage the SEO for your images by controlling their title & alt tag attributes.', 'all-in-one-seo-pack' ),
 
 
 
97
  'is_pro_feature' => true,
98
  'can_activate' => false,
99
  ),
@@ -116,10 +128,10 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Feature_Manager' ) ) {
116
  }
117
 
118
  // Set up default settings fields.
119
- // Name - Human-readable name of the setting.
120
- // Help_text - Inline documentation for the setting.
121
- // Type - Type of field; this defaults to checkbox; currently supported types are checkbox, text, select, multiselect.
122
- // Default - Default value of the field.
123
  // Initial_options - Initial option list used for selects and multiselects.
124
  // Other supported options: class, id, style -- allows you to set these HTML attributes on the field.
125
  $this->default_options = array();
91
  'is_pro_feature' => true,
92
  'can_activate' => AIOSEOPPRO,
93
  ),
94
+ 'schema_local_business' => array(
95
+ 'name' => __( 'Local Business SEO', 'all-in-one-seo-pack' ),
96
+ 'description' => sprintf(
97
+ __( 'Tell Google more about your business and increase your click-through rate using Local Business structured data %s.', 'all-in-one-seo-pack' ),
98
+ sprintf( '<strong>%s</strong>', __( '(Business & Agency plans only)', 'all-in-one-seo-pack' ) )
99
+ ),
100
+ 'is_pro_feature' => true,
101
+ 'can_activate' => false,
102
+ ),
103
  'image_seo' => array(
104
  'name' => __( 'Image SEO', 'all-in-one-seo-pack' ),
105
+ 'description' => sprintf(
106
+ __( 'Manage the SEO for your images by controlling their title & alt tag attributes %s.', 'all-in-one-seo-pack' ),
107
+ sprintf( '<strong>%s</strong>', __( '(Business & Agency plans only)', 'all-in-one-seo-pack' ) )
108
+ ),
109
  'is_pro_feature' => true,
110
  'can_activate' => false,
111
  ),
128
  }
129
 
130
  // Set up default settings fields.
131
+ // Name - Human-readable name of the setting.
132
+ // Help_text - Inline documentation for the setting.
133
+ // Type - Type of field; this defaults to checkbox; currently supported types are checkbox, text, select, multiselect.
134
+ // Default - Default value of the field.
135
  // Initial_options - Initial option list used for selects and multiselects.
136
  // Other supported options: class, id, style -- allows you to set these HTML attributes on the field.
137
  $this->default_options = array();
modules/aioseop_schema_local_business.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Loads the Local Business schema class.
4
+ *
5
+ * @since 3.6.0
6
+ */
7
+
8
+ if ( AIOSEOPPRO ) {
9
+ require_once( AIOSEOP_PLUGIN_DIR . 'pro/modules/class-aioseop-schema-local-business.php' );
10
+ }
modules/aioseop_sitemap.php CHANGED
@@ -302,13 +302,17 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
302
  * @param bool Whether or not the Google News sitemap should be output. Defaults to true.
303
  */
304
  if ( apply_filters( 'aioseo_news_sitemap_enabled', true ) ) {
305
- $news_sitemap = array(
 
 
 
 
 
 
306
  'name' => __( 'Google News Sitemap Post Types', 'all-in-one-seo-pack' ),
307
  'type' => 'multicheckbox',
308
  'default' => array( 'post' ),
309
  );
310
-
311
- $addl_sitemap_options['posttypes_news'] = $news_sitemap;
312
  }
313
 
314
  $addl_pages_options = array(
@@ -419,6 +423,10 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
419
  add_filter( $this->prefix . 'output_option', array( $this, 'display_custom_options' ), 10, 2 );
420
  add_action( $this->prefix . 'daily_update_cron', array( $this, 'daily_update' ) );
421
  add_action( 'init', array( $this, 'make_dynamic_xsl' ) );
 
 
 
 
422
 
423
  // TODO is this required for dynamic sitemap?
424
  add_action( 'transition_post_status', array( $this, 'update_sitemap_from_posts' ), 10, 3 );
@@ -2537,6 +2545,10 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
2537
  $urls = $this->get_homepage_timestamp( $urls );
2538
  $urls = $this->get_posts_page_timestamp( $urls );
2539
 
 
 
 
 
2540
  return $urls;
2541
  }
2542
 
@@ -4063,6 +4075,7 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
4063
  foreach ( $post_image_urls as $k1_index => $v1_image_url ) {
4064
  $v1_image_url = aiosp_common::absolutize_url( $v1_image_url );
4065
  $post_image_urls[ $k1_index ] = $v1_image_url;
 
4066
  $attachment_id = aiosp_common::attachment_url_to_postid( $v1_image_url );
4067
 
4068
  if ( $attachment_id ) {
@@ -4135,6 +4148,23 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
4135
  return $rtn_image_attributes;
4136
  }
4137
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4138
  /**
4139
  * Set Transient Attachment IDs => URLS
4140
  *
@@ -4633,9 +4663,49 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
4633
  $links = $this->update_woocommerce_shop_timestamp( $links );
4634
  }
4635
 
 
 
 
 
4636
  return $links;
4637
  }
4638
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4639
  /**
4640
  * The get_prio_freq_static_homepage() function.
4641
  *
302
  * @param bool Whether or not the Google News sitemap should be output. Defaults to true.
303
  */
304
  if ( apply_filters( 'aioseo_news_sitemap_enabled', true ) ) {
305
+ $addl_sitemap_options['publication_name'] = array(
306
+ 'name' => __( 'Google News Publication Name', 'all-in-one-seo-pack' ),
307
+ 'type' => 'text',
308
+ 'default' => get_bloginfo( 'name' ) ? get_bloginfo( 'name' ) : "",
309
+ );
310
+
311
+ $addl_sitemap_options['posttypes_news'] = array(
312
  'name' => __( 'Google News Sitemap Post Types', 'all-in-one-seo-pack' ),
313
  'type' => 'multicheckbox',
314
  'default' => array( 'post' ),
315
  );
 
 
316
  }
317
 
318
  $addl_pages_options = array(
423
  add_filter( $this->prefix . 'output_option', array( $this, 'display_custom_options' ), 10, 2 );
424
  add_action( $this->prefix . 'daily_update_cron', array( $this, 'daily_update' ) );
425
  add_action( 'init', array( $this, 'make_dynamic_xsl' ) );
426
+
427
+ // Disable Core Sitemaps functionality.
428
+ remove_action( 'init', 'wp_sitemaps_get_server' );
429
+ add_filter( 'wp_sitemaps_enabled', '__return_false' );
430
 
431
  // TODO is this required for dynamic sitemap?
432
  add_action( 'transition_post_status', array( $this, 'update_sitemap_from_posts' ), 10, 3 );
2545
  $urls = $this->get_homepage_timestamp( $urls );
2546
  $urls = $this->get_posts_page_timestamp( $urls );
2547
 
2548
+ if ( in_array( 'page', $options[ "{$this->prefix}posttypes" ], true ) ) {
2549
+ $urls = $this->removeWooCommercePages( $urls );
2550
+ }
2551
+
2552
  return $urls;
2553
  }
2554
 
4075
  foreach ( $post_image_urls as $k1_index => $v1_image_url ) {
4076
  $v1_image_url = aiosp_common::absolutize_url( $v1_image_url );
4077
  $post_image_urls[ $k1_index ] = $v1_image_url;
4078
+ $v1_image_url = $this->prepare_url( $v1_image_url );
4079
  $attachment_id = aiosp_common::attachment_url_to_postid( $v1_image_url );
4080
 
4081
  if ( $attachment_id ) {
4148
  return $rtn_image_attributes;
4149
  }
4150
 
4151
+ /**
4152
+ * Prepares a given image URL for further processing by removing the image dimensions from the slug.
4153
+ *
4154
+ * @since 3.6.0
4155
+ *
4156
+ * @param string $url The image URL.
4157
+ * @return string The prepared image URL.
4158
+ */
4159
+ private function prepare_url( $url ) {
4160
+ $upload_dir = wp_get_upload_dir();
4161
+ $upload_dir_url = $upload_dir['baseurl'];
4162
+ if ( ! preg_match( "#$upload_dir_url.*#", $url ) ) {
4163
+ return $url;
4164
+ }
4165
+ return preg_replace( '#(-[0-9]*x[0-9]*)#', '', $url );
4166
+ }
4167
+
4168
  /**
4169
  * Set Transient Attachment IDs => URLS
4170
  *
4663
  $links = $this->update_woocommerce_shop_timestamp( $links );
4664
  }
4665
 
4666
+ if ( 'page' === $include ) {
4667
+ $links = $this->removeWooCommercePages( $links );
4668
+ }
4669
+
4670
  return $links;
4671
  }
4672
 
4673
+ /**
4674
+ * Excludes the Cart, Checkout and My Account pages from the sitemap if WooCommerce noindex them.
4675
+ *
4676
+ * @since 3.6.0
4677
+ *
4678
+ * @param array $urls The URLs.
4679
+ * @return array $remainingUrls The filtered URLs.
4680
+ */
4681
+ private function removeWooCommercePages( $urls ) {
4682
+ // Check if WooCommerce is noindexing its own pages.
4683
+ if ( ! aioseop_is_woocommerce_active() || ! has_action( 'wp_head', 'wc_page_noindex' ) ) {
4684
+ return $urls;
4685
+ }
4686
+
4687
+ $pages = array(
4688
+ wc_get_cart_url(),
4689
+ wc_get_checkout_url(),
4690
+ wc_get_page_permalink( 'myaccount' )
4691
+ );
4692
+
4693
+ $remainingUrls = array();
4694
+ foreach ( $urls as $url ) {
4695
+ $isNoindexed = false;
4696
+ foreach( $pages as $page ) {
4697
+ if ( $page === $url['loc'] ) {
4698
+ $isNoindexed = true;
4699
+ break;
4700
+ }
4701
+ }
4702
+ if ( ! $isNoindexed ) {
4703
+ $remainingUrls[] = $url;
4704
+ }
4705
+ }
4706
+ return $remainingUrls;
4707
+ }
4708
+
4709
  /**
4710
  * The get_prio_freq_static_homepage() function.
4711
  *
public/google-analytics.php CHANGED
@@ -88,7 +88,7 @@ if ( ! class_exists( 'aioseop_google_analytics' ) ) {
88
  ) ) {
89
  $autotrack = apply_filters(
90
  'aiosp_google_autotrack',
91
- AIOSEOP_PLUGIN_URL . 'public/js/vendor/autotrack.js'
92
  );
93
  ?><script async src="<?php echo $autotrack; ?>"></script>
94
  <?php
88
  ) ) {
89
  $autotrack = apply_filters(
90
  'aiosp_google_autotrack',
91
+ AIOSEOP_PLUGIN_URL . 'public/js/vendor/autotrack.js?ver=' . AIOSEOP_VERSION
92
  );
93
  ?><script async src="<?php echo $autotrack; ?>"></script>
94
  <?php
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.1
6
- Stable tag: 3.5.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.4.2
6
+ Stable tag: 3.6.1
7
  License: GPLv2 or later
8
  Requires PHP: 5.2.4
9