SmartCrawl SEO - Version 2.2.6

Version Description

  • New: Support for Yoast v10 and AIOSEO v2.12 in third-party importer
  • Fix: Redirects added from sitemap crawl report not converted to absolute
  • Fix: Sitemap can't be removed while SC is active
  • Fix: Import not working for Automatic linking settings
  • Fix: Metabox conflict in classic editor
Download this release

Release Info

Developer khaxan
Plugin Icon 128x128 SmartCrawl SEO
Version 2.2.6
Comparing to
See all releases

Code changes from version 2.2.4.1 to 2.2.6

autoloader.php CHANGED
@@ -1,22 +1,38 @@
1
  <?php
2
 
3
- function smartcrawl_autoload( $class ) {
4
- $mappings_file = dirname( __FILE__ ) . '/class-mappings.php';
5
- if ( ! file_exists( $mappings_file ) ) {
6
- return;
7
- }
 
 
 
8
 
9
- $class_mappings = include $mappings_file;
10
- if ( ! isset( $class_mappings[ $class ] ) ) {
11
- return;
12
  }
13
 
14
- $class_path = untrailingslashit( SMARTCRAWL_PLUGIN_DIR ) . $class_mappings[ $class ];
15
- if ( ! file_exists( $class_path ) ) {
16
- return;
 
 
 
17
  }
18
 
19
- include $class_path;
 
 
 
 
 
 
 
 
 
 
 
 
20
  }
21
 
22
- spl_autoload_register( 'smartcrawl_autoload' );
1
  <?php
2
 
3
+ class Smartcrawl_Autoloader {
4
+ private static $class_mappings = array();
5
+
6
+ private static function load_from_file() {
7
+ $mappings_file = dirname( __FILE__ ) . '/class-mappings.php';
8
+ if ( file_exists( $mappings_file ) ) {
9
+ return include $mappings_file;
10
+ }
11
 
12
+ return array();
 
 
13
  }
14
 
15
+ private static function get_class_mappings() {
16
+ if ( empty( self::$class_mappings ) ) {
17
+ self::$class_mappings = self::load_from_file();
18
+ }
19
+
20
+ return self::$class_mappings;
21
  }
22
 
23
+ public static function autoload( $class ) {
24
+ $class_mappings = self::get_class_mappings();
25
+ if ( ! isset( $class_mappings[ $class ] ) ) {
26
+ return;
27
+ }
28
+
29
+ $class_path = untrailingslashit( SMARTCRAWL_PLUGIN_DIR ) . $class_mappings[ $class ];
30
+ if ( ! file_exists( $class_path ) ) {
31
+ return;
32
+ }
33
+
34
+ include $class_path;
35
+ }
36
  }
37
 
38
+ spl_autoload_register( array( 'Smartcrawl_Autoloader', 'autoload' ) );
changelog.txt CHANGED
@@ -2,6 +2,32 @@ Plugin Name: SmartCrawl SEO
2
 
3
  Change Log:
4
  ----------------------------------------------------------------------
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  2.2.4.1 - 2018-12-11
6
  ----------------------------------------------------------------------
7
  - Fix: Show the WP.org rating request to admins only
2
 
3
  Change Log:
4
  ----------------------------------------------------------------------
5
+ 2.2.6 - 2019-03-26
6
+ ----------------------------------------------------------------------
7
+ - Add: Support for Yoast v10 and AIOSEO v2.12 in third-party importer
8
+
9
+ - Fix: Redirects added from sitemap crawl report not converted to absolute
10
+ - Fix: Sitemap can't be removed while SC is active
11
+ - Fix: Import not working for Automatic linking settings
12
+ - Fix: Metabox conflict in classic editor
13
+
14
+ 2.2.5 - 2019-02-18
15
+ ----------------------------------------------------------------------
16
+ - Add: New filters for modifying OpenGraph values
17
+ - Add: Improved accuracy of readability analysis
18
+
19
+ - Fix: Missing columns on the post list page
20
+ - Fix: Certain websites throwing 404 error on redirection
21
+ - Fix: SEO metabox shown for non-public posts
22
+ - Fix: Better Gutenberg compatibility
23
+ - Fix: Warning on sitemap settings page
24
+ - Fix: Added ability to increase analysis request timeout
25
+ - Fix: Improved autoloader performance
26
+ - Fix: Warning in metabox placeholder loader
27
+ - Fix: Inaccurate preview when more recent post revision available
28
+ - Fix: Update the AIOSEOP importer to include the latest version
29
+ - Fix: Stylesheet URL incorrect in sub-site sitemaps
30
+
31
  2.2.4.1 - 2018-12-11
32
  ----------------------------------------------------------------------
33
  - Fix: Show the WP.org rating request to admins only
config.php CHANGED
@@ -82,6 +82,9 @@ if ( ! defined( 'SMARTCRAWL_WHITELABEL_ON' ) ) {
82
  if ( ! defined( 'SMARTCRAWL_OMIT_PORT_MATCHES' ) ) {
83
  define( 'SMARTCRAWL_OMIT_PORT_MATCHES', false );
84
  }
 
 
 
85
 
86
  /**
87
  * Setup plugin path and url.
82
  if ( ! defined( 'SMARTCRAWL_OMIT_PORT_MATCHES' ) ) {
83
  define( 'SMARTCRAWL_OMIT_PORT_MATCHES', false );
84
  }
85
+ if ( ! defined( 'SMARTCRAWL_ANALYSIS_REQUEST_TIMEOUT' ) ) {
86
+ define( 'SMARTCRAWL_ANALYSIS_REQUEST_TIMEOUT', 5 );
87
+ }
88
 
89
  /**
90
  * Setup plugin path and url.
includes/admin/metabox.php CHANGED
@@ -98,10 +98,17 @@ class Smartcrawl_Metabox extends Smartcrawl_Renderable {
98
  return;
99
  }
100
 
101
- $latest_post_version = smartcrawl_get_latest_post_version( $post_id );
 
 
 
 
 
 
 
102
  $result['success'] = true;
103
  $result['markup'] = $this->_load( 'metabox/metabox-preview', array(
104
- 'post' => $latest_post_version,
105
  ) );
106
 
107
  wp_send_json( $result );
@@ -127,8 +134,8 @@ class Smartcrawl_Metabox extends Smartcrawl_Renderable {
127
  ) );
128
  Smartcrawl_Settings_Admin::register_global_admin_scripts();
129
  wp_enqueue_script( 'wds_metabox_onpage', SMARTCRAWL_PLUGIN_URL . '/js/wds-metabox.js', array(
 
130
  'wds-select2',
131
- 'autosave',
132
  ), $version );
133
  wp_localize_script( 'wds_metabox_onpage', '_wds_metabox', array(
134
  'nonce' => wp_create_nonce( 'wds-metabox-nonce' ),
@@ -160,7 +167,7 @@ class Smartcrawl_Metabox extends Smartcrawl_Renderable {
160
  /**
161
  * Handles actual metabox rendering
162
  */
163
- public function smartcrawl_meta_boxes($post) {
164
  $robots_noindex_value = (int) smartcrawl_get_value( 'meta-robots-noindex' );
165
  $robots_nofollow_value = (int) smartcrawl_get_value( 'meta-robots-nofollow' );
166
  $robots_index_value = (int) smartcrawl_get_value( 'meta-robots-index' );
@@ -206,11 +213,14 @@ class Smartcrawl_Metabox extends Smartcrawl_Renderable {
206
  if ( function_exists( 'add_meta_box' ) ) {
207
  // Show branding for singular installs.
208
  $metabox_title = is_multisite() ? __( 'SmartCrawl', 'wds' ) : 'SmartCrawl';
209
- $post_types = get_post_types(array(
210
  'show_ui' => true, // Only if it actually supports WP UI.
211
- ));
 
212
  foreach ( $post_types as $posttype ) {
213
- if ( 'attachment' === $posttype ) { continue; }
 
 
214
  if ( $show ) {
215
  add_meta_box( 'wds-wds-meta-box', $metabox_title, array(
216
  &$this,
@@ -408,10 +418,12 @@ class Smartcrawl_Metabox extends Smartcrawl_Renderable {
408
  * @return array
409
  */
410
  public function smartcrawl_page_title_column_heading( $columns ) {
 
 
411
  return array_merge(
412
- array_slice( $columns, 0, 2 ),
413
  array( 'page-title' => __( 'Title Tag', 'wds' ) ),
414
- array_slice( $columns, 2, 6 ),
415
  array( 'page-meta-robots' => __( 'Robots Meta', 'wds' ) )
416
  );
417
  }
@@ -553,29 +565,32 @@ class Smartcrawl_Metabox extends Smartcrawl_Renderable {
553
  * Handle metabox live update requests
554
  */
555
  public function smartcrawl_metabox_live_update() {
 
556
  $data = $this->get_request_data();
557
- $id = (int) $data['id'];
558
- $post = get_post( $id );
559
-
560
- $post_data = sanitize_post( $data['post'] );
561
-
562
- /* Merge live post data with currently saved post data */
563
- $post->post_author = $post_data['post_author'];
564
- $post->post_title = $post_data['post_title'];
565
- $post->post_excerpt = $post_data['excerpt'];
566
- $post->post_content = $post_data['content'];
567
- $post->post_type = $post_data['post_type'];
568
-
569
- $title = smartcrawl_get_seo_title( $post );
570
- $description = smartcrawl_get_seo_desc( $post );
571
-
572
- wp_send_json( array(
573
- 'title' => $title,
574
- 'description' => $description,
575
- 'focus' => smartcrawl_get_value( 'focus-keywords', $id ),
576
- 'keywords' => smartcrawl_get_value( 'keywords', $id ),
577
- ) );
 
578
 
 
579
  die();
580
  }
581
 
98
  return;
99
  }
100
 
101
+ $is_dirty = (boolean) smartcrawl_get_array_value( $data, 'is_dirty' );
102
+ /**
103
+ * If there is_dirty flag is set i.e. are unsaved changes in the editor then we
104
+ * will fetch the latest post revision and preview that.
105
+ */
106
+ $post_to_preview = $is_dirty
107
+ ? smartcrawl_get_latest_post_version( $post_id )
108
+ : get_post( $post_id );
109
  $result['success'] = true;
110
  $result['markup'] = $this->_load( 'metabox/metabox-preview', array(
111
+ 'post' => $post_to_preview,
112
  ) );
113
 
114
  wp_send_json( $result );
134
  ) );
135
  Smartcrawl_Settings_Admin::register_global_admin_scripts();
136
  wp_enqueue_script( 'wds_metabox_onpage', SMARTCRAWL_PLUGIN_URL . '/js/wds-metabox.js', array(
137
+ 'underscore',
138
  'wds-select2',
 
139
  ), $version );
140
  wp_localize_script( 'wds_metabox_onpage', '_wds_metabox', array(
141
  'nonce' => wp_create_nonce( 'wds-metabox-nonce' ),
167
  /**
168
  * Handles actual metabox rendering
169
  */
170
+ public function smartcrawl_meta_boxes( $post ) {
171
  $robots_noindex_value = (int) smartcrawl_get_value( 'meta-robots-noindex' );
172
  $robots_nofollow_value = (int) smartcrawl_get_value( 'meta-robots-nofollow' );
173
  $robots_index_value = (int) smartcrawl_get_value( 'meta-robots-index' );
213
  if ( function_exists( 'add_meta_box' ) ) {
214
  // Show branding for singular installs.
215
  $metabox_title = is_multisite() ? __( 'SmartCrawl', 'wds' ) : 'SmartCrawl';
216
+ $post_types = get_post_types( array(
217
  'show_ui' => true, // Only if it actually supports WP UI.
218
+ 'public' => true, // ... and is public
219
+ ) );
220
  foreach ( $post_types as $posttype ) {
221
+ if ( 'attachment' === $posttype ) {
222
+ continue;
223
+ }
224
  if ( $show ) {
225
  add_meta_box( 'wds-wds-meta-box', $metabox_title, array(
226
  &$this,
418
  * @return array
419
  */
420
  public function smartcrawl_page_title_column_heading( $columns ) {
421
+ $title_idx = array_search( 'title', array_keys( $columns ) );
422
+ $title_idx = ! empty( $title_idx ) ? $title_idx + 1 : 2;
423
  return array_merge(
424
+ array_slice( $columns, 0, $title_idx ),
425
  array( 'page-title' => __( 'Title Tag', 'wds' ) ),
426
+ array_slice( $columns, $title_idx, count( $columns ) ),
427
  array( 'page-meta-robots' => __( 'Robots Meta', 'wds' ) )
428
  );
429
  }
565
  * Handle metabox live update requests
566
  */
567
  public function smartcrawl_metabox_live_update() {
568
+ $response = array();
569
  $data = $this->get_request_data();
570
+ $id = (int) smartcrawl_get_array_value( $data, 'id' );
571
+ if ( $id ) {
572
+ $post = get_post( $id );
573
+
574
+ $post_data = sanitize_post( $data['post'] );
575
+
576
+ /* Merge live post data with currently saved post data */
577
+ $post->post_author = $post_data['post_author'];
578
+ $post->post_title = $post_data['post_title'];
579
+ $post->post_excerpt = $post_data['excerpt'];
580
+ $post->post_content = $post_data['content'];
581
+ $post->post_type = $post_data['post_type'];
582
+
583
+ $title = smartcrawl_get_seo_title( $post );
584
+ $description = smartcrawl_get_seo_desc( $post );
585
+ $response = array(
586
+ 'title' => $title,
587
+ 'description' => $description,
588
+ 'focus' => smartcrawl_get_value( 'focus-keywords', $id ),
589
+ 'keywords' => smartcrawl_get_value( 'keywords', $id ),
590
+ );
591
+ }
592
 
593
+ wp_send_json( $response );
594
  die();
595
  }
596
 
includes/admin/settings/autolinks.php CHANGED
@@ -84,15 +84,15 @@ class Smartcrawl_Autolinks_Settings extends Smartcrawl_Settings_Admin {
84
  // Boolean Arrays.
85
  $post_type_names = array_keys( self::get_post_types() );
86
  foreach ( array_merge( $post_type_names, array( 'comment' ) ) as $post_type ) {
87
- $result[ $post_type ] = in_array( $post_type, $input, true );
88
  }
89
  foreach ( $post_type_names as $post_type ) {
90
- $result["l{$post_type}"] = in_array( "l{$post_type}", $input, true );
91
  }
92
  foreach ( get_taxonomies() as $taxonomy ) {
93
  $tax = get_taxonomy( $taxonomy );
94
  $key = strtolower( $tax->labels->name );
95
- $result["l{$key}"] = in_array( "l{$key}", $input, true );
96
  }
97
 
98
  // Numerics.
84
  // Boolean Arrays.
85
  $post_type_names = array_keys( self::get_post_types() );
86
  foreach ( array_merge( $post_type_names, array( 'comment' ) ) as $post_type ) {
87
+ $result[ $post_type ] = (boolean) smartcrawl_get_array_value( $input, $post_type );
88
  }
89
  foreach ( $post_type_names as $post_type ) {
90
+ $result["l{$post_type}"] = (boolean) smartcrawl_get_array_value( $input, "l{$post_type}" );
91
  }
92
  foreach ( get_taxonomies() as $taxonomy ) {
93
  $tax = get_taxonomy( $taxonomy );
94
  $key = strtolower( $tax->labels->name );
95
+ $result["l{$key}"] = (boolean) smartcrawl_get_array_value( $input, "l{$key}" );
96
  }
97
 
98
  // Numerics.
includes/admin/settings/dashboard.php CHANGED
@@ -237,8 +237,22 @@ class Smartcrawl_Settings_Dashboard extends Smartcrawl_Settings_Admin {
237
  wp_send_json_error( $result );
238
  }
239
 
240
- $source = esc_url( $data['source'] );
241
- $redirect = esc_url( $data['redirect'] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
242
  $rmodel = new Smartcrawl_Model_Redirection();
243
 
244
  $status_code = $rmodel->get_default_redirection_status_type();
237
  wp_send_json_error( $result );
238
  }
239
 
240
+ $source = (string) smartcrawl_get_array_value( $data, 'source' );
241
+ $source = trim( esc_url( $source ) );
242
+
243
+ $redirect = (string) smartcrawl_get_array_value( $data, 'redirect' );
244
+ $redirect = trim( esc_url( $redirect ) );
245
+
246
+ if ( ! $source || ! $redirect ) {
247
+ wp_send_json_error( $result );
248
+ }
249
+ if ( ! preg_match( '/^https?:\/\//', $source ) ) {
250
+ $source = home_url( $source );
251
+ }
252
+ if ( ! preg_match( '/^https?:\/\//', $redirect ) ) {
253
+ $redirect = home_url( $redirect );
254
+ }
255
+
256
  $rmodel = new Smartcrawl_Model_Redirection();
257
 
258
  $status_code = $rmodel->get_default_redirection_status_type();
includes/admin/settings/onpage.php CHANGED
@@ -362,6 +362,9 @@ class Smartcrawl_Onpage_Settings extends Smartcrawl_Settings_Admin {
362
  $link = bp_loggedin_user_domain();
363
  $updated = true;
364
  break;
 
 
 
365
  }
366
 
367
  // Custom post type?
362
  $link = bp_loggedin_user_domain();
363
  $updated = true;
364
  break;
365
+
366
+ default:
367
+ break;
368
  }
369
 
370
  // Custom post type?
includes/admin/templates/sitemap/sitemap-settings.php CHANGED
@@ -4,6 +4,7 @@ $sitemap_tab_name = __( 'Sitemap', 'wds' );
4
  $url_crawler_tab_id = 'tab_url_crawler';
5
  $url_crawler_tab_name = __( 'URL Crawler', 'wds' );
6
  $crawl_url = Smartcrawl_Sitemap_Settings::crawl_url();
 
7
  ?>
8
 
9
  <div id="container" class="wrap wrap-wds wds-page wds-sitemap-settings">
@@ -13,7 +14,6 @@ $crawl_url = Smartcrawl_Sitemap_Settings::crawl_url();
13
  <div class="actions">
14
  <?php if ( Smartcrawl_Settings::get_setting( 'sitemap' ) ) { ?>
15
  <?php
16
- $service = Smartcrawl_Service::get( Smartcrawl_Service::SERVICE_SEO );
17
  $end = $service->get_last_run_timestamp();
18
  $end = ! empty( $end ) && is_numeric( $end )
19
  ? date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), $end )
4
  $url_crawler_tab_id = 'tab_url_crawler';
5
  $url_crawler_tab_name = __( 'URL Crawler', 'wds' );
6
  $crawl_url = Smartcrawl_Sitemap_Settings::crawl_url();
7
+ $service = Smartcrawl_Service::get( Smartcrawl_Service::SERVICE_SEO );
8
  ?>
9
 
10
  <div id="container" class="wrap wrap-wds wds-page wds-sitemap-settings">
14
  <div class="actions">
15
  <?php if ( Smartcrawl_Settings::get_setting( 'sitemap' ) ) { ?>
16
  <?php
 
17
  $end = $service->get_last_run_timestamp();
18
  $end = ! empty( $end ) && is_numeric( $end )
19
  ? date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), $end )
includes/admin/templates/url-crawl-master.php CHANGED
@@ -74,4 +74,7 @@ switch ( $crawl_status ) {
74
  ) );
75
  }
76
  break;
 
 
 
77
  }
74
  ) );
75
  }
76
  break;
77
+
78
+ default:
79
+ break;
80
  }
includes/core/checks/class-wds-check-slug-keywords.php CHANGED
@@ -12,7 +12,7 @@ class Smartcrawl_Check_Slug_Keywords extends Smartcrawl_Check_Post_Abstract {
12
 
13
  public function apply() {
14
  $text = $this->get_markup();
15
- $subject = join( ' ', preg_split( '/[-_]/', $text ) );
16
 
17
  $this->_state = $this->has_focus( $subject );
18
 
12
 
13
  public function apply() {
14
  $text = $this->get_markup();
15
+ $subject = join( ' ', preg_split( '/[\-_]/', $text ) );
16
 
17
  $this->_state = $this->has_focus( $subject );
18
 
includes/core/class-wds-aioseop-importer.php CHANGED
@@ -13,6 +13,7 @@ class Smartcrawl_AIOSEOP_Importer extends Smartcrawl_Importer {
13
  'aioseop_options/modules/aiosp_opengraph_options/aiosp_opengraph_hometitle' => 'home_og_fields_enabled',
14
  'aioseop_options/modules/aiosp_opengraph_options/aiosp_opengraph_description' => 'home_og_fields_enabled',
15
  );
 
16
  // phpcs:enable
17
 
18
  public function data_exists() {
@@ -23,7 +24,10 @@ class Smartcrawl_AIOSEOP_Importer extends Smartcrawl_Importer {
23
  return false;
24
  }
25
 
26
- return strpos( $version, '2.9' ) === 0;
 
 
 
27
  }
28
 
29
  public function import_options() {
13
  'aioseop_options/modules/aiosp_opengraph_options/aiosp_opengraph_hometitle' => 'home_og_fields_enabled',
14
  'aioseop_options/modules/aiosp_opengraph_options/aiosp_opengraph_description' => 'home_og_fields_enabled',
15
  );
16
+
17
  // phpcs:enable
18
 
19
  public function data_exists() {
24
  return false;
25
  }
26
 
27
+ return apply_filters(
28
+ 'wds-import-aioseop-data-exists',
29
+ strpos( $version, '2.12' ) === 0
30
+ );
31
  }
32
 
33
  public function import_options() {
includes/core/class-wds-controller-analysis.php CHANGED
@@ -445,13 +445,17 @@ class Smartcrawl_Controller_Analysis extends Smartcrawl_Renderable {
445
  return;
446
  }
447
 
 
 
 
448
  /**
449
- * Since this code might be running as a result of an auto-save, we will use the latest post revision
450
- * to run a fresh analysis.
451
  */
452
- $latest_post_version = smartcrawl_get_latest_post_version( (int) $data['post_id'] );
453
- $this->analyze_post( $latest_post_version->ID );
454
- $post = get_post( (int) $data['post_id'] );
 
455
 
456
  $out = array();
457
  ob_start();
445
  return;
446
  }
447
 
448
+ $is_dirty = (boolean) smartcrawl_get_array_value( $data, 'is_dirty' );
449
+ $post_id = (int) smartcrawl_get_array_value( $data, 'post_id' );
450
+ $post = get_post( $post_id );
451
  /**
452
+ * If there is_dirty flag is set i.e. are unsaved changes in the editor then we
453
+ * will fetch the latest post revision and analyze that.
454
  */
455
+ $post_to_analyze = $is_dirty
456
+ ? smartcrawl_get_latest_post_version( $post_id )
457
+ : $post;
458
+ $this->analyze_post( $post_to_analyze->ID );
459
 
460
  $out = array();
461
  ob_start();
includes/core/class-wds-controller-onboard.php CHANGED
@@ -142,9 +142,11 @@ class Smartcrawl_Controller_Onboard extends Smartcrawl_Renderable {
142
  wp_send_json_success();
143
 
144
  return;
145
- }
146
 
147
- wp_send_json_error();
 
 
 
148
  }
149
 
150
  public function add_onboarding() {
142
  wp_send_json_success();
143
 
144
  return;
 
145
 
146
+ default:
147
+ wp_send_json_error();
148
+ return;
149
+ }
150
  }
151
 
152
  public function add_onboarding() {
includes/core/class-wds-controller-sitemap.php CHANGED
@@ -163,9 +163,12 @@ class Smartcrawl_Controller_Sitemap extends Smartcrawl_Renderable {
163
  */
164
  public function serve_sitemap() {
165
  if ( ! function_exists( 'smartcrawl_get_sitemap_path' ) ) {
166
- return false;
167
  }
168
- $smartcrawl_options = Smartcrawl_Settings::get_options();
 
 
 
169
  $url_path = $this->get_url_part( $_SERVER['REQUEST_URI'], PHP_URL_PATH );
170
 
171
  $path = smartcrawl_get_sitemap_path();
163
  */
164
  public function serve_sitemap() {
165
  if ( ! function_exists( 'smartcrawl_get_sitemap_path' ) ) {
166
+ return;
167
  }
168
+ if ( ! Smartcrawl_Settings::get_setting( 'sitemap' ) ) {
169
+ return;
170
+ }
171
+
172
  $url_path = $this->get_url_part( $_SERVER['REQUEST_URI'], PHP_URL_PATH );
173
 
174
  $path = smartcrawl_get_sitemap_path();
includes/core/class-wds-core-request.php CHANGED
@@ -63,14 +63,15 @@ class Smartcrawl_Core_Request {
63
  }
64
  $hasher = new PasswordHash( 8, true );
65
  $cookies[] = new WP_Http_Cookie( array(
66
- 'name' => 'wp-postpass_' . COOKIEHASH,
67
  'value' => $hasher->HashPassword( $post->post_password ),
68
- ));
69
  }
70
 
71
  if ( ! empty( $cookies ) ) {
72
  $params['cookies'] = $cookies;
73
  }
 
74
 
75
  $response = wp_remote_get( $url, $params );
76
 
@@ -88,4 +89,10 @@ class Smartcrawl_Core_Request {
88
 
89
  return (string) trim( join( "\n", $bits ) );
90
  }
 
 
 
 
 
 
91
  }
63
  }
64
  $hasher = new PasswordHash( 8, true );
65
  $cookies[] = new WP_Http_Cookie( array(
66
+ 'name' => 'wp-postpass_' . COOKIEHASH,
67
  'value' => $hasher->HashPassword( $post->post_password ),
68
+ ) );
69
  }
70
 
71
  if ( ! empty( $cookies ) ) {
72
  $params['cookies'] = $cookies;
73
  }
74
+ $params['timeout'] = $this->get_timeout();
75
 
76
  $response = wp_remote_get( $url, $params );
77
 
89
 
90
  return (string) trim( join( "\n", $bits ) );
91
  }
92
+
93
+ private function get_timeout() {
94
+ return defined( 'SMARTCRAWL_ANALYSIS_REQUEST_TIMEOUT' )
95
+ ? SMARTCRAWL_ANALYSIS_REQUEST_TIMEOUT
96
+ : 5;
97
+ }
98
  }
includes/core/class-wds-model-redirection.php CHANGED
@@ -21,6 +21,14 @@ class Smartcrawl_Model_Redirection extends Smartcrawl_Model {
21
  public function get_redirection( $source, $fallback = false ) {
22
  $redirections = $this->get_all_redirections();
23
 
 
 
 
 
 
 
 
 
24
  return ! empty( $redirections[ $source ] )
25
  ? $redirections[ $source ]
26
  : $fallback;
@@ -209,18 +217,12 @@ class Smartcrawl_Model_Redirection extends Smartcrawl_Model {
209
  $protocol = is_ssl() ? 'https:' : 'http:';
210
  $domain = $_SERVER['HTTP_HOST'];
211
 
212
- $port = (int) $_SERVER['SERVER_PORT'] ? ':' . (int) $_SERVER['SERVER_PORT'] : '';
213
- if ( is_ssl() && 443 === (int) $_SERVER['SERVER_PORT'] ) {
214
- $port = '';
215
- }
216
- if ( ! is_ssl() && 80 === (int) $_SERVER['SERVER_PORT'] ) {
217
- $port = '';
218
- }
219
- if ( smartcrawl_is_switch_active( 'SMARTCRAWL_OMIT_PORT_MATCHES' ) ) {
220
- $port = '';
221
- }
222
 
223
- $request = $_SERVER['REQUEST_URI'];
224
 
225
  $source = $protocol . '//' . $domain . $port . $request;
226
 
@@ -230,6 +232,22 @@ class Smartcrawl_Model_Redirection extends Smartcrawl_Model {
230
  );
231
  }
232
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233
  public function get_type() {
234
  return 'redirection';
235
  }
21
  public function get_redirection( $source, $fallback = false ) {
22
  $redirections = $this->get_all_redirections();
23
 
24
+ $source = in_array( trailingslashit( $source ), array_keys( $redirections ) )
25
+ ? trailingslashit( $source )
26
+ : ( in_array( untrailingslashit( $source ), array_keys( $redirections ) )
27
+ ? untrailingslashit( $source )
28
+ : $source
29
+ )
30
+ ;
31
+
32
  return ! empty( $redirections[ $source ] )
33
  ? $redirections[ $source ]
34
  : $fallback;
217
  $protocol = is_ssl() ? 'https:' : 'http:';
218
  $domain = $_SERVER['HTTP_HOST'];
219
 
220
+ $port = smartcrawl_is_switch_active( 'SMARTCRAWL_OMIT_PORT_MATCHES' )
221
+ ? ''
222
+ : $this->get_current_request_port()
223
+ ;
 
 
 
 
 
 
224
 
225
+ $request = parse_url( $_SERVER['REQUEST_URI'], PHP_URL_PATH );
226
 
227
  $source = $protocol . '//' . $domain . $port . $request;
228
 
232
  );
233
  }
234
 
235
+ /**
236
+ * Fetches the current request port
237
+ *
238
+ * @return int|string Port number or empty string
239
+ */
240
+ public function get_current_request_port() {
241
+ $port = (int) $_SERVER['SERVER_PORT'] ? ':' . (int) $_SERVER['SERVER_PORT'] : '';
242
+ if ( is_ssl() && 443 === (int) $_SERVER['SERVER_PORT'] ) {
243
+ $port = '';
244
+ }
245
+ if ( ! is_ssl() && 80 === (int) $_SERVER['SERVER_PORT'] ) {
246
+ $port = '';
247
+ }
248
+ return $port;
249
+ }
250
+
251
  public function get_type() {
252
  return 'redirection';
253
  }
includes/core/class-wds-opengraph-value-helper.php CHANGED
@@ -12,15 +12,17 @@ class Smartcrawl_OpenGraph_Value_Helper extends Smartcrawl_Type_Traverser {
12
  }
13
 
14
  public function get_title() {
15
- return $this->title;
16
  }
17
 
18
  public function get_description() {
19
- return $this->description;
20
  }
21
 
22
  public function get_images() {
23
- return array_unique( array_map( 'trim', $this->images ) );
 
 
24
  }
25
 
26
  public function is_enabled() {
@@ -67,7 +69,7 @@ class Smartcrawl_OpenGraph_Value_Helper extends Smartcrawl_Type_Traverser {
67
 
68
  // Add featured image as the last resort
69
  if ( has_post_thumbnail( $post ) ) {
70
- $this->images[] = get_the_post_thumbnail_url($post);
71
  }
72
 
73
  $this->enabled = ! $disabled;
12
  }
13
 
14
  public function get_title() {
15
+ return apply_filters( 'wds_custom_og_title', $this->title );
16
  }
17
 
18
  public function get_description() {
19
+ return apply_filters( 'wds_custom_og_description', $this->description );
20
  }
21
 
22
  public function get_images() {
23
+ $images = array_unique( array_map( 'trim', $this->images ) );
24
+
25
+ return apply_filters( 'wds_custom_og_image', $images );
26
  }
27
 
28
  public function is_enabled() {
69
 
70
  // Add featured image as the last resort
71
  if ( has_post_thumbnail( $post ) ) {
72
+ $this->images[] = get_the_post_thumbnail_url( $post );
73
  }
74
 
75
  $this->enabled = ! $disabled;
includes/core/class-wds-renderable.php CHANGED
@@ -28,7 +28,7 @@ abstract class Smartcrawl_Renderable {
28
  * @return mixed (string)View output on success, (bool)false on failure
29
  */
30
  protected function _load( $view, $args = array() ) {
31
- $view = preg_replace( '/[^-_a-z0-9\/]/i', '', $view );
32
  if ( empty( $view ) ) {
33
  return false;
34
  }
28
  * @return mixed (string)View output on success, (bool)false on failure
29
  */
30
  protected function _load( $view, $args = array() ) {
31
+ $view = preg_replace( '/[^\-_a-z0-9\/]/i', '', $view );
32
  if ( empty( $view ) ) {
33
  return false;
34
  }
includes/core/class-wds-string.php CHANGED
@@ -260,7 +260,7 @@ class Smartcrawl_String {
260
  * -2 for encoding issue
261
  */
262
  public static function syllables_count( $text ) {
263
- $syls = array();
264
 
265
  if ( empty( $text ) ) {
266
  return - 1;
@@ -268,21 +268,73 @@ class Smartcrawl_String {
268
  $words = self::words( $text );
269
 
270
  foreach ( $words as $word ) {
271
- $word = preg_replace( '/[^a-z]/', '', $word );
272
- if ( empty( $word ) ) {
273
- continue;
274
- } // Nothing here.
275
- $word = preg_replace( '/^[aeiouy]|[aeiouy]$/', '', $word );
276
- $tmp = preg_split( '/[aeiouy]+/', $word, null, PREG_SPLIT_NO_EMPTY );
277
- if ( 2 === count( $tmp ) && strlen( $word ) <= 4 ) {
278
- $tmp = array( $word );
279
- } // Simple threshold approximation.
280
- $syls = array_merge( $syls, $tmp );
281
  }
282
- if ( count( $syls ) === 0 /*|| count($syls) === count($words)*/ ) {
283
  return - 2;
284
  } // Well that didn't work...
285
- return count( $syls );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
286
  }
287
 
288
  /**
260
  * -2 for encoding issue
261
  */
262
  public static function syllables_count( $text ) {
263
+ $syls = 0;
264
 
265
  if ( empty( $text ) ) {
266
  return - 1;
268
  $words = self::words( $text );
269
 
270
  foreach ( $words as $word ) {
271
+ $syllables_count_word = self::syllables_count_word( $word );
272
+ $syls += $syllables_count_word;
 
 
 
 
 
 
 
 
273
  }
274
+ if ( $syls === 0 ) {
275
  return - 2;
276
  } // Well that didn't work...
277
+
278
+ return $syls;
279
+ }
280
+
281
+ /**
282
+ * Uses the method on https://howmanysyllables.com/howtocountsyllables
283
+ *
284
+ * @param $word
285
+ *
286
+ * @return int
287
+ */
288
+ private static function syllables_count_word( $word ) {
289
+ $word = trim( $word );
290
+ $unacceptable = (boolean) preg_match_all( '/[^a-zA-Z]/', $word );
291
+ if ( $unacceptable ) {
292
+ return 0;
293
+ }
294
+
295
+ $length = strlen( $word );
296
+ if ( $length < 3 ) {
297
+ // e.g. we, to, a
298
+ return 1;
299
+ }
300
+
301
+ // Count the number of vowels (A, E, I, O, U) in the word.
302
+ // Add 1 every time the letter 'y' makes the sound of a vowel
303
+ $syllables = preg_match_all( '/[aeiouy]/', $word );
304
+
305
+ // Subtract 1 for each silent vowel (like the silent 'e' at the end of a word).
306
+ $ends_with_e = self::ends_with( $word, 'e' );
307
+ $syllables -= $ends_with_e ? 1 : 0;
308
+
309
+ if ( $ends_with_e && $length === 3 ) {
310
+ // e.g. the, eve, axe
311
+ return 1;
312
+ }
313
+
314
+ // Subtract 1 for each diphthong
315
+ $diphthongs = preg_match_all( '/[aeiouy]{2}/', $word );
316
+ $syllables -= $diphthongs;
317
+
318
+ // Subtract 1 for each triphthong
319
+ $triphthongs = preg_match_all( '/[aeiouy]{3}/', $word );
320
+ $syllables -= $triphthongs;
321
+
322
+ // Does the word end with "le" or "les?" Add 1 only if the letter before the "le" is a consonant.
323
+ $ends_with_le = (boolean) preg_match_all( '/[^aeiouy]le|les$/', $word );
324
+ $syllables += $ends_with_le ? 1 : 0;
325
+
326
+ return $syllables <= 0
327
+ ? 0
328
+ : $syllables;
329
+ }
330
+
331
+ public static function ends_with( $haystack, $needle ) {
332
+ $length = strlen( $needle );
333
+ if ( $length == 0 ) {
334
+ return true;
335
+ }
336
+
337
+ return ( substr( $haystack, - $length ) === $needle );
338
  }
339
 
340
  /**
includes/core/class-wds-type-traverser.php CHANGED
@@ -57,6 +57,9 @@ abstract class Smartcrawl_Type_Traverser {
57
  case Smartcrawl_Endpoint_Resolver::L_SINGULAR:
58
  $this->handle_singular();
59
  break;
 
 
 
60
  }
61
  }
62
 
57
  case Smartcrawl_Endpoint_Resolver::L_SINGULAR:
58
  $this->handle_singular();
59
  break;
60
+
61
+ default:
62
+ break;
63
  }
64
  }
65
 
includes/core/class-wds-yoast-importer.php CHANGED
@@ -21,7 +21,10 @@ class Smartcrawl_Yoast_Importer extends Smartcrawl_Importer {
21
  return false;
22
  }
23
 
24
- return strpos( $version, '9.' ) === 0;
 
 
 
25
  }
26
 
27
  public function import_options() {
21
  return false;
22
  }
23
 
24
+ return apply_filters(
25
+ 'wds-import-yoast-data-exists',
26
+ strpos( $version, '10.' ) === 0
27
+ );
28
  }
29
 
30
  public function import_options() {
includes/core/core.php CHANGED
@@ -756,7 +756,19 @@ function smartcrawl_kill_stuck_transient( $key ) {
756
  * @return bool
757
  */
758
  function smartcrawl_is_switch_active( $switch ) {
759
- return defined( $switch ) ? constant( $switch ) : false;
 
 
 
 
 
 
 
 
 
 
 
 
760
  }
761
 
762
  /**
756
  * @return bool
757
  */
758
  function smartcrawl_is_switch_active( $switch ) {
759
+ $result = defined( $switch ) ? constant( $switch ) : false;
760
+
761
+ /**
762
+ * Checks if a define switch is toggled on
763
+ *
764
+ * Used in tests.
765
+ *
766
+ * @param bool $result Whether the switch is turned on.
767
+ * @param string $switch Switch name.
768
+ *
769
+ * @return bool
770
+ */
771
+ return (bool) apply_filters( 'smartcrawl_switch_active', $result, $switch );
772
  }
773
 
774
  /**
includes/external/simple_html_dom.php CHANGED
@@ -680,7 +680,7 @@ class simple_html_dom_node
680
  // This implies that an html attribute specifier may start with an @ sign that is NOT captured by the expression.
681
  // farther study is required to determine of this should be documented or removed.
682
  // $pattern = "/([\w-:\*]*)(?:\#([\w-]+)|\.([\w-]+))?(?:\[@?(!?[\w-]+)(?:([!*^$]?=)[\"']?(.*?)[\"']?)?\])?([\/, ]+)/is";
683
- $pattern = "/([\w-:\*]*)(?:\#([\w-]+)|\.([\w-]+))?(?:\[@?(!?[\w-:]+)(?:([!*^$]?=)[\"']?(.*?)[\"']?)?\])?([\/, ]+)/is";
684
  preg_match_all($pattern, trim($selector_string).' ', $matches, PREG_SET_ORDER);
685
  if (is_object($debugObject)) {$debugObject->debugLog(2, "Matches Array: ", $matches);}
686
 
@@ -886,7 +886,7 @@ class simple_html_dom_node
886
  {
887
  // Thanks to user gnarf from stackoverflow for this regular expression.
888
  $attributes = array();
889
- preg_match_all("/([\w-]+)\s*:\s*([^;]+)\s*;?/", $this->attr['style'], $matches, PREG_SET_ORDER);
890
  foreach ($matches as $match) {
891
  $attributes[$match[1]] = $match[2];
892
  }
@@ -1361,7 +1361,7 @@ class simple_html_dom
1361
  return true;
1362
  }
1363
 
1364
- if (!preg_match("/^[\w-:]+$/", $tag)) {
1365
  $node->_[HDOM_INFO_TEXT] = '<' . $tag . $this->copy_until('<>');
1366
  if ($this->char==='<') {
1367
  $this->link_nodes($node, false);
@@ -1718,4 +1718,4 @@ class simple_html_dom
1718
  function loadFile() {$args = func_get_args();$this->load_file($args);}
1719
  }
1720
 
1721
- ?>
680
  // This implies that an html attribute specifier may start with an @ sign that is NOT captured by the expression.
681
  // farther study is required to determine of this should be documented or removed.
682
  // $pattern = "/([\w-:\*]*)(?:\#([\w-]+)|\.([\w-]+))?(?:\[@?(!?[\w-]+)(?:([!*^$]?=)[\"']?(.*?)[\"']?)?\])?([\/, ]+)/is";
683
+ $pattern = "/([\w\-:\*]*)(?:\#([\w\-]+)|\.([\w\-]+))?(?:\[@?(!?[\w\-:]+)(?:([!*^$]?=)[\"']?(.*?)[\"']?)?\])?([\/, ]+)/is";
684
  preg_match_all($pattern, trim($selector_string).' ', $matches, PREG_SET_ORDER);
685
  if (is_object($debugObject)) {$debugObject->debugLog(2, "Matches Array: ", $matches);}
686
 
886
  {
887
  // Thanks to user gnarf from stackoverflow for this regular expression.
888
  $attributes = array();
889
+ preg_match_all("/([\w\-]+)\s*:\s*([^;]+)\s*;?/", $this->attr['style'], $matches, PREG_SET_ORDER);
890
  foreach ($matches as $match) {
891
  $attributes[$match[1]] = $match[2];
892
  }
1361
  return true;
1362
  }
1363
 
1364
+ if (!preg_match("/^[\w\-:]+$/", $tag)) {
1365
  $node->_[HDOM_INFO_TEXT] = '<' . $tag . $this->copy_until('<>');
1366
  if ($this->char==='<') {
1367
  $this->link_nodes($node, false);
1718
  function loadFile() {$args = func_get_args();$this->load_file($args);}
1719
  }
1720
 
1721
+ ?>
includes/js/wds-metabox.js CHANGED
@@ -5,51 +5,113 @@
5
  *
6
  * @param {Object} e Event object (optional)
7
  */
8
- function render_fields_change (e) {
9
  var $currentTarget = $(e.currentTarget),
10
- field = false,
11
- value = false;
 
12
 
13
- if($currentTarget.is('#title')) {
14
- field = 'title';
15
- } else if($currentTarget.is('#content') || $currentTarget.is('#excerpt')) {
16
- field = 'desc';
17
  }
18
 
19
- if( field ){
20
- $.post(ajaxurl, {
21
- id: wp.autosave.getPostData().post_id,
22
- action: "wds_metabox_update",
23
- post: wp.autosave.getPostData(),
24
- _wds_nonce: _wds_metabox.nonce
25
- }, 'json').done(function (rsp) {
26
- var description = (rsp || {}).description || '',
27
- title = (rsp || {}).title || '';
28
- $('#wds_title').attr('placeholder',title);
29
- $('#wds_metadesc').attr('placeholder',description);
30
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  }
32
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  }
34
 
35
  function refresh_meta_field_placeholders() {
36
- // The following line will trigger a call to ajax wds_metabox_update
37
- $('input#title').trigger('input');
 
 
 
 
38
  }
39
 
40
- function init () {
41
  window.setTimeout( function() {
42
  var editor = typeof tinymce !== 'undefined' && tinymce.get('content');
43
  if( editor ) {
44
  editor.on('change', function(e) {
45
  e.currentTarget = $('#content');
46
- _.debounce(render_fields_change.bind(e), 1000);
47
  });
48
  }
49
  }, 1000 );
50
- $(document).on("input","input#title,textarea#content,textarea#excerpt",_.debounce(render_fields_change, 1000)).trigger('input');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
 
52
- $('.wds-horizontal-tab-nav').on('click', '.wds-nav-item', function(){
 
 
 
 
 
 
 
53
  $('.wds-horizontal-tab-nav .active').removeClass('active');
54
  $(this).addClass('active');
55
  });
@@ -66,6 +128,14 @@
66
  // Boot
67
  $(init);
68
 
 
 
 
 
 
 
 
 
69
  /**
70
  * Deal with SEO analysis updates
71
  */
@@ -80,7 +150,8 @@
80
 
81
  var data = $.extend({
82
  action: 'wds-analysis-get-editor-analysis',
83
- post_id: wp.autosave.getPostData().post_id,
 
84
  wds_title: title,
85
  wds_description: description,
86
  wds_focus_keywords: focus_keywords,
@@ -132,24 +203,43 @@
132
 
133
  function handle_refresh_click() {
134
  before_ajax_request_blocking();
 
 
 
 
 
 
135
 
136
- var cback = function () {
 
137
  handle_autosave();
138
  // Re-hook our regular autosave handler
139
  $(document).on('after-autosave.smartcrawl', handle_autosave);
140
  };
 
 
 
 
 
 
 
 
141
  var editorSync = (tinyMCE || {}).triggerSave;
142
  if (editorSync) {
143
  editorSync();
144
  }
145
- var save = (((wp || {}).autosave || {}).server || {}).triggerSave;
146
- if (save) {
147
- // We are already hooked to autosave so let's disable our regular autosave handler momentarily to avoid multiple calls ...
148
- $(document).off('after-autosave.smartcrawl');
149
- // hook a new handler to heartbeat-tick.autosave
150
- $(document).one('heartbeat-tick.autosave', cback);
 
 
 
 
151
  wp.autosave.server.triggerSave();
152
- } else cback();
153
  }
154
 
155
  function before_ajax_request_blocking() {
@@ -243,7 +333,7 @@
243
  ;
244
  return $.post(ajaxurl, {
245
  action: action,
246
- post_id: wp.autosave.getPostData().post_id,
247
  check_id: check_id,
248
  _wds_nonce: _wds_metabox.nonce
249
  }, 'json');
@@ -299,6 +389,7 @@
299
  wds_title: title,
300
  wds_description: description,
301
  post_id: post_id,
 
302
  _wds_nonce: _wds_metabox.nonce
303
  }, 'json').done(function (data) {
304
  if ((data || {}).success) {
@@ -311,12 +402,50 @@
311
  });
312
  }
313
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
314
  function init_analysis () {
315
  window.render_update = render_update;
316
  window.Wds.dismissible_message();
317
 
318
  $(document)
319
- .on('after-autosave.smartcrawl', handle_autosave)
 
320
  .on('click', '#wds-wds-meta-box .wds-ignore', handle_ignore_toggle)
321
  .on('click', '#wds-wds-meta-box .wds-unignore', handle_ignore_toggle)
322
  .on('click', '#wds-wds-meta-box a[href="#reload"]', handle_update)
@@ -340,7 +469,10 @@
340
  }
341
  });
342
 
343
- handle_page_load();
 
 
 
344
 
345
  // Set metabox state on page load based on cookie value.
346
  // Fixes: https://app.asana.com/0/0/580085427092951/f
5
  *
6
  * @param {Object} e Event object (optional)
7
  */
8
+ function classic_post_fields_change_handler (e) {
9
  var $currentTarget = $(e.currentTarget),
10
+ field = $currentTarget.is('#title')
11
+ || $currentTarget.is('#content')
12
+ || $currentTarget.is('#excerpt');
13
 
14
+ if( field ){
15
+ refresh_meta_field_placeholders_ajax();
 
 
16
  }
17
 
18
+ }
19
+
20
+ function refresh_meta_field_placeholders_ajax() {
21
+ $.post(ajaxurl, {
22
+ id: get_post_data().post_id,
23
+ action: "wds_metabox_update",
24
+ post: get_post_data(),
25
+ _wds_nonce: _wds_metabox.nonce
26
+ }, 'json').done(function (rsp) {
27
+ var description = (rsp || {}).description || '',
28
+ title = (rsp || {}).title || '';
29
+
30
+ $('#wds_title').attr('placeholder', title);
31
+ $('#wds_metadesc').attr('placeholder', description);
32
+ });
33
+ }
34
+
35
+ function is_classic_editor_active() {
36
+ return $('input#title').length && (wp || {}).autosave;
37
+ }
38
+
39
+ function is_gutenberg_active() {
40
+ var data = (wp || {}).data;
41
+
42
+ return data
43
+ && data.select && data.select("core/editor")
44
+ && data.dispatch && data.dispatch("core/editor");
45
+ }
46
+
47
+ function get_post_data() {
48
+ if (is_gutenberg_active()) {
49
+ return get_gutenberg_data();
50
+ } else if (is_classic_editor_active()) {
51
+ return wp.autosave.getPostData();
52
  }
53
 
54
+ return {};
55
+ }
56
+
57
+ function get_gutenberg_data() {
58
+ var fields = ['content', 'excerpt', 'post_author', 'post_id', 'post_title', 'post_type'],
59
+ data = {};
60
+
61
+ _.each(fields, function (field) {
62
+ data[field] = wp.data.select("core/editor").getEditedPostAttribute(field.replace('post_', '')) || '';
63
+ });
64
+
65
+ if (!data.post_id) {
66
+ data.post_id = $('#post_ID').val() || 0;
67
+ }
68
+
69
+ return data;
70
  }
71
 
72
  function refresh_meta_field_placeholders() {
73
+ if (is_classic_editor_active()) {
74
+ // The following line will trigger a call to ajax wds_metabox_update
75
+ $('input#title').trigger('input');
76
+ } else {
77
+ refresh_meta_field_placeholders_ajax();
78
+ }
79
  }
80
 
81
+ function hook_classic_editor_listeners() {
82
  window.setTimeout( function() {
83
  var editor = typeof tinymce !== 'undefined' && tinymce.get('content');
84
  if( editor ) {
85
  editor.on('change', function(e) {
86
  e.currentTarget = $('#content');
87
+ _.debounce(classic_post_fields_change_handler.bind(e), 1000);
88
  });
89
  }
90
  }, 1000 );
91
+ $(document).on("input","input#title,textarea#content,textarea#excerpt",_.debounce(classic_post_fields_change_handler, 1000)).trigger('input');
92
+ }
93
+
94
+ function hook_gutenberg_listeners() {
95
+ if (!is_gutenberg_active()) {
96
+ return;
97
+ }
98
+
99
+ var debounced = _.debounce(refresh_meta_field_placeholders_ajax, 5000);
100
+ wp.data.subscribe(function () {
101
+ if (wp.data.select("core/editor").isEditedPostDirty()) {
102
+ debounced();
103
+ }
104
+ });
105
+ }
106
 
107
+ function init() {
108
+ if (is_gutenberg_active()) {
109
+ hook_gutenberg_listeners();
110
+ } else if (is_classic_editor_active()) {
111
+ hook_classic_editor_listeners();
112
+ }
113
+
114
+ $('.wds-horizontal-tab-nav').on('click', '.wds-nav-item', function () {
115
  $('.wds-horizontal-tab-nav .active').removeClass('active');
116
  $(this).addClass('active');
117
  });
128
  // Boot
129
  $(init);
130
 
131
+ function is_edited_post_dirty() {
132
+ if (is_gutenberg_active()) {
133
+ return wp.data.select("core/editor").isEditedPostDirty();
134
+ } else {
135
+ return wp.autosave.server.postChanged();
136
+ }
137
+ }
138
+
139
  /**
140
  * Deal with SEO analysis updates
141
  */
150
 
151
  var data = $.extend({
152
  action: 'wds-analysis-get-editor-analysis',
153
+ post_id: get_post_data().post_id,
154
+ is_dirty: is_edited_post_dirty() ? 1 : 0,
155
  wds_title: title,
156
  wds_description: description,
157
  wds_focus_keywords: focus_keywords,
203
 
204
  function handle_refresh_click() {
205
  before_ajax_request_blocking();
206
+ if (is_classic_editor_active()) {
207
+ hook_to_heartbeat();
208
+ trigger_tinymce_save();
209
+ }
210
+ trigger_autosave();
211
+ }
212
 
213
+ function hook_to_heartbeat() {
214
+ var handle_heartbeat = function () {
215
  handle_autosave();
216
  // Re-hook our regular autosave handler
217
  $(document).on('after-autosave.smartcrawl', handle_autosave);
218
  };
219
+
220
+ // We are already hooked to autosave so let's disable our regular autosave handler momentarily to avoid multiple calls ...
221
+ $(document).off('after-autosave.smartcrawl');
222
+ // hook a new handler to heartbeat-tick.autosave
223
+ $(document).one('heartbeat-tick.autosave', handle_heartbeat);
224
+ }
225
+
226
+ function trigger_tinymce_save() {
227
  var editorSync = (tinyMCE || {}).triggerSave;
228
  if (editorSync) {
229
  editorSync();
230
  }
231
+ }
232
+
233
+ function trigger_autosave() {
234
+ if (is_gutenberg_active()) {
235
+ if (wp.data.select("core/editor").isEditedPostAutosaveable()) {
236
+ wp.data.dispatch("core/editor").autosave();
237
+ } else {
238
+ trigger_custom_autosave_event();
239
+ }
240
+ } else if (is_classic_editor_active()) {
241
  wp.autosave.server.triggerSave();
242
+ }
243
  }
244
 
245
  function before_ajax_request_blocking() {
333
  ;
334
  return $.post(ajaxurl, {
335
  action: action,
336
+ post_id: get_post_data().post_id,
337
  check_id: check_id,
338
  _wds_nonce: _wds_metabox.nonce
339
  }, 'json');
389
  wds_title: title,
390
  wds_description: description,
391
  post_id: post_id,
392
+ is_dirty: is_edited_post_dirty() ? 1 : 0,
393
  _wds_nonce: _wds_metabox.nonce
394
  }, 'json').done(function (data) {
395
  if ((data || {}).success) {
402
  });
403
  }
404
 
405
+ function register_api_fetch_middleware() {
406
+ if (!(wp || {}).apiFetch) {
407
+ return;
408
+ }
409
+
410
+ wp.apiFetch.use(function (options, next) {
411
+ var result = next(options);
412
+ result.then(function () {
413
+ if (is_autosave_request(options) || is_post_save_request(options)) {
414
+ trigger_custom_autosave_event();
415
+ }
416
+ });
417
+
418
+ return result;
419
+ });
420
+ }
421
+
422
+ function is_autosave_request(request) {
423
+ return request && request.path
424
+ && request.path.includes('/autosaves');
425
+ }
426
+
427
+ function is_post_save_request(request) {
428
+ var post = get_post_data(),
429
+ post_id = post.post_id,
430
+ post_type = post.post_type;
431
+
432
+ return request && request.path
433
+ && request.method === 'PUT'
434
+ && request.path.includes('/' + post_id)
435
+ && request.path.includes('/' + post_type);
436
+ }
437
+
438
+ function trigger_custom_autosave_event() {
439
+ $(document).trigger('wds-after-autosave');
440
+ }
441
+
442
  function init_analysis () {
443
  window.render_update = render_update;
444
  window.Wds.dismissible_message();
445
 
446
  $(document)
447
+ .on('after-autosave.smartcrawl', trigger_custom_autosave_event)
448
+ .on('wds-after-autosave', handle_autosave)
449
  .on('click', '#wds-wds-meta-box .wds-ignore', handle_ignore_toggle)
450
  .on('click', '#wds-wds-meta-box .wds-unignore', handle_ignore_toggle)
451
  .on('click', '#wds-wds-meta-box a[href="#reload"]', handle_update)
469
  }
470
  });
471
 
472
+ $(window)
473
+ .on('load', handle_page_load)
474
+ .on('load', register_api_fetch_middleware)
475
+ ;
476
 
477
  // Set metabox state on page load based on cookie value.
478
  // Fixes: https://app.asana.com/0/0/580085427092951/f
includes/tools/onpage.php CHANGED
@@ -670,7 +670,7 @@ class Smartcrawl_OnPage {
670
  // News keywords.
671
  $resolver = $this->get_resolver();
672
  $news_meta = $resolver->is_singular() ? stripslashes( smartcrawl_get_value( 'news_keywords' ) ) : false;
673
- $news_meta = trim( preg_replace( '/\s\s+/', ' ', preg_replace( '/[^-_,a-z0-9 ]/i', ' ', $news_meta ) ) );
674
  if ( $news_meta ) {
675
  echo '<meta name="news_keywords" content="' . esc_attr( $news_meta ) . '" />' . "\n";
676
  }
670
  // News keywords.
671
  $resolver = $this->get_resolver();
672
  $news_meta = $resolver->is_singular() ? stripslashes( smartcrawl_get_value( 'news_keywords' ) ) : false;
673
+ $news_meta = trim( preg_replace( '/\s\s+/', ' ', preg_replace( '/[^\-_,a-z0-9 ]/i', ' ', $news_meta ) ) );
674
  if ( $news_meta ) {
675
  echo '<meta name="news_keywords" content="' . esc_attr( $news_meta ) . '" />' . "\n";
676
  }
includes/tools/sitemaps.php CHANGED
@@ -286,7 +286,7 @@ class Smartcrawl_Xml_Sitemap {
286
  * Loads all items that will get into a sitemap.
287
  */
288
  private function _load_all_items() {
289
- $this->_add_item( home_url('/'), 1, 'daily' ); // Home URL.
290
  $this->_load_post_items();
291
  $this->_load_taxonomy_items();
292
  // Load BuddyPress-specific items.
@@ -676,20 +676,9 @@ class Smartcrawl_Xml_Sitemap {
676
  * @return string
677
  */
678
  private function _get_stylesheet( $xsl ) {
679
- if ( is_multisite() && defined( 'SUBDOMAIN_INSTALL' ) && ! SUBDOMAIN_INSTALL ) {
680
- $plugin_host = wp_parse_url( SMARTCRAWL_PLUGIN_URL, PHP_URL_HOST );
681
- $xsl_host = preg_replace(
682
- '/^https?:\/\/' . preg_quote( $plugin_host . '/', '/' ) . '/',
683
- '', SMARTCRAWL_PLUGIN_URL
684
- );
685
- $xsl_host = '../' . $xsl_host;
686
-
687
- return "<?xml-stylesheet type='text/xml' href='{$xsl_host}admin/templates/xsl/{$xsl}.xsl'?>\n";
688
- } else {
689
- $plugin_dir_url = plugin_dir_url( dirname( __FILE__ ) );
690
 
691
- return "<?xml-stylesheet type='text/xml' href='{$plugin_dir_url}admin/templates/xsl/{$xsl}.xsl'?>\n";
692
- }
693
  }
694
 
695
  /**
286
  * Loads all items that will get into a sitemap.
287
  */
288
  private function _load_all_items() {
289
+ $this->_add_item( home_url( '/' ), 1, 'daily' ); // Home URL.
290
  $this->_load_post_items();
291
  $this->_load_taxonomy_items();
292
  // Load BuddyPress-specific items.
676
  * @return string
677
  */
678
  private function _get_stylesheet( $xsl ) {
679
+ $plugin_dir_url = SMARTCRAWL_PLUGIN_URL;
 
 
 
 
 
 
 
 
 
 
680
 
681
+ return "<?xml-stylesheet type='text/xml' href='{$plugin_dir_url}admin/templates/xsl/{$xsl}.xsl'?>\n";
 
682
  }
683
 
684
  /**
includes/tools/video-sitemaps.php CHANGED
@@ -280,7 +280,7 @@ class Smartcrawl_Xml_VideoSitemap {
280
  }
281
 
282
  $post = get_post( $post_id );
283
- $src = preg_match( '#(http://wordpress.tv/[-_/.a-z0-9]+)#i', $post->post_content, $matches );
284
  if ( empty( $matches[1] ) ) {
285
  return false;
286
  }
280
  }
281
 
282
  $post = get_post( $post_id );
283
+ $src = preg_match( '#(http://wordpress.tv/[\-_/.a-z0-9]+)#i', $post->post_content, $matches );
284
  if ( empty( $matches[1] ) ) {
285
  return false;
286
  }
languages/wds.pot CHANGED
@@ -1,17 +1,18 @@
1
- # Copyright (C) 2018 WPMU DEV
2
  # This file is distributed under the same license as the SmartCrawl package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: SmartCrawl 2.2.4.1\n"
6
- "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/wpmu-dev-seo\n"
7
- "POT-Creation-Date: 2018-12-11 04:55:00+00:00\n"
 
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=utf-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
11
- "PO-Revision-Date: 2018-MO-DA HO:MI+ZONE\n"
12
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
  "Language-Team: LANGUAGE <LL@li.org>\n"
14
- "X-Generator: grunt-wp-i18n1.0.2\n"
15
 
16
  #: includes/admin/admin.php:134 includes/admin/settings/settings.php:248
17
  #: includes/admin/settings/settings.php:319
@@ -43,84 +44,84 @@ msgstr ""
43
  msgid "You can fix this here"
44
  msgstr ""
45
 
46
- #: includes/admin/metabox.php:119
47
  msgid "{TOTAL_LEFT} characters left"
48
  msgstr ""
49
 
50
- #: includes/admin/metabox.php:120
51
  msgid "Over {MAX_COUNT} characters ({CURRENT_COUNT})"
52
  msgstr ""
53
 
54
- #: includes/admin/metabox.php:121
55
  msgid ""
56
  "Over {MAX_COUNT} characters ({CURRENT_COUNT}) - make sure your SEO title is "
57
  "shorter"
58
  msgstr ""
59
 
60
- #: includes/admin/metabox.php:137
61
  #: includes/admin/templates/metabox/analysis-readability.php:67
62
  #: includes/admin/templates/metabox/analysis-seo-analysis.php:24
63
  msgid "Analyzing content, please wait a few moments"
64
  msgstr ""
65
 
66
- #: includes/admin/metabox.php:170
67
  msgid "NO ODP (Block Open Directory Project description of the page)"
68
  msgstr ""
69
 
70
- #: includes/admin/metabox.php:171
71
  msgid "NO YDIR (Don't display the Yahoo! Directory titles and abstracts)"
72
  msgstr ""
73
 
74
- #: includes/admin/metabox.php:172 includes/admin/metabox.php:457
75
  msgid "No Archive"
76
  msgstr ""
77
 
78
- #: includes/admin/metabox.php:173 includes/admin/metabox.php:458
79
  msgid "No Snippet"
80
  msgstr ""
81
 
82
- #: includes/admin/metabox.php:176
83
  msgid "Automatic prioritization"
84
  msgstr ""
85
 
86
- #: includes/admin/metabox.php:177
87
  msgid "1 - Highest priority"
88
  msgstr ""
89
 
90
- #: includes/admin/metabox.php:179
91
  msgid "High priority (root pages default)"
92
  msgstr ""
93
 
94
- #: includes/admin/metabox.php:181
95
  msgid "Secondary priority (subpages default)"
96
  msgstr ""
97
 
98
- #: includes/admin/metabox.php:182
99
  msgid "Medium priority"
100
  msgstr ""
101
 
102
- #: includes/admin/metabox.php:186
103
  msgid "Lowest priority"
104
  msgstr ""
105
 
106
- #: includes/admin/metabox.php:413
107
  #: includes/admin/templates/quick-edit-title.php:5
108
  msgid "Title Tag"
109
  msgstr ""
110
 
111
- #: includes/admin/metabox.php:415
112
  msgid "Robots Meta"
113
  msgstr ""
114
 
115
- #: includes/admin/metabox.php:436
116
  msgid "Redirects to %s"
117
  msgstr ""
118
 
119
- #: includes/admin/metabox.php:455
120
  msgid "No ODP"
121
  msgstr ""
122
 
123
- #: includes/admin/metabox.php:456
124
  msgid "No YDIR"
125
  msgstr ""
126
 
@@ -234,162 +235,162 @@ msgstr ""
234
  msgid "Your description seems to be a bit on the long side, consider trimming it"
235
  msgstr ""
236
 
237
- #: includes/admin/settings/onpage.php:526
238
  #: includes/admin/templates/sitemap/sitemap-crawl-issues-group.php:41
239
  msgid "No"
240
  msgstr ""
241
 
242
- #: includes/admin/settings/onpage.php:527
243
  #: includes/admin/settings/sitemap.php:224
244
  #: includes/admin/settings/sitemap.php:351
245
  msgid "Yes"
246
  msgstr ""
247
 
248
- #: includes/admin/settings/onpage.php:531
249
  #: includes/admin/settings/sitemap.php:347
250
  msgid "Google"
251
  msgstr ""
252
 
253
- #: includes/admin/settings/onpage.php:532
254
  #: includes/admin/settings/sitemap.php:348
255
  msgid "Bing"
256
  msgstr ""
257
 
258
- #: includes/admin/settings/onpage.php:552
259
  #: includes/admin/templates/onpage/onpage-section-settings.php:5
260
  msgid "Separator"
261
  msgstr ""
262
 
263
- #: includes/admin/settings/onpage.php:553
264
  msgid "Date of the post/page"
265
  msgstr ""
266
 
267
- #: includes/admin/settings/onpage.php:554
268
  msgid "Title of the post/page"
269
  msgstr ""
270
 
271
- #: includes/admin/settings/onpage.php:555
272
  msgid "Site's name"
273
  msgstr ""
274
 
275
- #: includes/admin/settings/onpage.php:556
276
  msgid "Site's tagline / description"
277
  msgstr ""
278
 
279
- #: includes/admin/settings/onpage.php:557
280
  msgid "Post/page excerpt (or auto-generated if it does not exist)"
281
  msgstr ""
282
 
283
- #: includes/admin/settings/onpage.php:558
284
  msgid "Post/page excerpt (without auto-generation)"
285
  msgstr ""
286
 
287
- #: includes/admin/settings/onpage.php:559
288
  msgid "Current tag/tags"
289
  msgstr ""
290
 
291
- #: includes/admin/settings/onpage.php:560
292
  msgid "Post categories (comma separated)"
293
  msgstr ""
294
 
295
- #: includes/admin/settings/onpage.php:561
296
  msgid "Category description"
297
  msgstr ""
298
 
299
- #: includes/admin/settings/onpage.php:562
300
  msgid "Tag description"
301
  msgstr ""
302
 
303
- #: includes/admin/settings/onpage.php:563
304
  msgid "Term description"
305
  msgstr ""
306
 
307
- #: includes/admin/settings/onpage.php:564
308
  msgid "Term name"
309
  msgstr ""
310
 
311
- #: includes/admin/settings/onpage.php:565
312
  msgid "Post/page modified time"
313
  msgstr ""
314
 
315
- #: includes/admin/settings/onpage.php:566
316
  msgid "Post/page ID"
317
  msgstr ""
318
 
319
- #: includes/admin/settings/onpage.php:567
320
  msgid "Post/page author's 'nicename'"
321
  msgstr ""
322
 
323
- #: includes/admin/settings/onpage.php:568
324
  msgid "Post/page author's userid"
325
  msgstr ""
326
 
327
- #: includes/admin/settings/onpage.php:569
328
  msgid "Current search phrase"
329
  msgstr ""
330
 
331
- #: includes/admin/settings/onpage.php:570
332
  msgid "Current time"
333
  msgstr ""
334
 
335
- #: includes/admin/settings/onpage.php:571
336
  msgid "Current date"
337
  msgstr ""
338
 
339
- #: includes/admin/settings/onpage.php:572
340
  msgid "Current month"
341
  msgstr ""
342
 
343
- #: includes/admin/settings/onpage.php:573
344
  msgid "Current year"
345
  msgstr ""
346
 
347
- #: includes/admin/settings/onpage.php:574
348
  msgid "Current page number (i.e. page 2 of 4)"
349
  msgstr ""
350
 
351
- #: includes/admin/settings/onpage.php:575
352
  msgid "Current page total"
353
  msgstr ""
354
 
355
- #: includes/admin/settings/onpage.php:576
356
  msgid "Current page number"
357
  msgstr ""
358
 
359
- #: includes/admin/settings/onpage.php:577
360
  msgid "Attachment caption"
361
  msgstr ""
362
 
363
- #: includes/admin/settings/onpage.php:578
364
- #: includes/admin/settings/onpage.php:580
365
  msgid "Current page number, spelled out as numeral in English"
366
  msgstr ""
367
 
368
- #: includes/admin/settings/onpage.php:579
369
  msgid "Current page total, spelled out as numeral in English"
370
  msgstr ""
371
 
372
- #: includes/admin/settings/onpage.php:581
373
  msgid "Post type label plural"
374
  msgstr ""
375
 
376
- #: includes/admin/settings/onpage.php:582
377
  msgid "Post type label singular"
378
  msgstr ""
379
 
380
- #: includes/admin/settings/onpage.php:586
381
  msgid "BuddyPress group name"
382
  msgstr ""
383
 
384
- #: includes/admin/settings/onpage.php:587
385
  msgid "BuddyPress group description"
386
  msgstr ""
387
 
388
- #: includes/admin/settings/onpage.php:588
389
  msgid "BuddyPress username"
390
  msgstr ""
391
 
392
- #: includes/admin/settings/onpage.php:589
393
  msgid "BuddyPress user's full name"
394
  msgstr ""
395
 
@@ -1186,7 +1187,7 @@ msgstr ""
1186
  #: includes/admin/templates/dashboard/dashboard-content-analysis-seo-overview.php:32
1187
  #: includes/admin/templates/dashboard/dashboard-content-analysis-seo-overview.php:57
1188
  #: includes/admin/templates/post-list/post-seo-analysis-good.php:2
1189
- #: includes/core/class-wds-controller-analysis.php:638
1190
  msgid "Good"
1191
  msgstr ""
1192
 
@@ -3987,19 +3988,19 @@ msgstr ""
3987
  msgid "N/A"
3988
  msgstr ""
3989
 
3990
- #: includes/core/class-wds-controller-analysis.php:632
3991
  msgid "No Focus Keyword"
3992
  msgstr ""
3993
 
3994
- #: includes/core/class-wds-controller-analysis.php:635
3995
  msgid "Needs Improvement"
3996
  msgstr ""
3997
 
3998
- #: includes/core/class-wds-controller-analysis.php:657
3999
  msgid "SEO:"
4000
  msgstr ""
4001
 
4002
- #: includes/core/class-wds-controller-analysis.php:664
4003
  msgid "Readability:"
4004
  msgstr ""
4005
 
@@ -4069,7 +4070,7 @@ msgstr ""
4069
  msgid "Invalid parameters. Try refreshing the page and attempting again."
4070
  msgstr ""
4071
 
4072
- #: includes/core/class-wds-controller-onboard.php:162
4073
  msgid "All done, please hold on..."
4074
  msgstr ""
4075
 
@@ -4087,7 +4088,7 @@ msgstr ""
4087
  msgid "The missing items have been added to your sitemap as extra URLs."
4088
  msgstr ""
4089
 
4090
- #: includes/core/class-wds-controller-sitemap.php:192
4091
  msgid "The sitemap file was not found."
4092
  msgstr ""
4093
 
1
+ # Copyright (C) 2019 WPMU DEV
2
  # This file is distributed under the same license as the SmartCrawl package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: SmartCrawl 2.2.6\n"
6
+ "Report-Msgid-Bugs-To: "
7
+ "https://wordpress.org/support/plugin/smartcrawl-regular\n"
8
+ "POT-Creation-Date: 2019-04-12 05:52:48+00:00\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=utf-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
+ "PO-Revision-Date: 2019-MO-DA HO:MI+ZONE\n"
13
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
  "Language-Team: LANGUAGE <LL@li.org>\n"
15
+ "X-Generator: grunt-wp-i18n 1.0.3\n"
16
 
17
  #: includes/admin/admin.php:134 includes/admin/settings/settings.php:248
18
  #: includes/admin/settings/settings.php:319
44
  msgid "You can fix this here"
45
  msgstr ""
46
 
47
+ #: includes/admin/metabox.php:126
48
  msgid "{TOTAL_LEFT} characters left"
49
  msgstr ""
50
 
51
+ #: includes/admin/metabox.php:127
52
  msgid "Over {MAX_COUNT} characters ({CURRENT_COUNT})"
53
  msgstr ""
54
 
55
+ #: includes/admin/metabox.php:128
56
  msgid ""
57
  "Over {MAX_COUNT} characters ({CURRENT_COUNT}) - make sure your SEO title is "
58
  "shorter"
59
  msgstr ""
60
 
61
+ #: includes/admin/metabox.php:144
62
  #: includes/admin/templates/metabox/analysis-readability.php:67
63
  #: includes/admin/templates/metabox/analysis-seo-analysis.php:24
64
  msgid "Analyzing content, please wait a few moments"
65
  msgstr ""
66
 
67
+ #: includes/admin/metabox.php:177
68
  msgid "NO ODP (Block Open Directory Project description of the page)"
69
  msgstr ""
70
 
71
+ #: includes/admin/metabox.php:178
72
  msgid "NO YDIR (Don't display the Yahoo! Directory titles and abstracts)"
73
  msgstr ""
74
 
75
+ #: includes/admin/metabox.php:179 includes/admin/metabox.php:469
76
  msgid "No Archive"
77
  msgstr ""
78
 
79
+ #: includes/admin/metabox.php:180 includes/admin/metabox.php:470
80
  msgid "No Snippet"
81
  msgstr ""
82
 
83
+ #: includes/admin/metabox.php:183
84
  msgid "Automatic prioritization"
85
  msgstr ""
86
 
87
+ #: includes/admin/metabox.php:184
88
  msgid "1 - Highest priority"
89
  msgstr ""
90
 
91
+ #: includes/admin/metabox.php:186
92
  msgid "High priority (root pages default)"
93
  msgstr ""
94
 
95
+ #: includes/admin/metabox.php:188
96
  msgid "Secondary priority (subpages default)"
97
  msgstr ""
98
 
99
+ #: includes/admin/metabox.php:189
100
  msgid "Medium priority"
101
  msgstr ""
102
 
103
+ #: includes/admin/metabox.php:193
104
  msgid "Lowest priority"
105
  msgstr ""
106
 
107
+ #: includes/admin/metabox.php:425
108
  #: includes/admin/templates/quick-edit-title.php:5
109
  msgid "Title Tag"
110
  msgstr ""
111
 
112
+ #: includes/admin/metabox.php:427
113
  msgid "Robots Meta"
114
  msgstr ""
115
 
116
+ #: includes/admin/metabox.php:448
117
  msgid "Redirects to %s"
118
  msgstr ""
119
 
120
+ #: includes/admin/metabox.php:467
121
  msgid "No ODP"
122
  msgstr ""
123
 
124
+ #: includes/admin/metabox.php:468
125
  msgid "No YDIR"
126
  msgstr ""
127
 
235
  msgid "Your description seems to be a bit on the long side, consider trimming it"
236
  msgstr ""
237
 
238
+ #: includes/admin/settings/onpage.php:529
239
  #: includes/admin/templates/sitemap/sitemap-crawl-issues-group.php:41
240
  msgid "No"
241
  msgstr ""
242
 
243
+ #: includes/admin/settings/onpage.php:530
244
  #: includes/admin/settings/sitemap.php:224
245
  #: includes/admin/settings/sitemap.php:351
246
  msgid "Yes"
247
  msgstr ""
248
 
249
+ #: includes/admin/settings/onpage.php:534
250
  #: includes/admin/settings/sitemap.php:347
251
  msgid "Google"
252
  msgstr ""
253
 
254
+ #: includes/admin/settings/onpage.php:535
255
  #: includes/admin/settings/sitemap.php:348
256
  msgid "Bing"
257
  msgstr ""
258
 
259
+ #: includes/admin/settings/onpage.php:555
260
  #: includes/admin/templates/onpage/onpage-section-settings.php:5
261
  msgid "Separator"
262
  msgstr ""
263
 
264
+ #: includes/admin/settings/onpage.php:556
265
  msgid "Date of the post/page"
266
  msgstr ""
267
 
268
+ #: includes/admin/settings/onpage.php:557
269
  msgid "Title of the post/page"
270
  msgstr ""
271
 
272
+ #: includes/admin/settings/onpage.php:558
273
  msgid "Site's name"
274
  msgstr ""
275
 
276
+ #: includes/admin/settings/onpage.php:559
277
  msgid "Site's tagline / description"
278
  msgstr ""
279
 
280
+ #: includes/admin/settings/onpage.php:560
281
  msgid "Post/page excerpt (or auto-generated if it does not exist)"
282
  msgstr ""
283
 
284
+ #: includes/admin/settings/onpage.php:561
285
  msgid "Post/page excerpt (without auto-generation)"
286
  msgstr ""
287
 
288
+ #: includes/admin/settings/onpage.php:562
289
  msgid "Current tag/tags"
290
  msgstr ""
291
 
292
+ #: includes/admin/settings/onpage.php:563
293
  msgid "Post categories (comma separated)"
294
  msgstr ""
295
 
296
+ #: includes/admin/settings/onpage.php:564
297
  msgid "Category description"
298
  msgstr ""
299
 
300
+ #: includes/admin/settings/onpage.php:565
301
  msgid "Tag description"
302
  msgstr ""
303
 
304
+ #: includes/admin/settings/onpage.php:566
305
  msgid "Term description"
306
  msgstr ""
307
 
308
+ #: includes/admin/settings/onpage.php:567
309
  msgid "Term name"
310
  msgstr ""
311
 
312
+ #: includes/admin/settings/onpage.php:568
313
  msgid "Post/page modified time"
314
  msgstr ""
315
 
316
+ #: includes/admin/settings/onpage.php:569
317
  msgid "Post/page ID"
318
  msgstr ""
319
 
320
+ #: includes/admin/settings/onpage.php:570
321
  msgid "Post/page author's 'nicename'"
322
  msgstr ""
323
 
324
+ #: includes/admin/settings/onpage.php:571
325
  msgid "Post/page author's userid"
326
  msgstr ""
327
 
328
+ #: includes/admin/settings/onpage.php:572
329
  msgid "Current search phrase"
330
  msgstr ""
331
 
332
+ #: includes/admin/settings/onpage.php:573
333
  msgid "Current time"
334
  msgstr ""
335
 
336
+ #: includes/admin/settings/onpage.php:574
337
  msgid "Current date"
338
  msgstr ""
339
 
340
+ #: includes/admin/settings/onpage.php:575
341
  msgid "Current month"
342
  msgstr ""
343
 
344
+ #: includes/admin/settings/onpage.php:576
345
  msgid "Current year"
346
  msgstr ""
347
 
348
+ #: includes/admin/settings/onpage.php:577
349
  msgid "Current page number (i.e. page 2 of 4)"
350
  msgstr ""
351
 
352
+ #: includes/admin/settings/onpage.php:578
353
  msgid "Current page total"
354
  msgstr ""
355
 
356
+ #: includes/admin/settings/onpage.php:579
357
  msgid "Current page number"
358
  msgstr ""
359
 
360
+ #: includes/admin/settings/onpage.php:580
361
  msgid "Attachment caption"
362
  msgstr ""
363
 
364
+ #: includes/admin/settings/onpage.php:581
365
+ #: includes/admin/settings/onpage.php:583
366
  msgid "Current page number, spelled out as numeral in English"
367
  msgstr ""
368
 
369
+ #: includes/admin/settings/onpage.php:582
370
  msgid "Current page total, spelled out as numeral in English"
371
  msgstr ""
372
 
373
+ #: includes/admin/settings/onpage.php:584
374
  msgid "Post type label plural"
375
  msgstr ""
376
 
377
+ #: includes/admin/settings/onpage.php:585
378
  msgid "Post type label singular"
379
  msgstr ""
380
 
381
+ #: includes/admin/settings/onpage.php:589
382
  msgid "BuddyPress group name"
383
  msgstr ""
384
 
385
+ #: includes/admin/settings/onpage.php:590
386
  msgid "BuddyPress group description"
387
  msgstr ""
388
 
389
+ #: includes/admin/settings/onpage.php:591
390
  msgid "BuddyPress username"
391
  msgstr ""
392
 
393
+ #: includes/admin/settings/onpage.php:592
394
  msgid "BuddyPress user's full name"
395
  msgstr ""
396
 
1187
  #: includes/admin/templates/dashboard/dashboard-content-analysis-seo-overview.php:32
1188
  #: includes/admin/templates/dashboard/dashboard-content-analysis-seo-overview.php:57
1189
  #: includes/admin/templates/post-list/post-seo-analysis-good.php:2
1190
+ #: includes/core/class-wds-controller-analysis.php:642
1191
  msgid "Good"
1192
  msgstr ""
1193
 
3988
  msgid "N/A"
3989
  msgstr ""
3990
 
3991
+ #: includes/core/class-wds-controller-analysis.php:636
3992
  msgid "No Focus Keyword"
3993
  msgstr ""
3994
 
3995
+ #: includes/core/class-wds-controller-analysis.php:639
3996
  msgid "Needs Improvement"
3997
  msgstr ""
3998
 
3999
+ #: includes/core/class-wds-controller-analysis.php:661
4000
  msgid "SEO:"
4001
  msgstr ""
4002
 
4003
+ #: includes/core/class-wds-controller-analysis.php:668
4004
  msgid "Readability:"
4005
  msgstr ""
4006
 
4070
  msgid "Invalid parameters. Try refreshing the page and attempting again."
4071
  msgstr ""
4072
 
4073
+ #: includes/core/class-wds-controller-onboard.php:164
4074
  msgid "All done, please hold on..."
4075
  msgstr ""
4076
 
4088
  msgid "The missing items have been added to your sitemap as extra URLs."
4089
  msgstr ""
4090
 
4091
+ #: includes/core/class-wds-controller-sitemap.php:195
4092
  msgid "The sitemap file was not found."
4093
  msgstr ""
4094
 
readme.txt CHANGED
@@ -6,8 +6,8 @@ Tags: SEO, Search Engine Optimization, Sitemap, PageRank, website ranking, SEO t
6
  Author URI: https://premium.wpmudev.org/
7
  Author: WPMU DEV
8
  Requires at least: 4.6
9
- Tested up to: 5.0
10
- Stable tag: 2.2.4.1
11
 
12
  The SEO checker and optimization tool that helps you rank higher and get discovered in search engines.
13
 
@@ -59,7 +59,7 @@ Love SmartCrawl! WPMU DEV has some other awesome free plugins you should checkou
59
  - [Hustle](https://wordpress.org/plugins/wordpress-popup/) - Pop-ups, Slide-ins and Email Opt-ins
60
  - [Defender](https://wordpress.org/plugins/defender-security/) - Security, Monitoring, and Hack Protection
61
 
62
- And if you want scheduled SEO scans, reports, automatic keyword linking and access to our suite of site management tools you can always take the next step with a [WPMU DEV Membership](https://premium.wpmudev.org/project/smartcrawl-wordpress-seo/). Give it a go free for 30 days.
63
 
64
  == Frequently Asked Questions ==
65
 
@@ -86,6 +86,31 @@ SmartCrawl works with any normal WP content and page builders shouldn’t be an
86
 
87
  == Changelog ==
88
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  = 2.2.4.1 =
90
 
91
  * Fix: Show the WP.org rating request to admins only
@@ -300,9 +325,9 @@ SmartCrawl works with any normal WP content and page builders shouldn’t be an
300
 
301
  == About Us ==
302
  WPMU DEV is a premium supplier of quality WordPress plugins, services and support. Join us here:
303
- [https://premium.wpmudev.org/](https://premium.wpmudev.org/?utm_source=wordpress.org&utm_medium=readme)
304
 
305
  Don't forget to stay up to date on everything WordPress from the Internet's number one resource:
306
- [WPMU DEV Blog](https://premium.wpmudev.org/blog/?utm_source=wordpress.org&utm_medium=readme)
307
 
308
  Hey, one more thing... we hope you enjoy our [free offerings](http://profiles.wordpress.org/WPMUDEV/) as much as we've loved making them for you!
6
  Author URI: https://premium.wpmudev.org/
7
  Author: WPMU DEV
8
  Requires at least: 4.6
9
+ Tested up to: 5.1
10
+ Stable tag: 2.2.6
11
 
12
  The SEO checker and optimization tool that helps you rank higher and get discovered in search engines.
13
 
59
  - [Hustle](https://wordpress.org/plugins/wordpress-popup/) - Pop-ups, Slide-ins and Email Opt-ins
60
  - [Defender](https://wordpress.org/plugins/defender-security/) - Security, Monitoring, and Hack Protection
61
 
62
+ And if you want scheduled SEO scans, reports, automatic keyword linking and access to our suite of site management tools you can always take the next step with a [WPMU DEV Membership](https://premium.wpmudev.org/project/smartcrawl-wordpress-seo/?utm_source=wordpress.org&utm_medium=readme&utm_campaign=smartcrawl-readme&utm_content=wpmu_dev_membership#trial). Give it a go free for 30 days.
63
 
64
  == Frequently Asked Questions ==
65
 
86
 
87
  == Changelog ==
88
 
89
+ = 2.2.6 =
90
+
91
+ * New: Support for Yoast v10 and AIOSEO v2.12 in third-party importer
92
+ * Fix: Redirects added from sitemap crawl report not converted to absolute
93
+ * Fix: Sitemap can't be removed while SC is active
94
+ * Fix: Import not working for Automatic linking settings
95
+ * Fix: Metabox conflict in classic editor
96
+
97
+ = 2.2.5 =
98
+
99
+ * New: New filters for modifying OpenGraph values
100
+ * New: Improved accuracy of readability analysis
101
+
102
+ * Fix: Missing columns on the post list page
103
+ * Fix: Certain websites throwing 404 error on redirection
104
+ * Fix: SEO metabox shown for non-public posts
105
+ * Fix: Better Gutenberg compatibility
106
+ * Fix: Warning on sitemap settings page
107
+ * Fix: Added ability to increase analysis request timeout
108
+ * Fix: Improved autoloader performance
109
+ * Fix: Warning in metabox placeholder loader
110
+ * Fix: Inaccurate preview when more recent post revision available
111
+ * Fix: Update the AIOSEOP importer to include the latest version
112
+ * Fix: Stylesheet URL incorrect in sub-site sitemaps
113
+
114
  = 2.2.4.1 =
115
 
116
  * Fix: Show the WP.org rating request to admins only
325
 
326
  == About Us ==
327
  WPMU DEV is a premium supplier of quality WordPress plugins, services and support. Join us here:
328
+ [https://premium.wpmudev.org/](https://premium.wpmudev.org/?utm_source=wordpress.org&utm_medium=readme&utm_campaign=smartcrawl-readme&utm_content=wpmu_dev_link)
329
 
330
  Don't forget to stay up to date on everything WordPress from the Internet's number one resource:
331
+ [WPMU DEV Blog](https://premium.wpmudev.org/?utm_source=wordpress.org&utm_medium=readme&utm_campaign=smartcrawl-readme&utm_content=wpmu_dev_blog_link)
332
 
333
  Hey, one more thing... we hope you enjoy our [free offerings](http://profiles.wordpress.org/WPMUDEV/) as much as we've loved making them for you!
wpmu-dev-seo.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: SmartCrawl
4
  * Plugin URI: http://premium.wpmudev.org/project/wpmu-dev-seo/
5
  * Description: Every SEO option that a site requires, in one easy bundle.
6
- * Version: 2.2.4.1
7
  * Network: true
8
  * Text Domain: wds
9
  * Author: WPMU DEV
@@ -29,7 +29,7 @@
29
  */
30
 
31
 
32
- define( 'SMARTCRAWL_VERSION', '2.2.4.1' );
33
 
34
  class Smartcrawl_Loader {
35
 
3
  * Plugin Name: SmartCrawl
4
  * Plugin URI: http://premium.wpmudev.org/project/wpmu-dev-seo/
5
  * Description: Every SEO option that a site requires, in one easy bundle.
6
+ * Version: 2.2.6
7
  * Network: true
8
  * Text Domain: wds
9
  * Author: WPMU DEV
29
  */
30
 
31
 
32
+ define( 'SMARTCRAWL_VERSION', '2.2.6' );
33
 
34
  class Smartcrawl_Loader {
35