Cyr-To-Lat - Version 4.3

Version Description

(14.12.2019) = * Added Chinese table * Tested up to WordPress 5.3 * Tested up to PHP 7.4 * External library wp-background-processing scoped into own namespace to prevent errors in some cases

Download this release

Release Info

Developer mihdan
Plugin Icon 128x128 Cyr-To-Lat
Version 4.3
Comparing to
See all releases

Code changes from version 4.2.3 to 4.3

Files changed (30) hide show
  1. includes/background-processes/class-cyr-to-lat-conversion-process.php → classes/background-processes/class-conversion-process.php +12 -8
  2. includes/background-processes/class-cyr-to-lat-post-conversion-process.php → classes/background-processes/class-post-conversion-process.php +11 -7
  3. includes/background-processes/class-cyr-to-lat-term-conversion-process.php → classes/background-processes/class-term-conversion-process.php +14 -10
  4. includes/class-cyr-to-lat-acf.php → classes/class-acf.php +10 -10
  5. includes/class-cyr-to-lat-admin-notices.php → classes/class-admin-notices.php +10 -8
  6. classes/class-conversion-tables.php +827 -0
  7. includes/class-cyr-to-lat-converter.php → classes/class-converter.php +28 -26
  8. includes/class-cyr-to-lat-main.php → classes/class-main.php +68 -35
  9. includes/class-cyr-to-lat-requirements.php → classes/class-requirements.php +6 -4
  10. includes/class-cyr-to-lat-settings.php → classes/class-settings.php +146 -94
  11. includes/class-cyr-to-lat-wp-cli.php → classes/class-wp-cli.php +20 -13
  12. cyr-to-lat.php +12 -10
  13. dist/js/settings/app.js +1 -1
  14. includes/class-cyr-to-lat-conversion-tables.php +0 -415
  15. languages/cyr2lat-ru_RU.mo +0 -0
  16. languages/cyr2lat-ru_RU.po +69 -56
  17. languages/cyr2lat-sv.mo +0 -0
  18. languages/cyr2lat-sv.po +67 -54
  19. languages/cyr2lat-uk.mo +0 -0
  20. languages/cyr2lat-uk.po +69 -54
  21. lib/wp-background-processing/class-wp-async-request.php +142 -0
  22. lib/wp-background-processing/class-wp-background-process.php +464 -0
  23. readme.txt +16 -11
  24. vendor/a5hleyrich/wp-background-processing/classes/wp-async-request.php +0 -163
  25. vendor/a5hleyrich/wp-background-processing/classes/wp-background-process.php +0 -535
  26. vendor/a5hleyrich/wp-background-processing/license.txt +0 -280
  27. vendor/a5hleyrich/wp-background-processing/wp-background-processing.php +0 -20
  28. vendor/composer/autoload_classmap.php +13 -107
  29. vendor/composer/autoload_static.php +13 -107
  30. vendor/composer/installed.json +0 -40
includes/background-processes/class-cyr-to-lat-conversion-process.php → classes/background-processes/class-conversion-process.php RENAMED
@@ -5,10 +5,14 @@
5
  * @package cyr-to-lat
6
  */
7
 
 
 
 
 
8
  /**
9
- * Class Cyr_To_Lat_Conversion_Process
10
  */
11
- class Cyr_To_Lat_Conversion_Process extends WP_Background_Process {
12
 
13
  /**
14
  * Prefix
@@ -20,14 +24,14 @@ class Cyr_To_Lat_Conversion_Process extends WP_Background_Process {
20
  /**
21
  * Plugin main class
22
  *
23
- * @var Cyr_To_Lat_Main
24
  */
25
  protected $main;
26
 
27
  /**
28
- * Cyr_To_Lat_Conversion_Process constructor
29
  *
30
- * @param Cyr_To_Lat_Main $main Plugin main class.
31
  */
32
  public function __construct( $main ) {
33
  $this->main = $main;
@@ -71,6 +75,7 @@ class Cyr_To_Lat_Conversion_Process extends WP_Background_Process {
71
  return false;
72
  }
73
 
 
74
  /**
75
  * Is process running
76
  *
@@ -78,10 +83,9 @@ class Cyr_To_Lat_Conversion_Process extends WP_Background_Process {
78
  * in a background process.
79
  */
80
  public function is_process_running() {
81
- $is_process_running = parent::is_process_running();
82
-
83
- return $is_process_running;
84
  }
 
85
 
86
  /**
87
  * Log
5
  * @package cyr-to-lat
6
  */
7
 
8
+ namespace Cyr_To_Lat;
9
+
10
+ use Cyr_To_Lat\KAGG\WP_Background_Processing\WP_Background_Process;
11
+
12
  /**
13
+ * Class Conversion_Process
14
  */
15
+ class Conversion_Process extends WP_Background_Process {
16
 
17
  /**
18
  * Prefix
24
  /**
25
  * Plugin main class
26
  *
27
+ * @var Main
28
  */
29
  protected $main;
30
 
31
  /**
32
+ * Conversion_Process constructor
33
  *
34
+ * @param Main $main Plugin main class.
35
  */
36
  public function __construct( $main ) {
37
  $this->main = $main;
75
  return false;
76
  }
77
 
78
+ // phpcs:disable Generic.CodeAnalysis.UselessOverridingMethod.Found
79
  /**
80
  * Is process running
81
  *
83
  * in a background process.
84
  */
85
  public function is_process_running() {
86
+ return parent::is_process_running();
 
 
87
  }
88
+ // phpcs:enable Generic.CodeAnalysis.UselessOverridingMethod.Found
89
 
90
  /**
91
  * Log
includes/background-processes/class-cyr-to-lat-post-conversion-process.php → classes/background-processes/class-post-conversion-process.php RENAMED
@@ -5,10 +5,14 @@
5
  * @package cyr-to-lat
6
  */
7
 
 
 
 
 
8
  /**
9
- * Class Cyr_To_Lat_Post_Conversion_Process
10
  */
11
- class Cyr_To_Lat_Post_Conversion_Process extends Cyr_To_Lat_Conversion_Process {
12
 
13
  /**
14
  * Site locale.
@@ -32,9 +36,9 @@ class Cyr_To_Lat_Post_Conversion_Process extends Cyr_To_Lat_Conversion_Process {
32
  protected $action = CYR_TO_LAT_POST_CONVERSION_ACTION;
33
 
34
  /**
35
- * Cyr_To_Lat_Post_Conversion_Process constructor.
36
  *
37
- * @param Cyr_To_Lat_Main $main Plugin main class.
38
  */
39
  public function __construct( $main ) {
40
  parent::__construct( $main );
@@ -54,14 +58,14 @@ class Cyr_To_Lat_Post_Conversion_Process extends Cyr_To_Lat_Conversion_Process {
54
  $this->post = $post;
55
  $post_name = urldecode( $post->post_name );
56
 
57
- add_filter( 'locale', array( $this, 'filter_post_locale' ) );
58
  $sanitized_name = sanitize_title( $post_name );
59
- remove_filter( 'locale', array( $this, 'filter_post_locale' ) );
60
 
61
  if ( urldecode( $sanitized_name ) !== $post_name ) {
62
  update_post_meta( $post->ID, '_wp_old_slug', $post_name );
63
  // phpcs:disable WordPress.DB.DirectDatabaseQuery
64
- $wpdb->update( $wpdb->posts, array( 'post_name' => $sanitized_name ), array( 'ID' => $post->ID ) );
65
  // phpcs:enable
66
 
67
  $this->log( __( 'Post slug converted:', 'cyr2lat' ) . ' ' . $post_name . ' => ' . urldecode( $sanitized_name ) );
5
  * @package cyr-to-lat
6
  */
7
 
8
+ namespace Cyr_To_Lat;
9
+
10
+ use stdClass;
11
+
12
  /**
13
+ * Class Post_Conversion_Process
14
  */
15
+ class Post_Conversion_Process extends Conversion_Process {
16
 
17
  /**
18
  * Site locale.
36
  protected $action = CYR_TO_LAT_POST_CONVERSION_ACTION;
37
 
38
  /**
39
+ * Post_Conversion_Process constructor.
40
  *
41
+ * @param Main $main Plugin main class.
42
  */
43
  public function __construct( $main ) {
44
  parent::__construct( $main );
58
  $this->post = $post;
59
  $post_name = urldecode( $post->post_name );
60
 
61
+ add_filter( 'locale', [ $this, 'filter_post_locale' ] );
62
  $sanitized_name = sanitize_title( $post_name );
63
+ remove_filter( 'locale', [ $this, 'filter_post_locale' ] );
64
 
65
  if ( urldecode( $sanitized_name ) !== $post_name ) {
66
  update_post_meta( $post->ID, '_wp_old_slug', $post_name );
67
  // phpcs:disable WordPress.DB.DirectDatabaseQuery
68
+ $wpdb->update( $wpdb->posts, [ 'post_name' => $sanitized_name ], [ 'ID' => $post->ID ] );
69
  // phpcs:enable
70
 
71
  $this->log( __( 'Post slug converted:', 'cyr2lat' ) . ' ' . $post_name . ' => ' . urldecode( $sanitized_name ) );
includes/background-processes/class-cyr-to-lat-term-conversion-process.php → classes/background-processes/class-term-conversion-process.php RENAMED
@@ -5,10 +5,14 @@
5
  * @package cyr-to-lat
6
  */
7
 
 
 
 
 
8
  /**
9
- * Class Cyr_To_Lat_Term_Conversion_Process
10
  */
11
- class Cyr_To_Lat_Term_Conversion_Process extends Cyr_To_Lat_Conversion_Process {
12
 
13
  /**
14
  * Site locale.
@@ -32,9 +36,9 @@ class Cyr_To_Lat_Term_Conversion_Process extends Cyr_To_Lat_Conversion_Process {
32
  protected $action = CYR_TO_LAT_TERM_CONVERSION_ACTION;
33
 
34
  /**
35
- * Cyr_To_Lat_Term_Conversion_Process constructor.
36
  *
37
- * @param Cyr_To_Lat_Main $main Plugin main class.
38
  */
39
  public function __construct( $main ) {
40
  parent::__construct( $main );
@@ -54,13 +58,13 @@ class Cyr_To_Lat_Term_Conversion_Process extends Cyr_To_Lat_Conversion_Process {
54
  $this->term = $term;
55
  $slug = urldecode( $term->slug );
56
 
57
- add_filter( 'locale', array( $this, 'filter_term_locale' ) );
58
  $sanitized_slug = sanitize_title( $slug );
59
- remove_filter( 'locale', array( $this, 'filter_term_locale' ) );
60
 
61
  if ( urldecode( $sanitized_slug ) !== $slug ) {
62
  // phpcs:disable WordPress.DB.DirectDatabaseQuery
63
- $wpdb->update( $wpdb->terms, array( 'slug' => $sanitized_slug ), array( 'term_id' => $term->term_id ) );
64
  // phpcs:enable
65
 
66
  $this->log( __( 'Term slug converted:', 'cyr2lat' ) . ' ' . $slug . ' => ' . urldecode( $sanitized_slug ) );
@@ -84,10 +88,10 @@ class Cyr_To_Lat_Term_Conversion_Process extends Cyr_To_Lat_Conversion_Process {
84
  * @return string
85
  */
86
  public function filter_term_locale() {
87
- $args = array(
88
  'element_type' => $this->term->taxonomy,
89
  'element_id' => $this->term->term_taxonomy_id,
90
- );
91
 
92
  $wpml_element_language_details = apply_filters( 'wpml_element_language_details', false, $args );
93
 
@@ -97,7 +101,7 @@ class Cyr_To_Lat_Term_Conversion_Process extends Cyr_To_Lat_Conversion_Process {
97
 
98
  $language_code = $wpml_element_language_details->language_code;
99
 
100
- $wpml_active_languages = apply_filters( 'wpml_active_languages', false, array() );
101
 
102
  return isset( $wpml_active_languages[ $language_code ]['default_locale'] ) ?
103
  $wpml_active_languages[ $language_code ]['default_locale'] : $this->locale;
5
  * @package cyr-to-lat
6
  */
7
 
8
+ namespace Cyr_To_Lat;
9
+
10
+ use stdClass;
11
+
12
  /**
13
+ * Class Term_Conversion_Process
14
  */
15
+ class Term_Conversion_Process extends Conversion_Process {
16
 
17
  /**
18
  * Site locale.
36
  protected $action = CYR_TO_LAT_TERM_CONVERSION_ACTION;
37
 
38
  /**
39
+ * Term_Conversion_Process constructor.
40
  *
41
+ * @param Main $main Plugin main class.
42
  */
43
  public function __construct( $main ) {
44
  parent::__construct( $main );
58
  $this->term = $term;
59
  $slug = urldecode( $term->slug );
60
 
61
+ add_filter( 'locale', [ $this, 'filter_term_locale' ] );
62
  $sanitized_slug = sanitize_title( $slug );
63
+ remove_filter( 'locale', [ $this, 'filter_term_locale' ] );
64
 
65
  if ( urldecode( $sanitized_slug ) !== $slug ) {
66
  // phpcs:disable WordPress.DB.DirectDatabaseQuery
67
+ $wpdb->update( $wpdb->terms, [ 'slug' => $sanitized_slug ], [ 'term_id' => $term->term_id ] );
68
  // phpcs:enable
69
 
70
  $this->log( __( 'Term slug converted:', 'cyr2lat' ) . ' ' . $slug . ' => ' . urldecode( $sanitized_slug ) );
88
  * @return string
89
  */
90
  public function filter_term_locale() {
91
+ $args = [
92
  'element_type' => $this->term->taxonomy,
93
  'element_id' => $this->term->term_taxonomy_id,
94
+ ];
95
 
96
  $wpml_element_language_details = apply_filters( 'wpml_element_language_details', false, $args );
97
 
101
 
102
  $language_code = $wpml_element_language_details->language_code;
103
 
104
+ $wpml_active_languages = apply_filters( 'wpml_active_languages', false, [] );
105
 
106
  return isset( $wpml_active_languages[ $language_code ]['default_locale'] ) ?
107
  $wpml_active_languages[ $language_code ]['default_locale'] : $this->locale;
includes/class-cyr-to-lat-acf.php → classes/class-acf.php RENAMED
@@ -5,22 +5,24 @@
5
  * @package cyr-to-lat
6
  */
7
 
 
 
8
  /**
9
- * Class Cyr_To_Lat_ACF
10
  */
11
- class Cyr_To_Lat_ACF {
12
 
13
  /**
14
  * Plugin settings.
15
  *
16
- * @var Cyr_To_Lat_Settings
17
  */
18
  private $settings;
19
 
20
  /**
21
- * Cyr_To_Lat_ACF constructor.
22
  *
23
- * @param Cyr_To_Lat_Settings $settings Plugin settings.
24
  */
25
  public function __construct( $settings ) {
26
  $this->settings = $settings;
@@ -32,7 +34,7 @@ class Cyr_To_Lat_ACF {
32
  * Init class hooks.
33
  */
34
  public function init_hooks() {
35
- add_action( 'acf/field_group/admin_enqueue_scripts', array( $this, 'enqueue_script' ) );
36
  }
37
 
38
  /**
@@ -44,14 +46,12 @@ class Cyr_To_Lat_ACF {
44
  wp_enqueue_script(
45
  'cyr-to-lat-acf-field-group',
46
  CYR_TO_LAT_URL . '/js/acf-field-group.js',
47
- array(),
48
  CYR_TO_LAT_VERSION,
49
  true
50
  );
51
 
52
- $object = array(
53
- 'table' => $table,
54
- );
55
 
56
  wp_localize_script( 'cyr-to-lat-acf-field-group', 'CyrToLatAcfFieldGroup', $object );
57
  }
5
  * @package cyr-to-lat
6
  */
7
 
8
+ namespace Cyr_To_Lat;
9
+
10
  /**
11
+ * Class ACF
12
  */
13
+ class ACF {
14
 
15
  /**
16
  * Plugin settings.
17
  *
18
+ * @var Settings
19
  */
20
  private $settings;
21
 
22
  /**
23
+ * ACF constructor.
24
  *
25
+ * @param Settings $settings Plugin settings.
26
  */
27
  public function __construct( $settings ) {
28
  $this->settings = $settings;
34
  * Init class hooks.
35
  */
36
  public function init_hooks() {
37
+ add_action( 'acf/field_group/admin_enqueue_scripts', [ $this, 'enqueue_script' ] );
38
  }
39
 
40
  /**
46
  wp_enqueue_script(
47
  'cyr-to-lat-acf-field-group',
48
  CYR_TO_LAT_URL . '/js/acf-field-group.js',
49
+ [],
50
  CYR_TO_LAT_VERSION,
51
  true
52
  );
53
 
54
+ $object = [ 'table' => $table ];
 
 
55
 
56
  wp_localize_script( 'cyr-to-lat-acf-field-group', 'CyrToLatAcfFieldGroup', $object );
57
  }
includes/class-cyr-to-lat-admin-notices.php → classes/class-admin-notices.php RENAMED
@@ -5,25 +5,27 @@
5
  * @package cyr-to-lat
6
  */
7
 
 
 
8
  /**
9
- * Class Cyr_To_Lat_Admin_Notices
10
  *
11
- * @class Cyr_To_Lat_Admin_Notices
12
  */
13
- class Cyr_To_Lat_Admin_Notices {
14
 
15
  /**
16
  * Admin notices array.
17
  *
18
  * @var array
19
  */
20
- private $notices = array();
21
 
22
  /**
23
- * Cyr_To_Lat_Admin_Notices constructor.
24
  */
25
  public function __construct() {
26
- add_action( 'admin_notices', array( $this, 'show_notices' ) );
27
  }
28
 
29
  /**
@@ -34,10 +36,10 @@ class Cyr_To_Lat_Admin_Notices {
34
  * is-dismissible.
35
  */
36
  public function add_notice( $message, $class = 'notice' ) {
37
- $this->notices[] = array(
38
  'message' => $message,
39
  'class' => $class,
40
- );
41
  }
42
 
43
  /**
5
  * @package cyr-to-lat
6
  */
7
 
8
+ namespace Cyr_To_Lat;
9
+
10
  /**
11
+ * Class Admin_Notices
12
  *
13
+ * @class Admin_Notices
14
  */
15
+ class Admin_Notices {
16
 
17
  /**
18
  * Admin notices array.
19
  *
20
  * @var array
21
  */
22
+ private $notices = [];
23
 
24
  /**
25
+ * Admin_Notices constructor.
26
  */
27
  public function __construct() {
28
+ add_action( 'admin_notices', [ $this, 'show_notices' ] );
29
  }
30
 
31
  /**
36
  * is-dismissible.
37
  */
38
  public function add_notice( $message, $class = 'notice' ) {
39
+ $this->notices[] = [
40
  'message' => $message,
41
  'class' => $class,
42
+ ];
43
  }
44
 
45
  /**
classes/class-conversion-tables.php ADDED
@@ -0,0 +1,827 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Conversion tables.
4
+ *
5
+ * @package cyr-to-lat
6
+ */
7
+
8
+ namespace Cyr_To_Lat;
9
+
10
+ use Cyr_To_Lat\Symfony\Polyfill\Mbstring\Mbstring;
11
+
12
+ /**
13
+ * Class Conversion_Tables
14
+ *
15
+ * @class Conversion_Tables
16
+ */
17
+ class Conversion_Tables {
18
+
19
+ /**
20
+ * Get conversion table by locale.
21
+ *
22
+ * @link https://ru.wikipedia.org/wiki/ISO_9
23
+ *
24
+ * @param string $locale WordPress locale.
25
+ *
26
+ * @return array
27
+ */
28
+ public static function get( $locale = '' ) {
29
+ $table = [
30
+ 'А' => 'A',
31
+ 'Б' => 'B',
32
+ 'В' => 'V',
33
+ 'Г' => 'G',
34
+ 'Д' => 'D',
35
+ 'Е' => 'E',
36
+ 'Ё' => 'YO',
37
+ 'Ж' => 'ZH',
38
+ 'З' => 'Z',
39
+ 'И' => 'I',
40
+ 'Й' => 'J',
41
+ 'І' => 'I',
42
+ 'К' => 'K',
43
+ 'Л' => 'L',
44
+ 'М' => 'M',
45
+ 'Н' => 'N',
46
+ 'О' => 'O',
47
+ 'П' => 'P',
48
+ 'Р' => 'R',
49
+ 'С' => 'S',
50
+ 'Т' => 'T',
51
+ 'У' => 'U',
52
+ 'Ф' => 'F',
53
+ 'Х' => 'H',
54
+ 'Ц' => 'CZ',
55
+ 'Ч' => 'CH',
56
+ 'Ш' => 'SH',
57
+ 'Щ' => 'SHH',
58
+ 'Ъ' => '',
59
+ 'Ы' => 'Y',
60
+ 'Ь' => '',
61
+ 'Э' => 'E',
62
+ 'Ю' => 'YU',
63
+ 'Я' => 'YA',
64
+ 'Ѣ' => 'YE',
65
+ 'Ѳ' => 'FH',
66
+ 'Ѵ' => 'YH',
67
+ 'а' => 'a',
68
+ 'б' => 'b',
69
+ 'в' => 'v',
70
+ 'г' => 'g',
71
+ 'д' => 'd',
72
+ 'е' => 'e',
73
+ 'ё' => 'yo',
74
+ 'ж' => 'zh',
75
+ 'з' => 'z',
76
+ 'и' => 'i',
77
+ 'й' => 'j',
78
+ 'і' => 'i',
79
+ 'к' => 'k',
80
+ 'л' => 'l',
81
+ 'м' => 'm',
82
+ 'н' => 'n',
83
+ 'о' => 'o',
84
+ 'п' => 'p',
85
+ 'р' => 'r',
86
+ 'с' => 's',
87
+ 'т' => 't',
88
+ 'у' => 'u',
89
+ 'ф' => 'f',
90
+ 'х' => 'h',
91
+ 'ц' => 'cz',
92
+ 'ч' => 'ch',
93
+ 'ш' => 'sh',
94
+ 'щ' => 'shh',
95
+ 'ъ' => '',
96
+ 'ы' => 'y',
97
+ 'ь' => '',
98
+ 'э' => 'e',
99
+ 'ю' => 'yu',
100
+ 'я' => 'ya',
101
+ 'ѣ' => 'ye',
102
+ 'ѳ' => 'fh',
103
+ 'ѵ' => 'yh',
104
+ ];
105
+ switch ( $locale ) {
106
+ // Belorussian.
107
+ case 'bel':
108
+ unset( $table['И'] );
109
+ unset( $table['и'] );
110
+ $table['Ў'] = 'U';
111
+ $table['ў'] = 'u';
112
+ unset( $table['Щ'] );
113
+ unset( $table['щ'] );
114
+ unset( $table['Ъ'] );
115
+ unset( $table['ъ'] );
116
+ unset( $table['Ѣ'] );
117
+ unset( $table['ѣ'] );
118
+ unset( $table['Ѳ'] );
119
+ unset( $table['ѳ'] );
120
+ unset( $table['Ѵ'] );
121
+ unset( $table['ѵ'] );
122
+ break;
123
+ // Ukrainian.
124
+ case 'uk':
125
+ $table['Ґ'] = 'G';
126
+ $table['ґ'] = 'g';
127
+ unset( $table['Ё'] );
128
+ unset( $table['ё'] );
129
+ $table['Є'] = 'YE';
130
+ $table['є'] = 'ye';
131
+ $table['И'] = 'Y';
132
+ $table['и'] = 'y';
133
+ $table['Ї'] = 'YI';
134
+ $table['ї'] = 'yi';
135
+ unset( $table['Ъ'] );
136
+ unset( $table['ъ'] );
137
+ unset( $table['Ы'] );
138
+ unset( $table['ы'] );
139
+ unset( $table['Э'] );
140
+ unset( $table['э'] );
141
+ unset( $table['Ѣ'] );
142
+ unset( $table['ѣ'] );
143
+ unset( $table['Ѳ'] );
144
+ unset( $table['ѳ'] );
145
+ unset( $table['Ѵ'] );
146
+ unset( $table['ѵ'] );
147
+ break;
148
+ // Bulgarian.
149
+ case 'bg_BG':
150
+ unset( $table['Ё'] );
151
+ unset( $table['ё'] );
152
+ $table['Щ'] = 'STH';
153
+ $table['щ'] = 'sth';
154
+ $table['Ъ'] = 'A';
155
+ $table['ъ'] = 'a';
156
+ unset( $table['Ы'] );
157
+ unset( $table['ы'] );
158
+ unset( $table['Э'] );
159
+ unset( $table['э'] );
160
+ $table['Ѫ'] = 'О';
161
+ $table['ѫ'] = 'о';
162
+ break;
163
+ // Macedonian.
164
+ case 'mk_MK':
165
+ $table['Ѓ'] = 'G';
166
+ $table['ѓ'] = 'g';
167
+ unset( $table['Ё'] );
168
+ unset( $table['ё'] );
169
+ $table['Ѕ'] = 'Z';
170
+ $table['ѕ'] = 'z';
171
+ unset( $table['Й'] );
172
+ unset( $table['й'] );
173
+ $table['Ј'] = 'J';
174
+ $table['ј'] = 'j';
175
+ unset( $table['I'] );
176
+ unset( $table['i'] );
177
+ $table['Ќ'] = 'K';
178
+ $table['ќ'] = 'k';
179
+ $table['Љ'] = 'L';
180
+ $table['љ'] = 'l';
181
+ $table['Њ'] = 'N';
182
+ $table['њ'] = 'n';
183
+ $table['Џ'] = 'DH';
184
+ $table['џ'] = 'dh';
185
+ unset( $table['Щ'] );
186
+ unset( $table['щ'] );
187
+ unset( $table['Ъ'] );
188
+ unset( $table['ъ'] );
189
+ unset( $table['Ы'] );
190
+ unset( $table['ы'] );
191
+ unset( $table['Ь'] );
192
+ unset( $table['ь'] );
193
+ unset( $table['Э'] );
194
+ unset( $table['э'] );
195
+ unset( $table['Ю'] );
196
+ unset( $table['ю'] );
197
+ unset( $table['Я'] );
198
+ unset( $table['я'] );
199
+ unset( $table['Ѣ'] );
200
+ unset( $table['ѣ'] );
201
+ unset( $table['Ѳ'] );
202
+ unset( $table['ѳ'] );
203
+ unset( $table['Ѵ'] );
204
+ unset( $table['ѵ'] );
205
+ break;
206
+ // Serbian.
207
+ case 'sr_RS':
208
+ $table['Ђ'] = 'Dj';
209
+ $table['ђ'] = 'dj';
210
+ unset( $table['Ё'] );
211
+ unset( $table['ё'] );
212
+ $table['Ж'] = 'Z';
213
+ $table['ж'] = 'z';
214
+ unset( $table['Й'] );
215
+ unset( $table['й'] );
216
+ unset( $table['І'] );
217
+ unset( $table['і'] );
218
+ $table['J'] = 'J';
219
+ $table['j'] = 'j';
220
+ $table['Љ'] = 'Lj';
221
+ $table['љ'] = 'lj';
222
+ $table['Њ'] = 'Nj';
223
+ $table['њ'] = 'nj';
224
+ $table['Ћ'] = 'C';
225
+ $table['ћ'] = 'c';
226
+ $table['Ц'] = 'C';
227
+ $table['ц'] = 'c';
228
+ $table['Ч'] = 'C';
229
+ $table['ч'] = 'c';
230
+ $table['Џ'] = 'Dz';
231
+ $table['џ'] = 'dz';
232
+ $table['Ш'] = 'S';
233
+ $table['ш'] = 's';
234
+ unset( $table['Щ'] );
235
+ unset( $table['щ'] );
236
+ unset( $table['Ъ'] );
237
+ unset( $table['ъ'] );
238
+ unset( $table['Ы'] );
239
+ unset( $table['ы'] );
240
+ unset( $table['Ь'] );
241
+ unset( $table['ь'] );
242
+ unset( $table['Э'] );
243
+ unset( $table['э'] );
244
+ unset( $table['Ю'] );
245
+ unset( $table['ю'] );
246
+ unset( $table['Я'] );
247
+ unset( $table['я'] );
248
+ unset( $table['Ѣ'] );
249
+ unset( $table['ѣ'] );
250
+ unset( $table['Ѳ'] );
251
+ unset( $table['ѳ'] );
252
+ unset( $table['Ѵ'] );
253
+ unset( $table['ѵ'] );
254
+ break;
255
+ // Georgian.
256
+ case 'ka_GE':
257
+ $table['ა'] = 'a';
258
+ $table['ბ'] = 'b';
259
+ $table['გ'] = 'g';
260
+ $table['დ'] = 'd';
261
+ $table['ე'] = 'e';
262
+ $table['ვ'] = 'v';
263
+ $table['ზ'] = 'z';
264
+ $table['თ'] = 'th';
265
+ $table['ი'] = 'i';
266
+ $table['კ'] = 'k';
267
+ $table['ლ'] = 'l';
268
+ $table['მ'] = 'm';
269
+ $table['ნ'] = 'n';
270
+ $table['ო'] = 'o';
271
+ $table['პ'] = 'p';
272
+ $table['ჟ'] = 'zh';
273
+ $table['რ'] = 'r';
274
+ $table['ს'] = 's';
275
+ $table['ტ'] = 't';
276
+ $table['უ'] = 'u';
277
+ $table['ფ'] = 'ph';
278
+ $table['ქ'] = 'q';
279
+ $table['ღ'] = 'gh';
280
+ $table['ყ'] = 'qh';
281
+ $table['შ'] = 'sh';
282
+ $table['ჩ'] = 'ch';
283
+ $table['ც'] = 'ts';
284
+ $table['ძ'] = 'dz';
285
+ $table['წ'] = 'ts';
286
+ $table['ჭ'] = 'tch';
287
+ $table['ხ'] = 'kh';
288
+ $table['ჯ'] = 'j';
289
+ $table['ჰ'] = 'h';
290
+ break;
291
+ // Kazakh.
292
+ case 'kk':
293
+ $table['Ә'] = 'Ae';
294
+ $table['ә'] = 'ae';
295
+ $table['Ғ'] = 'Gh';
296
+ $table['ғ'] = 'gh';
297
+ unset( $table['Ё'] );
298
+ unset( $table['ё'] );
299
+ $table['Қ'] = 'Q';
300
+ $table['қ'] = 'q';
301
+ $table['Ң'] = 'Ng';
302
+ $table['ң'] = 'ng';
303
+ $table['Ө'] = 'Oe';
304
+ $table['ө'] = 'oe';
305
+ $table['У'] = 'W';
306
+ $table['у'] = 'w';
307
+ $table['Ұ'] = 'U';
308
+ $table['ұ'] = 'u';
309
+ $table['Ү'] = 'Ue';
310
+ $table['ү'] = 'ue';
311
+ $table['Һ'] = 'H';
312
+ $table['һ'] = 'h';
313
+ $table['Ц'] = 'C';
314
+ $table['ц'] = 'c';
315
+ unset( $table['Щ'] );
316
+ unset( $table['щ'] );
317
+ unset( $table['Ъ'] );
318
+ unset( $table['ъ'] );
319
+ unset( $table['Ь'] );
320
+ unset( $table['ь'] );
321
+ unset( $table['Э'] );
322
+ unset( $table['э'] );
323
+ unset( $table['Ю'] );
324
+ unset( $table['ю'] );
325
+ unset( $table['Я'] );
326
+ unset( $table['я'] );
327
+
328
+ // Kazakh 2018 latin.
329
+ $table['Á'] = 'A';
330
+ $table['á'] = 'a';
331
+ $table['Ǵ'] = 'G';
332
+ $table['ǵ'] = 'g';
333
+ $table['I'] = 'I';
334
+ $table['ı'] = 'i';
335
+ $table['Ń'] = 'N';
336
+ $table['ń'] = 'n';
337
+ $table['Ó'] = 'O';
338
+ $table['ó'] = 'o';
339
+ $table['Ú'] = 'O';
340
+ $table['ú'] = 'o';
341
+ $table['Ý'] = 'O';
342
+ $table['ý'] = 'o';
343
+ break;
344
+ // Hebrew.
345
+ case 'he_IL':
346
+ $table = [
347
+ 'א' => '',
348
+ 'ב' => 'b',
349
+ 'ג' => 'g',
350
+ 'ד' => 'd',
351
+ 'ה' => 'h',
352
+ 'ו' => 'w',
353
+ 'ז' => 'z',
354
+ 'ח' => 'x',
355
+ 'ט' => 't',
356
+ 'י' => 'y',
357
+ 'ך' => '',
358
+ 'כ' => 'kh',
359
+ 'ל' => 'l',
360
+ 'ם' => '',
361
+ 'מ' => 'm',
362
+ 'ן' => '',
363
+ 'נ' => 'n',
364
+ 'ס' => 's',
365
+ 'ע' => '',
366
+ 'ף' => '',
367
+ 'פ' => 'ph',
368
+ 'ץ' => '',
369
+ 'צ' => 's',
370
+ 'ק' => 'k',
371
+ 'ר' => 'r',
372
+ 'ש' => 'sh',
373
+ 'ת' => 'th',
374
+ ];
375
+ for ( $code = 0x0590; $code <= 0x05CF; $code ++ ) {
376
+ $table[ Mbstring::mb_chr( $code ) ] = '';
377
+ }
378
+ for ( $code = 0x05F0; $code <= 0x05F5; $code ++ ) {
379
+ $table[ Mbstring::mb_chr( $code ) ] = '';
380
+ }
381
+ for ( $code = 0xFB1D; $code <= 0xFB4F; $code ++ ) {
382
+ $table[ Mbstring::mb_chr( $code ) ] = '';
383
+ }
384
+ break;
385
+ // phpcs:disable PSR2.ControlStructures.SwitchDeclaration.TerminatingComment
386
+ case 'zh_CN':
387
+ case 'zh_HK':
388
+ case 'zh_SG':
389
+ case 'zh_TW':
390
+ // phpcs:enable PSR2.ControlStructures.SwitchDeclaration.TerminatingComment
391
+
392
+ // Chinese dictionary copied from Pinyin Permalinks plugin.
393
+ $table = [
394
+ 'A' => '啊阿吖嗄锕',
395
+ 'Ai' => '埃挨哎唉哀皑癌蔼矮艾碍爱隘捱嗳嫒瑷暧砹锿霭',
396
+ 'An' => '鞍氨安俺按暗岸胺案谙埯揞庵桉铵鹌黯',
397
+ 'Ang' => '肮昂盎',
398
+ 'Ao' => '凹敖熬翱袄傲奥懊澳坳拗嗷岙廒遨媪骜獒聱螯鏊鳌鏖',
399
+ 'Ba' => '芭捌扒叭吧笆八疤巴拔跋靶把坝霸罢爸茇菝岜灞钯粑鲅魃',
400
+ 'Bai' => '白柏百摆佰败拜稗捭掰',
401
+ 'Ban' => '斑班搬扳般颁板版扮拌伴瓣半办绊阪坂钣瘢癍舨',
402
+ 'Bang' => '邦帮梆榜膀绑棒磅蚌镑傍谤蒡浜',
403
+ 'Bao' => '苞胞包褒薄雹保堡饱宝抱报暴豹鲍爆曝勹葆孢煲鸨褓趵龅',
404
+ 'Bei' => '杯碑悲卑北辈背贝钡倍狈备惫焙被孛陂邶蓓呗悖碚鹎褙鐾鞴',
405
+ 'Ben' => '奔苯本笨畚坌锛',
406
+ 'Beng' => '崩绷甭泵蹦迸嘣甏',
407
+ 'Bi' => '逼鼻比鄙笔彼碧蓖蔽毕毙毖币庇痹闭敝弊必壁臂避陛匕俾荜荸萆薜吡哔狴庳愎滗濞弼妣婢嬖璧贲睥畀铋秕裨筚箅篦舭襞跸髀',
408
+ 'Bian' => '鞭边编贬扁便变卞辨辩辫遍匾弁苄忭汴缏煸砭碥窆褊蝙笾鳊',
409
+ 'Biao' => '标彪膘表婊骠飑飙飚镖镳瘭裱鳔',
410
+ 'Bie' => '鳖憋别瘪蹩',
411
+ 'Bin' => '彬斌濒滨宾摈傧豳缤玢殡膑镔髌鬓',
412
+ 'Bing' => '兵冰柄丙秉饼炳病并禀邴摒槟',
413
+ 'Bo' => '剥玻菠播拨钵波博勃搏铂箔伯帛舶脖膊渤泊驳卜亳啵饽檗擘礴钹鹁簸跛踣',
414
+ 'Bu' => '捕哺补埠不布步簿部怖卟逋瓿晡钚钸醭',
415
+ 'Ca' => '擦礤',
416
+ 'Cai' => '猜裁材才财睬踩采彩菜蔡',
417
+ 'Can' => '餐参蚕残惭惨灿孱骖璨粲黪',
418
+ 'Cang' => '苍舱仓沧藏伧',
419
+ 'Cao' => '操糙槽曹草嘈漕螬艚',
420
+ 'Ce' => '厕策侧册测恻',
421
+ 'Cen' => '岑涔',
422
+ 'Ceng' => '层蹭曾噌',
423
+ 'Cha' => '插叉茬茶查碴搽察岔差诧嚓猹馇汊姹杈槎檫锸镲衩',
424
+ 'Chai' => '拆柴豺侪钗瘥虿',
425
+ 'Chan' => '搀掺蝉馋谗缠铲产阐颤冁谄蒇廛忏潺澶羼婵骣觇禅蟾躔',
426
+ 'Chang' => '昌猖场尝常长偿肠厂敞畅唱倡伥鬯苌菖徜怅阊娼嫦昶氅鲳',
427
+ 'Chao' => '超抄钞朝嘲潮巢吵炒怊晁焯耖',
428
+ 'Che' => '车扯撤掣彻澈坼砗',
429
+ 'Chen' => '郴臣辰尘晨忱沉陈趁衬谌谶抻嗔宸琛榇碜龀',
430
+ 'Cheng' => '撑称城橙成呈乘程惩澄诚承逞骋秤丞埕枨柽塍瞠铖裎蛏酲',
431
+ 'Chi' => '吃痴持池迟弛驰耻齿侈尺赤翅斥炽傺墀茌叱哧啻嗤彳饬媸敕眵鸱瘛褫蚩螭笞篪豉踟魑',
432
+ 'Chong' => '充冲虫崇宠茺忡憧铳舂艟',
433
+ 'Chou' => '抽酬畴踌稠愁筹仇绸瞅丑臭俦帱惆瘳雠',
434
+ 'Chu' => '初出橱厨躇锄雏滁除楚础储矗搐触处畜亍刍怵憷绌杵楮樗褚蜍蹰黜',
435
+ 'Chuai' => '揣搋啜膪踹',
436
+ 'Chuan' => '川穿椽传船喘串舛遄氚钏舡',
437
+ 'Chuang' => '疮窗床闯创怆',
438
+ 'Chui' => '吹炊捶锤垂陲棰槌',
439
+ 'Chun' => '春椿醇唇淳纯蠢莼鹑蝽',
440
+ 'Chuo' => '戳绰辍踔龊',
441
+ 'Ci' => '疵茨磁雌辞慈瓷词此刺赐次茈祠鹚糍',
442
+ 'Cong' => '聪葱囱匆从丛苁淙骢琮璁枞',
443
+ 'Cou' => '凑楱辏腠',
444
+ 'Cu' => '粗醋簇促蔟徂猝殂蹙蹴',
445
+ 'Cuan' => '蹿篡窜汆撺爨镩',
446
+ 'Cui' => '摧崔催脆瘁粹淬翠萃啐悴璀榱毳',
447
+ 'Cun' => '村存寸忖皴',
448
+ 'Cuo' => '磋撮搓措挫错厝嵯脞锉矬痤鹾蹉',
449
+ 'Da' => '搭达答瘩打大耷哒嗒怛妲沓褡笪靼鞑',
450
+ 'Dai' => '呆歹傣戴带殆代贷袋待逮怠埭甙呔岱迨绐玳黛',
451
+ 'Dan' => '耽担丹单郸掸胆旦氮但惮淡诞弹蛋儋凼萏菪啖澹宕殚赕眈疸瘅聃箪',
452
+ 'Dang' => '当挡党荡档谠砀铛裆',
453
+ 'Dao' => '刀捣蹈倒岛祷导到稻悼道盗叨氘焘纛',
454
+ 'De' => '德得的锝',
455
+ 'Deng' => '蹬灯登等瞪凳邓噔嶝戥磴镫簦',
456
+ 'Di' => '堤低滴迪敌笛狄涤翟嫡抵底地蒂第帝弟递缔氐籴诋谛邸坻荻嘀娣柢棣觌祗砥碲睇镝羝骶',
457
+ 'Dia' => '嗲',
458
+ 'Dian' => '颠掂滇碘点典靛垫电佃甸店惦奠淀殿丶阽坫巅玷钿癜癫簟踮',
459
+ 'Diao' => '碉叼雕凋刁掉吊钓调铞貂鲷',
460
+ 'Die' => '跌爹碟蝶迭谍叠垤堞揲喋牒瓞耋鲽',
461
+ 'Ding' => '丁盯叮钉顶鼎锭定订仃啶玎腚碇町疔耵酊',
462
+ 'Diu' => '丢铥',
463
+ 'Dong' => '东冬董懂动栋侗恫冻洞垌咚岽峒氡胨胴硐鸫',
464
+ 'Dou' => '兜抖斗陡豆逗痘都蔸钭窦蚪篼',
465
+ 'Du' => '督毒犊独读堵睹赌杜镀肚度渡妒芏嘟渎椟牍蠹笃髑黩',
466
+ 'Duan' => '端短锻段断缎椴煅簖',
467
+ 'Dui' => '堆兑队对怼憝碓镦',
468
+ 'Dun' => '墩吨蹲敦顿钝盾遁沌炖砘礅盹趸',
469
+ 'Duo' => '掇哆多夺垛躲朵跺舵剁惰堕咄哚沲缍铎裰踱',
470
+ 'E' => '蛾峨鹅俄额讹娥恶厄扼遏鄂饿噩谔垩苊莪萼呃愕屙婀轭腭锇锷鹗颚鳄',
471
+ 'Ei' => '诶',
472
+ 'En' => '恩蒽摁嗯',
473
+ 'Er' => '而儿耳尔饵洱二贰迩珥铒鸸鲕',
474
+ 'Fa' => '发罚筏伐乏阀法珐垡砝',
475
+ 'Fan' => '藩帆番翻樊矾钒繁凡烦反返范贩犯饭泛蕃蘩幡梵燔畈蹯',
476
+ 'Fang' => '坊芳方肪房防妨仿访纺放邡枋钫舫鲂',
477
+ 'Fei' => '菲非啡飞肥匪诽吠肺废沸费芾狒悱淝妃绯榧腓斐扉砩镄痱蜚篚翡霏鲱',
478
+ 'Fen' => '芬酚吩氛分纷坟焚汾粉奋份忿愤粪偾瀵棼鲼鼢',
479
+ 'Feng' => '丰封枫蜂峰锋风疯烽逢冯缝讽奉凤俸酆葑唪沣砜',
480
+ 'Fo' => '佛',
481
+ 'Fou' => '否缶',
482
+ 'Fu' => '夫敷肤孵扶拂辐幅氟符伏俘服浮涪福袱弗甫抚辅俯釜斧脯腑府腐赴副覆赋复傅付阜父腹负富讣附妇缚咐匐凫郛芙苻茯莩菔拊呋呒幞怫滏艴孚驸绂绋桴赙祓黻黼罘稃馥蚨蜉蝠蝮麸趺跗鲋鳆',
483
+ 'Ga' => '噶嘎垓尬尕尜旮钆',
484
+ 'Gai' => '该改概钙盖溉丐陔戤赅',
485
+ 'Gan' => '干甘杆柑竿肝赶感秆敢赣坩苷尴擀泔淦澉绀橄旰矸疳酐',
486
+ 'Gang' => '冈刚钢缸肛纲岗港杠戆罡筻',
487
+ 'Gao' => '篙皋高膏羔糕搞镐稿告睾诰郜藁缟槔槁杲锆',
488
+ 'Ge' => '哥歌搁戈鸽胳疙割革葛格蛤阁隔铬个各咯鬲仡哿圪塥嗝纥搿膈硌镉袼虼舸骼',
489
+ 'Gei' => '给',
490
+ 'Gen' => '根跟亘茛哏艮',
491
+ 'Geng' => '耕更庚羹埂耿梗哽赓绠鲠',
492
+ 'Gong' => '工攻功恭龚供躬公宫弓巩汞拱贡共珙肱蚣觥',
493
+ 'Gou' => '钩勾沟苟狗垢构购够佝诟岣遘媾缑枸觏彀笱篝鞲',
494
+ 'Gu' => '辜菇咕箍估沽孤姑鼓古蛊骨谷股故顾固雇嘏诂菰崮汩梏轱牯牿臌毂瞽罟钴锢鸪痼蛄酤觚鲴',
495
+ 'Gua' => '刮瓜剐寡挂褂卦诖呱栝胍鸹',
496
+ 'Guai' => '乖拐怪',
497
+ 'Guan' => '棺关官冠观管馆罐惯灌贯倌莞掼涫盥鹳鳏',
498
+ 'Guang' => '光广逛咣犷桄胱',
499
+ 'Gui' => '瑰规圭硅归龟闺轨鬼诡癸桂柜跪贵刽匦刿庋宄妫炅晷皈簋鲑鳜',
500
+ 'Gun' => '辊滚棍衮绲磙鲧',
501
+ 'Guo' => '锅郭国果裹过馘埚掴呙帼崞猓椁虢聒蜾蝈',
502
+ 'Ha' => '哈铪',
503
+ 'Hai' => '骸孩海氦亥害骇嗨胲醢',
504
+ 'Han' => '酣憨邯韩含涵寒函喊罕翰撼捍旱憾悍焊汗汉邗菡撖犴阚瀚晗焓顸颔蚶鼾',
505
+ 'Hang' => '夯杭航沆绗颃',
506
+ 'Hao' => '壕嚎豪毫郝好耗号浩蒿薅嗥嚆濠灏昊皓颢蚝',
507
+ 'He' => '呵喝荷菏核禾和何合盒貉阂河涸赫褐鹤贺诃劾壑嗬阖曷盍颌蚵翮',
508
+ 'Hei' => '嘿黑',
509
+ 'Hen' => '痕很狠恨',
510
+ 'Heng' => '哼亨横衡恒蘅珩桁',
511
+ 'Hong' => '轰哄烘虹鸿洪宏弘红黉訇讧荭蕻薨闳泓',
512
+ 'Hou' => '喉侯猴吼厚候后堠後逅瘊篌糇鲎骺',
513
+ 'Hu' => '呼乎忽瑚壶葫胡蝴狐糊湖弧虎唬护互沪户冱唿囫岵猢怙惚浒滹琥槲轷觳烀煳戽扈祜瓠鹄鹕鹱笏醐斛鹘',
514
+ 'Hua' => '花哗华猾滑画划化话骅桦砉铧',
515
+ 'Huai' => '槐徊怀淮坏踝',
516
+ 'Huan' => '欢环桓还缓换患唤痪豢焕涣宦幻奂擐獾洹浣漶寰逭缳锾鲩鬟',
517
+ 'Huang' => '荒慌黄磺蝗簧皇凰惶煌晃幌恍谎隍徨湟潢遑璜肓癀蟥篁鳇',
518
+ 'Hui' => '灰挥辉徽恢蛔回毁悔慧卉惠晦贿秽会烩汇讳诲绘诙茴荟蕙咴喙隳洄彗缋桧晖恚虺蟪麾',
519
+ 'Hun' => '荤昏婚魂浑混诨馄阍溷珲',
520
+ 'Huo' => '豁活伙火获或惑霍货祸劐藿攉嚯夥钬锪镬耠蠖',
521
+ 'Ji' => '击圾基机畸稽积箕肌饥迹激讥鸡姬绩缉吉极棘辑籍集及急疾汲即嫉级挤几脊己蓟技冀季伎祭剂悸济寄寂计记既忌际妓继纪藉亟乩剞佶偈墼芨芰荠蒺蕺掎叽咭哜唧岌嵴洎屐骥畿玑楫殛戟戢赍觊犄齑矶羁嵇稷瘠虮笈笄暨跻跽霁鲚鲫髻麂',
522
+ 'Jia' => '嘉枷夹佳家加荚颊贾甲钾假稼价架驾嫁伽郏葭岬浃迦珈戛胛恝铗镓痂瘕蛱笳袈跏',
523
+ 'Jian' => '歼监坚尖笺间煎兼肩艰奸缄茧检柬碱硷拣捡简俭剪减荐槛鉴践贱见键箭件健舰剑饯渐溅涧建僭谏谫菅蒹搛湔蹇謇缣枧楗戋戬牮犍毽腱睑锏鹣裥笕翦踺鲣鞯',
524
+ 'Jiang' => '僵姜将浆江疆蒋桨奖讲匠酱降茳洚绛缰犟礓耩糨豇',
525
+ 'Jiao' => '蕉椒礁焦胶交郊浇骄娇嚼搅铰矫侥脚狡角饺缴绞剿教酵轿较叫窖佼僬艽茭挢噍徼姣敫皎鹪蛟醮跤鲛',
526
+ 'Jie' => '揭接皆秸街阶截劫节桔杰捷睫竭洁结解姐戒芥界借介疥诫届讦诘拮喈嗟婕孑桀碣疖颉蚧羯鲒骱',
527
+ 'Jin' => '巾筋斤金今津襟紧锦仅谨进靳晋禁近烬浸尽劲卺荩堇噤馑廑妗缙瑾槿赆觐衿矜',
528
+ 'Jing' => '荆兢茎睛晶鲸京惊精粳经井警景颈静境敬镜径痉靖竟竞净刭儆阱菁獍憬泾迳弪婧肼胫腈旌箐',
529
+ 'Jiong' => '炯窘迥扃',
530
+ 'Jiu' => '揪究纠玖韭久灸九酒厩救旧臼舅咎就疚僦啾阄柩桕鸠鹫赳鬏',
531
+ 'Ju' => '鞠拘狙疽居驹菊局咀矩举沮聚拒据巨具距踞锯俱句惧炬剧倨讵苣苴莒掬遽屦琚椐榘榉橘犋飓钜锔窭裾醵踽龃雎鞫',
532
+ 'Juan' => '捐鹃娟倦眷卷绢鄄狷涓桊蠲锩镌隽',
533
+ 'Jue' => '撅攫抉掘倔爵觉决诀绝厥劂谲矍蕨噘崛獗孓珏桷橛爝镢蹶觖',
534
+ 'Jun' => '均菌钧军君峻俊竣浚郡骏捃皲',
535
+ 'Ka' => '喀咖卡佧咔胩',
536
+ 'Kai' => '开揩楷凯慨剀垲蒈忾恺铠锎锴',
537
+ 'Kan' => '刊堪勘坎砍看侃莰戡龛瞰',
538
+ 'Kang' => '康慷糠扛抗亢炕伉闶钪',
539
+ 'Kao' => '考拷烤靠尻栲犒铐',
540
+ 'Ke' => '坷苛柯棵磕颗科壳咳可渴克刻客课嗑岢恪溘骒缂珂轲氪瞌钶锞稞疴窠颏蝌髁',
541
+ 'Ken' => '肯啃垦恳裉',
542
+ 'Keng' => '坑吭铿',
543
+ 'Kong' => '空恐孔控倥崆箜',
544
+ 'Kou' => '抠口扣寇芤蔻叩囗眍筘',
545
+ 'Ku' => '枯哭窟苦酷库裤刳堀喾绔骷',
546
+ 'Kua' => '夸垮挎跨胯侉',
547
+ 'Kuai' => '块筷侩快蒯郐哙狯浍脍',
548
+ 'Kuan' => '宽款髋',
549
+ 'Kuang' => '匡筐狂框矿眶旷况诓诳邝圹夼哐纩贶',
550
+ 'Kui' => '亏盔岿窥葵奎魁傀馈愧溃馗匮夔隗蒉揆喹喟悝愦逵暌睽聩蝰篑跬',
551
+ 'Kun' => '坤昆捆困悃阃琨锟醌鲲髡',
552
+ 'Kuo' => '括扩廓阔蛞',
553
+ 'La' => '垃拉喇蜡腊辣啦剌邋旯砬瘌',
554
+ 'Lai' => '莱来赖崃徕涞濑赉睐铼癞籁',
555
+ 'Lan' => '蓝婪栏拦篮阑兰澜谰揽览懒缆烂滥岚漤榄斓罱镧褴',
556
+ 'Lang' => '琅榔狼廊郎朗浪蒗啷阆稂螂',
557
+ 'Lao' => '捞劳牢老佬姥酪烙涝唠崂忉栳铑铹痨耢醪',
558
+ 'Le' => '勒乐了仂叻泐鳓',
559
+ 'Lei' => '雷镭蕾磊累儡垒擂肋类泪羸诔嘞嫘缧檑耒酹',
560
+ 'Leng' => '棱楞冷塄愣',
561
+ 'Li' => '厘梨犁黎篱狸离漓理李里鲤礼莉荔吏栗丽厉励砾历利傈例俐痢立粒沥隶力璃哩俪俚郦坜苈莅蓠藜呖唳喱猁溧澧逦娌嫠骊缡枥栎轹膦戾砺詈罹锂鹂疠疬蛎蜊蠡笠篥粝醴跞雳鲡鳢黧',
562
+ 'Lian' => '联莲连镰廉怜涟帘敛脸链恋炼练蔹奁潋濂琏楝殓臁裢裣蠊鲢',
563
+ 'Liang' => '俩粮凉梁粱良两辆量晾亮谅墚莨椋锒踉靓魉',
564
+ 'Liao' => '撩聊僚疗燎寥辽潦撂镣廖料蓼尥嘹獠寮缭钌鹩',
565
+ 'Lie' => '列裂烈劣猎冽埒捩咧洌趔躐鬣',
566
+ 'Lin' => '琳林磷霖临邻鳞淋凛赁吝拎蔺啉嶙廪懔遴檩辚瞵粼躏麟',
567
+ 'Ling' => '玲菱零龄铃伶羚凌灵陵岭领另令酃苓呤囹泠绫柃棂瓴聆蛉翎鲮',
568
+ 'Liu' => '溜琉榴硫馏留刘瘤流柳六浏遛骝绺旒熘锍镏鹨鎏',
569
+ 'Long' => '龙聋咙笼窿隆垄拢陇垅茏泷珑栊胧砻癃',
570
+ 'Lou' => '楼娄搂篓漏陋偻蒌喽嵝镂瘘耧蝼髅',
571
+ 'Lu' => '芦卢颅庐炉掳卤虏鲁麓碌露路赂鹿潞禄录陆戮垆撸噜泸渌漉逯璐栌橹轳辂辘氇胪镥鸬鹭簏舻鲈',
572
+ 'Luan' => '峦挛孪滦卵乱脔娈栾鸾銮',
573
+ 'Lue' => '掠略锊',
574
+ 'Lun' => '抡轮伦仑沦纶论囵',
575
+ 'Luo' => '萝螺罗逻锣箩骡裸落洛骆络倮蠃荦摞猡泺漯珞椤脶镙瘰雒',
576
+ 'Lv' => '驴吕铝侣旅履屡缕虑氯律滤绿捋闾榈膂稆褛',
577
+ 'Ma' => '妈麻玛码蚂马骂嘛吗唛犸杩蟆',
578
+ 'Mai' => '埋买麦卖迈脉劢荬霾',
579
+ 'Man' => '瞒馒蛮满蔓曼慢漫谩墁幔缦熳镘颟螨鳗鞔',
580
+ 'Mang' => '芒茫盲氓忙莽邙漭硭蟒',
581
+ 'Mao' => '猫茅锚毛矛铆卯茂冒帽貌贸袤茆峁泖瑁昴牦耄旄懋瞀蝥蟊髦',
582
+ 'Me' => '么麽',
583
+ 'Mei' => '玫枚梅酶霉煤没眉媒镁每美昧寐妹媚莓嵋猸浼湄楣镅鹛袂魅',
584
+ 'Men' => '门闷们扪焖懑钔',
585
+ 'Meng' => '萌蒙檬盟锰猛梦孟勐甍瞢懵朦礞虻蜢蠓艋艨',
586
+ 'Mi' => '眯醚靡糜迷谜弥米秘觅泌蜜密幂芈谧咪嘧猕汨宓弭脒祢敉縻麋',
587
+ 'Mian' => '棉眠绵冕免勉娩缅面沔渑湎腼眄',
588
+ 'Miao' => '苗描瞄藐秒渺庙妙喵邈缈杪淼眇鹋',
589
+ 'Mie' => '蔑灭乜咩蠛篾',
590
+ 'Min' => '民抿皿敏悯闽苠岷闵泯缗玟珉愍黾鳘',
591
+ 'Ming' => '明螟鸣铭名命冥茗溟暝瞑酩',
592
+ 'Miu' => '谬缪',
593
+ 'Mo' => '摸摹蘑模膜磨摩魔抹末莫墨默沫漠寞陌谟茉蓦馍嫫嬷殁镆秣瘼耱貊貘',
594
+ 'Mou' => '谋牟某侔哞眸蛑鍪',
595
+ 'Mu' => '拇牡亩姆母墓暮幕募慕木目睦牧穆仫坶苜沐毪钼',
596
+ 'Na' => '拿哪呐钠那娜纳讷捺肭镎衲',
597
+ 'Nai' => '氖乃奶耐奈鼐佴艿萘柰',
598
+ 'Nan' => '南男难喃囝囡楠腩蝻赧',
599
+ 'Nang' => '囊攮囔馕曩',
600
+ 'Nao' => '挠脑恼闹淖孬垴呶猱瑙硇铙蛲',
601
+ 'Ne' => '呢',
602
+ 'Nei' => '馁内',
603
+ 'Nen' => '嫩恁',
604
+ 'Neng' => '能',
605
+ 'Ni' => '妮霓倪泥尼拟你匿腻逆溺伲坭蘼猊怩昵旎睨铌鲵',
606
+ 'Nian' => '蔫拈年碾撵捻念廿埝辇黏鲇鲶',
607
+ 'Niang' => '娘酿',
608
+ 'Niao' => '鸟尿茑嬲脲袅',
609
+ 'Nie' => '捏聂孽啮镊镍涅陧蘖嗫颞臬蹑',
610
+ 'Nin' => '您',
611
+ 'Ning' => '柠狞凝宁拧泞佞咛甯聍',
612
+ 'Niu' => '牛扭钮纽狃忸妞',
613
+ 'Nong' => '脓浓农弄侬哝',
614
+ 'Nou' => '耨',
615
+ 'Nu' => '奴努怒弩胬孥驽',
616
+ 'Nuan' => '暖',
617
+ 'Nue' => '虐疟挪',
618
+ 'Nuo' => '懦糯诺傩搦喏锘',
619
+ 'Nv' => '女恧钕衄',
620
+ 'O' => '哦噢',
621
+ 'Ou' => '欧鸥殴藕呕偶沤讴怄瓯耦',
622
+ 'Pa' => '耙啪趴爬帕怕琶葩杷筢',
623
+ 'Pai' => '拍排牌徘湃派俳蒎哌',
624
+ 'Pan' => '攀潘盘磐盼畔判叛拚爿泮袢襻蟠蹒',
625
+ 'Pang' => '乓庞旁耪胖彷滂逄螃',
626
+ 'Pao' => '抛咆刨炮袍跑泡匏狍庖脬疱',
627
+ 'Pei' => '呸胚培裴赔陪配佩沛辔帔旆锫醅霈',
628
+ 'Pen' => '喷盆湓',
629
+ 'Peng' => '砰抨烹澎彭蓬棚硼篷膨朋鹏捧碰堋嘭怦蟛',
630
+ 'Pi' => '辟坯砒霹批披劈琵毗啤脾疲皮匹痞僻屁譬丕仳陴邳郫圮埤鼙芘擗噼庀淠媲纰枇甓罴铍癖疋蚍蜱貔',
631
+ 'Pian' => '篇偏片骗谝骈犏胼翩蹁',
632
+ 'Piao' => '飘漂瓢票剽嘌嫖缥殍瞟螵',
633
+ 'Pie' => '撇瞥丿苤氕',
634
+ 'Pin' => '拼频贫品聘姘嫔榀牝颦',
635
+ 'Ping' => '乒坪苹萍平凭瓶评屏俜娉枰鲆',
636
+ 'Po' => '坡泼颇婆破魄迫粕叵鄱珀钋钷皤笸',
637
+ 'Pou' => '剖裒掊',
638
+ 'Pu' => '扑铺仆莆葡菩蒲埔朴圃普浦谱瀑匍噗溥濮璞氆镤镨蹼',
639
+ 'Qi' => '期欺戚妻七凄漆柒沏其棋奇歧畦崎脐齐旗祈祁骑起岂乞企启契砌器气迄弃汽泣讫亓圻芑芪萁萋葺蕲嘁屺岐汔淇骐绮琪琦杞桤槭耆祺憩碛颀蛴蜞綦鳍麒',
640
+ 'Qia' => '掐恰洽葜袷髂',
641
+ 'Qian' => '牵扦钎铅千迁签仟谦乾黔钱钳前潜遣浅谴堑嵌欠歉倩佥阡芊芡掮岍悭慊骞搴褰缱椠肷愆钤虔箝',
642
+ 'Qiang' => '枪呛腔羌墙蔷强抢戕嫱樯戗炝锖锵镪襁蜣羟跄',
643
+ 'Qiao' => '橇锹敲悄桥瞧乔侨巧鞘撬翘峭俏窍劁诮谯荞峤愀憔缲樵硗跷鞒',
644
+ 'Qie' => '切茄且怯窃郄惬妾挈锲箧趄',
645
+ 'Qin' => '钦侵亲秦琴勤芹擒禽寝沁芩揿吣嗪噙溱檎锓螓衾',
646
+ 'Qing' => '青轻氢倾卿清擎晴氰情顷请庆苘圊檠磬蜻罄綮謦鲭黥',
647
+ 'Qiong' => '琼穷邛茕穹蛩筇跫銎',
648
+ 'Qiu' => '秋丘邱球求囚酋泅俅巯犰湫逑遒楸赇虬蚯蝤裘糗鳅鼽',
649
+ 'Qu' => '趋区蛆曲躯屈驱渠取娶龋趣去诎劬蕖蘧岖衢阒璩觑氍朐祛磲鸲癯蛐蠼麴瞿黢',
650
+ 'Quan' => '圈颧权醛泉全痊拳犬券劝诠荃犭悛绻辁畎铨蜷筌鬈',
651
+ 'Que' => '缺炔瘸却鹊榷确雀阕阙悫',
652
+ 'Qun' => '裙群逡麇',
653
+ 'Ran' => '然燃冉染苒蚺髯',
654
+ 'Rang' => '瓤壤攘嚷让禳穰',
655
+ 'Rao' => '饶扰绕荛娆桡',
656
+ 'Re' => '惹热',
657
+ 'Ren' => '壬仁人忍韧任认刃妊纫仞荏饪轫稔衽',
658
+ 'Reng' => '扔仍',
659
+ 'Ri' => '日',
660
+ 'Rong' => '戎茸蓉荣融熔溶容绒冗嵘狨榕肜蝾',
661
+ 'Rou' => '揉柔肉糅蹂鞣',
662
+ 'Ru' => '茹蠕儒孺如辱乳汝入褥蓐薷嚅洳溽濡缛铷襦颥',
663
+ 'Ruan' => '软阮朊',
664
+ 'Rui' => '蕊瑞锐芮蕤枘睿蚋',
665
+ 'Run' => '闰润',
666
+ 'Ruo' => '若弱偌箬',
667
+ 'Sa' => '撒洒萨卅挲脎飒',
668
+ 'Sai' => '腮鳃塞赛噻',
669
+ 'San' => '三叁伞散仨彡馓毵',
670
+ 'Sang' => '桑嗓丧搡磉颡',
671
+ 'Sao' => '搔骚扫嫂埽缫臊瘙鳋',
672
+ 'Se' => '瑟色涩啬铯穑',
673
+ 'Sen' => '森',
674
+ 'Seng' => '僧',
675
+ 'Sha' => '莎砂杀刹沙纱傻啥煞唼歃铩痧裟霎鲨',
676
+ 'Shai' => '筛晒酾',
677
+ 'Shan' => '珊苫杉山删煽衫闪陕擅赡膳善汕扇缮栅讪鄯芟潸姗嬗骟膻钐疝蟮舢跚鳝',
678
+ 'Shang' => '墒伤商赏晌上尚裳垧绱殇熵觞',
679
+ 'Shao' => '梢捎稍烧芍勺韶少哨邵绍劭潲杓蛸筲艄',
680
+ 'She' => '奢赊蛇舌舍赦摄射慑涉社设厍佘猞滠畲麝',
681
+ 'Shen' => '砷申呻伸身深娠绅神沈审婶甚肾慎渗什诜谂莘葚哂渖胂矧蜃糁',
682
+ 'Sheng' => '声生甥牲升绳省盛剩胜圣嵊晟眚笙',
683
+ 'Shi' => '匙师失狮施湿诗尸虱十石拾时食蚀实识史矢使屎驶始式示士世柿事拭誓逝势是嗜噬适仕侍释饰氏市恃室视试谥埘莳蓍弑轼贳炻礻铈舐筮豕鲥鲺',
684
+ 'Shou' => '收手首守寿授售受瘦兽狩绶艏',
685
+ 'Shu' => '蔬枢梳殊抒输叔舒淑疏书赎孰熟薯暑曙署蜀黍鼠属术述树束戍竖墅庶数漱恕丨倏塾菽摅沭澍姝纾毹腧殳秫',
686
+ 'Shua' => '刷耍唰',
687
+ 'Shuai' => '率摔衰甩帅蟀',
688
+ 'Shuan' => '栓拴闩涮',
689
+ 'Shuang' => '霜双爽孀',
690
+ 'Shui' => '谁水睡税',
691
+ 'Shun' => '吮瞬顺舜',
692
+ 'Shuo' => '说硕朔烁蒴搠妁槊铄',
693
+ 'Si' => '斯撕嘶思私司丝死肆寺嗣四伺似饲巳厮俟兕厶咝汜泗澌姒驷缌祀锶鸶耜蛳笥',
694
+ 'Song' => '松耸怂颂送宋讼诵凇菘崧嵩忪悚淞竦',
695
+ 'Sou' => '搜艘擞嗽叟薮嗖嗾馊溲飕瞍锼螋',
696
+ 'Su' => '苏酥俗素速粟僳塑溯宿诉肃夙谡蔌嗉愫涑簌觫稣',
697
+ 'Suan' => '酸蒜算狻',
698
+ 'Sui' => '虽隋随绥髓碎岁穗遂隧祟谇荽濉邃燧眭睢',
699
+ 'Sun' => '孙损笋荪狲飧榫隼',
700
+ 'Suo' => '蓑梭唆缩琐索锁所唢嗦嗍娑桫睃羧',
701
+ 'Ta' => '塌他它她塔獭挞蹋踏闼溻遢榻铊趿鳎',
702
+ 'Tai' => '胎苔抬台泰酞太态汰邰薹骀肽炱钛跆鲐',
703
+ 'Tan' => '坍摊贪瘫滩坛檀痰潭谭谈坦毯袒碳探叹炭郯昙忐钽锬覃',
704
+ 'Tang' => '汤塘搪堂棠膛唐糖倘躺淌趟烫傥帑惝溏瑭樘铴镗耥螗螳羰醣',
705
+ 'Tao' => '掏涛滔绦萄桃逃淘陶讨套鼗啕洮韬饕',
706
+ 'Te' => '特忒忑慝铽',
707
+ 'Teng' => '藤腾疼誊滕',
708
+ 'Ti' => '梯剔踢锑提题蹄啼体替嚏惕涕剃屉倜悌逖绨缇鹈醍',
709
+ 'Tian' => '天添填田甜恬舔腆掭忝阗殄畋',
710
+ 'Tiao' => '挑条迢眺跳佻苕祧窕蜩笤粜龆鲦髫',
711
+ 'Tie' => '贴铁帖萜餮',
712
+ 'Ting' => '厅听烃汀廷停亭庭挺艇莛葶婷梃铤蜓霆',
713
+ 'Tong' => '通桐酮瞳同铜彤童桶捅筒统痛佟仝茼嗵恸潼砼',
714
+ 'Tou' => '偷投头透骰',
715
+ 'Tu' => '凸秃突图徒途涂屠土吐兔堍荼菟钍酴',
716
+ 'Tuan' => '湍团抟彖疃',
717
+ 'Tui' => '推颓腿蜕褪退煺',
718
+ 'Tun' => '囤吞屯臀氽饨暾豚',
719
+ 'Tuo' => '拖托脱鸵陀驮驼椭妥拓唾佗坨庹沱柝柁橐砣箨酡跎鼍',
720
+ 'Wa' => '挖哇蛙洼娃瓦袜佤娲腽',
721
+ 'Wai' => '歪外崴',
722
+ 'Wan' => '豌弯湾玩顽丸烷完碗挽晚皖惋宛婉万腕剜芄菀纨绾琬脘畹蜿',
723
+ 'Wang' => '汪王亡枉网往旺望忘妄罔惘辋魍',
724
+ 'Wei' => '威巍微危韦违桅围唯惟为潍维苇萎委伟伪尾纬未蔚味畏胃喂魏位渭谓尉慰卫偎诿隈圩葳薇帏帷嵬猥猬闱沩洧涠逶娓玮韪軎炜煨痿艉鲔',
725
+ 'Wen' => '瘟温蚊文闻纹吻稳紊问刎夂阌汶璺攵雯',
726
+ 'Weng' => '嗡翁瓮蓊蕹',
727
+ 'Wo' => '挝蜗涡窝我斡卧握沃倭莴喔幄渥肟硪龌',
728
+ 'Wu' => '巫呜钨乌污诬屋无芜梧吾吴毋武五捂午舞伍侮坞戊雾晤物勿务悟误兀仵阢邬圬芴唔庑怃忤寤迕妩婺骛杌牾焐鹉鹜痦蜈鋈鼯',
729
+ 'Xi' => '栖昔熙析西硒矽晰嘻吸锡牺稀息希悉膝夕惜熄烯溪汐犀檄袭席习媳喜铣洗系隙戏细僖兮隰郗茜菥葸蓰奚唏徙饩阋浠淅屣嬉玺樨曦觋欷歙熹禊禧皙穸裼蜥螅蟋舄舾羲粞翕醯蹊鼷',
730
+ 'Xia' => '瞎虾匣霞辖暇峡侠狭下厦夏吓呷狎遐瑕柙硖罅黠',
731
+ 'Xian' => '掀锨先仙鲜纤咸贤衔舷闲涎弦嫌显险现献县腺馅羡宪陷限线冼苋莶藓岘猃暹娴氙燹祆鹇痫蚬筅籼酰跣跹霰',
732
+ 'Xiang' => '相厢镶香箱襄湘乡翔祥详想响享项巷橡像向象芗葙饷庠骧缃蟓鲞飨',
733
+ 'Xiao' => '萧硝霄削哮嚣销消宵淆晓小孝校肖啸笑效哓崤潇逍骁绡枭枵筱箫魈',
734
+ 'Xie' => '楔些歇蝎鞋协挟携邪斜胁谐写械卸蟹懈泄泻谢屑偕亵勰燮薤撷獬廨渫瀣邂绁缬榭榍蹀躞',
735
+ 'Xin' => '薪芯锌欣辛新忻心信衅囟馨昕歆镡鑫',
736
+ 'Xing' => '星腥猩惺兴刑型形邢行醒幸杏性姓陉荇荥擤饧悻硎',
737
+ 'Xiong' => '兄凶胸匈汹雄熊芎',
738
+ 'Xiu' => '休修羞朽嗅锈秀袖绣咻岫馐庥溴鸺貅髹',
739
+ 'Xu' => '墟戌需虚嘘须徐许蓄酗叙旭序恤絮婿绪续吁诩勖蓿洫溆顼栩煦盱胥糈醑',
740
+ 'Xuan' => '轩喧宣悬旋玄选癣眩绚儇谖萱揎泫渲漩璇楦暄炫煊碹铉镟痃',
741
+ 'Xue' => '靴薛学穴雪血谑噱泶踅鳕',
742
+ 'Xun' => '勋熏循旬询寻驯巡殉汛训讯逊迅巽郇埙荀荨蕈薰峋徇獯恂洵浔曛醺鲟',
743
+ 'Ya' => '压押鸦鸭呀丫芽牙蚜崖衙涯雅哑亚讶伢垭揠岈迓娅琊桠氩砑睚痖',
744
+ 'Yan' => '焉咽阉烟淹盐严研蜒岩延言颜阎炎沿奄掩眼衍演艳堰燕厌砚雁唁彦焰宴谚验厣赝剡俨偃兖谳郾鄢埏菸崦恹闫阏湮滟妍嫣琰檐晏胭腌焱罨筵酽趼魇餍鼹',
745
+ 'Yang' => '殃央鸯秧杨扬佯疡羊洋阳氧仰痒养样漾徉怏泱炀烊恙蛘鞅',
746
+ 'Yao' => '邀腰妖瑶摇尧遥窑谣姚咬舀药要耀钥夭爻吆崾徭幺珧杳轺曜肴铫鹞窈繇鳐',
747
+ 'Ye' => '椰噎耶爷野冶也页掖业叶曳腋夜液靥谒邺揶晔烨铘',
748
+ 'Yi' => '一壹医揖铱依伊衣颐夷遗移仪胰疑沂宜姨彝椅蚁倚已乙矣以艺抑易邑屹亿役臆逸肄疫亦裔意毅忆义益溢诣议谊译异翼翌绎刈劓佚佾诒圯埸懿苡荑薏弈奕挹弋呓咦咿嗌噫峄嶷猗饴怿怡悒漪迤驿缢殪轶贻欹旖熠眙钇镒镱痍瘗癔翊蜴舣羿翳酏黟',
749
+ 'Yin' => '茵荫因殷音阴姻吟银淫寅饮尹引隐印胤鄞垠堙茚吲喑狺夤洇氤铟瘾窨蚓霪龈',
750
+ 'Ying' => '英樱婴鹰应缨莹萤营荧蝇迎赢盈影颖硬映嬴郢茔莺萦蓥撄嘤膺滢潆瀛瑛璎楹媵鹦瘿颍罂',
751
+ 'Yo' => '哟唷',
752
+ 'Yong' => '拥佣臃痈庸雍踊蛹咏泳涌永恿勇用俑壅墉喁慵邕镛甬鳙饔',
753
+ 'You' => '幽优悠忧尤由邮铀犹油游酉有友右佑釉诱又幼卣攸侑莠莜莸尢呦囿宥柚猷牖铕疣蚰蚴蝣鱿黝鼬',
754
+ 'Yu' => '迂淤于盂榆虞愚舆余俞逾鱼愉渝渔隅予娱雨与屿禹宇语羽玉域芋郁遇喻峪御愈欲狱育誉浴寓裕预豫驭禺毓伛俣谀谕萸蓣揄圄圉嵛狳饫馀庾阈鬻妪妤纡瑜昱觎腴欤於煜燠聿钰鹆鹬瘐瘀窬窳蜮蝓竽臾舁雩龉',
755
+ 'Yuan' => '鸳渊冤元垣袁原援辕园员圆猿源缘远苑愿怨院垸塬芫掾圜沅媛瑗橼爰眢鸢螈箢鼋',
756
+ 'Yue' => '曰约越跃岳粤月悦阅龠哕瀹樾刖钺',
757
+ 'Yun' => '耘云郧匀陨允运蕴酝晕韵孕郓芸狁恽愠纭韫殒昀氲熨筠',
758
+ 'Za' => '匝砸杂咋拶咂',
759
+ 'Zai' => '栽哉灾宰载再在崽甾',
760
+ 'Zan' => '咱攒暂赞瓒昝簪糌趱錾',
761
+ 'Zang' => '赃脏葬奘驵臧',
762
+ 'Zao' => '遭糟凿藻枣早澡蚤躁噪造皂灶燥唣',
763
+ 'Ze' => '责择则泽仄赜啧帻迮昃笮箦舴',
764
+ 'Zei' => '贼',
765
+ 'Zen' => '怎谮',
766
+ 'Zeng' => '增憎赠缯甑罾锃',
767
+ 'Zha' => '扎喳渣札轧铡闸眨榨乍炸诈柞揸吒咤哳楂砟痄蚱齄',
768
+ 'Zhai' => '摘斋宅窄债寨砦瘵',
769
+ 'Zhan' => '瞻毡詹粘沾盏斩辗崭展蘸栈占战站湛绽谵搌旃',
770
+ 'Zhang' => '樟章彰漳张掌涨杖丈帐账仗胀瘴障仉鄣幛嶂獐嫜璋蟑',
771
+ 'Zhao' => '招昭找沼赵照罩兆肇召诏棹钊笊',
772
+ 'Zhe' => '遮折哲蛰辙者锗蔗这浙着乇谪摺柘辄磔鹧褶蜇螫赭',
773
+ 'Zhen' => '珍斟真甄砧臻贞针侦枕疹诊震振镇阵帧圳蓁浈缜桢椹榛轸赈胗朕祯畛稹鸩箴',
774
+ 'Zheng' => '蒸挣睁征狰争怔整拯正政症郑证诤峥徵钲铮筝',
775
+ 'Zhi' => '芝枝支吱蜘知肢脂汁之织职直植殖执值侄址指止趾只旨纸志挚掷至致置帜峙制智秩稚质炙痔滞治窒卮陟郅埴芷摭帙忮彘咫骘栉枳栀桎轵轾贽胝膣祉黹雉鸷痣蛭絷酯跖踬踯豸觯',
776
+ 'Zhong' => '中盅忠钟衷终种肿重仲众冢锺螽舯踵',
777
+ 'Zhou' => '舟周州洲诌粥轴肘帚咒皱宙昼骤荮啁妯纣绉胄碡籀酎',
778
+ 'Zhu' => '珠株蛛朱猪诸诛逐竹烛煮拄瞩嘱主著柱助蛀贮铸筑住注祝驻伫侏邾苎茱洙渚潴杼槠橥炷铢疰瘃竺箸舳翥躅麈',
779
+ 'Zhua' => '抓爪',
780
+ 'Zhuai' => '拽',
781
+ 'Zhuan' => '专砖转撰赚篆啭馔颛',
782
+ 'Zhuang' => '幢桩庄装妆撞壮状僮',
783
+ 'Zhui' => '椎锥追赘坠缀萑惴骓缒隹',
784
+ 'Zhun' => '谆准肫窀',
785
+ 'Zhuo' => '捉拙卓桌琢茁酌啄灼浊倬诼擢浞涿濯禚斫镯',
786
+ 'Zi' => '兹咨资姿滋淄孜紫仔籽滓子自渍字谘呲嵫姊孳缁梓辎赀恣眦锱秭耔笫粢趑訾龇鲻髭',
787
+ 'Zong' => '鬃棕踪宗综总纵偬腙粽',
788
+ 'Zou' => '邹走奏揍诹陬鄹驺鲰',
789
+ 'Zu' => '租足卒族祖诅阻组俎菹镞',
790
+ 'Zuan' => '钻纂攥缵躜',
791
+ 'Zui' => '嘴醉最罪蕞觜',
792
+ 'Zun' => '尊遵撙樽鳟',
793
+ 'Zuo' => '昨左佐做作坐座阼唑嘬怍胙祚酢',
794
+ ];
795
+ default:
796
+ }
797
+
798
+ return $table;
799
+ }
800
+
801
+ /**
802
+ * Get fix table for MacOS.
803
+ * On MacOS, files containing characters in the table, are sometimes encoded improperly.
804
+ *
805
+ * @return array
806
+ */
807
+ public static function get_fix_table_for_mac() {
808
+ /**
809
+ * Keys in the table are standard ISO9 characters.
810
+ *
811
+ * Example of wrong encoding on Mac:
812
+ * берЁзовыЙ-белозёрский - original input,
813
+ * берЁзовыЙ-белозёрский.png - actual filename created on Mac (ЁёЙй are already wrongly encoded),
814
+ * ber%d0%95%cc%88zovy%d0%98%cc%86-beloz%d0%B5%cc%88rski%d0%B8%cc%86.png - urlencode() of the above,
815
+ * berËzovyĬ-belozërskiĭ.png - actual filename passed via standard ISO9 transliteration table,
816
+ * berE%CC%88zovyI%CC%86-beloze%CC%88rskii%CC%86.png - urlencode() of the above.
817
+ *
818
+ * To avoid misunderstanding, we use urldecode() here.
819
+ */
820
+ return [
821
+ 'Ё' => urldecode( '%d0%95%cc%88' ),
822
+ 'ё' => urldecode( '%d0%B5%cc%88' ),
823
+ 'Й' => urldecode( '%d0%98%cc%86' ),
824
+ 'й' => urldecode( '%d0%B8%cc%86' ),
825
+ ];
826
+ }
827
+ }
includes/class-cyr-to-lat-converter.php → classes/class-converter.php RENAMED
@@ -5,12 +5,14 @@
5
  * @package cyr-to-lat
6
  */
7
 
 
 
8
  /**
9
- * Class Cyr_To_Lat_Converter
10
  *
11
- * @class Cyr_To_Lat_Converter
12
  */
13
- class Cyr_To_Lat_Converter {
14
 
15
  /**
16
  * Query arg in url to start conversion.
@@ -20,35 +22,35 @@ class Cyr_To_Lat_Converter {
20
  /**
21
  * Plugin main class.
22
  *
23
- * @var Cyr_To_Lat_Main
24
  */
25
  private $main;
26
 
27
  /**
28
  * Plugin settings.
29
  *
30
- * @var Cyr_To_Lat_Settings
31
  */
32
  private $settings;
33
 
34
  /**
35
  * Background process to convert posts.
36
  *
37
- * @var Cyr_To_Lat_Post_Conversion_Process
38
  */
39
  private $process_all_posts;
40
 
41
  /**
42
  * Background process to convert terms.
43
  *
44
- * @var Cyr_To_Lat_Term_Conversion_Process
45
  */
46
  private $process_all_terms;
47
 
48
  /**
49
  * Admin notices.
50
  *
51
- * @var Cyr_To_Lat_Admin_Notices
52
  */
53
  private $admin_notices;
54
 
@@ -60,34 +62,34 @@ class Cyr_To_Lat_Converter {
60
  private $option_group = '';
61
 
62
  /**
63
- * Cyr_To_Lat_Converter constructor.
64
  *
65
- * @param Cyr_To_Lat_Main $main Plugin main class.
66
- * @param Cyr_To_Lat_Settings $settings Plugin settings.
67
- * @param Cyr_To_Lat_Post_Conversion_Process $process_all_posts Plugin settings.
68
- * @param Cyr_To_Lat_Term_Conversion_Process $process_all_terms Plugin settings.
69
- * @param Cyr_To_Lat_Admin_Notices $admin_notices Plugin settings.
70
  */
71
  public function __construct(
72
  $main, $settings, $process_all_posts = null, $process_all_terms = null, $admin_notices = null
73
  ) {
74
  $this->main = $main;
75
  $this->settings = $settings;
76
- $this->option_group = Cyr_To_Lat_Settings::OPTION_GROUP;
77
 
78
  $this->process_all_posts = $process_all_posts;
79
  if ( ! $this->process_all_posts ) {
80
- $this->process_all_posts = new Cyr_To_Lat_Post_Conversion_Process( $main );
81
  }
82
 
83
  $this->process_all_terms = $process_all_terms;
84
  if ( ! $this->process_all_terms ) {
85
- $this->process_all_terms = new Cyr_To_Lat_Term_Conversion_Process( $main );
86
  }
87
 
88
  $this->admin_notices = $admin_notices;
89
  if ( ! $this->admin_notices ) {
90
- $this->admin_notices = new Cyr_To_Lat_Admin_Notices();
91
  }
92
 
93
  $this->init_hooks();
@@ -97,8 +99,8 @@ class Cyr_To_Lat_Converter {
97
  * Init class hooks.
98
  */
99
  public function init_hooks() {
100
- add_action( 'admin_init', array( $this, 'process_handler' ) );
101
- add_action( 'admin_init', array( $this, 'conversion_notices' ) );
102
  }
103
 
104
  /**
@@ -109,7 +111,7 @@ class Cyr_To_Lat_Converter {
109
  $terms_process_running = $this->process_all_terms->is_process_running();
110
 
111
  if ( ! $posts_process_running && ! $terms_process_running ) {
112
- add_action( 'admin_init', array( $this, 'start_conversion' ), 20 );
113
  }
114
 
115
  if ( $posts_process_running ) {
@@ -172,15 +174,15 @@ class Cyr_To_Lat_Converter {
172
  *
173
  * @param array $args Arguments for query.
174
  */
175
- public function convert_existing_slugs( $args = array() ) {
176
  global $wpdb;
177
 
178
- $regexp = Cyr_To_Lat_Main::PROHIBITED_CHARS_REGEX . '+';
179
 
180
- $defaults = array(
181
  'post_type' => get_post_types(),
182
- 'post_status' => array( 'publish', 'future', 'private' ),
183
- );
184
 
185
  $args = wp_parse_args( $args, $defaults );
186
 
5
  * @package cyr-to-lat
6
  */
7
 
8
+ namespace Cyr_To_Lat;
9
+
10
  /**
11
+ * Class Converter
12
  *
13
+ * @class Converter
14
  */
15
+ class Converter {
16
 
17
  /**
18
  * Query arg in url to start conversion.
22
  /**
23
  * Plugin main class.
24
  *
25
+ * @var Main
26
  */
27
  private $main;
28
 
29
  /**
30
  * Plugin settings.
31
  *
32
+ * @var Settings
33
  */
34
  private $settings;
35
 
36
  /**
37
  * Background process to convert posts.
38
  *
39
+ * @var Post_Conversion_Process
40
  */
41
  private $process_all_posts;
42
 
43
  /**
44
  * Background process to convert terms.
45
  *
46
+ * @var Term_Conversion_Process
47
  */
48
  private $process_all_terms;
49
 
50
  /**
51
  * Admin notices.
52
  *
53
+ * @var Admin_Notices
54
  */
55
  private $admin_notices;
56
 
62
  private $option_group = '';
63
 
64
  /**
65
+ * Converter constructor.
66
  *
67
+ * @param Main $main Plugin main class.
68
+ * @param Settings $settings Plugin settings.
69
+ * @param Post_Conversion_Process $process_all_posts Plugin settings.
70
+ * @param Term_Conversion_Process $process_all_terms Plugin settings.
71
+ * @param Admin_Notices $admin_notices Plugin settings.
72
  */
73
  public function __construct(
74
  $main, $settings, $process_all_posts = null, $process_all_terms = null, $admin_notices = null
75
  ) {
76
  $this->main = $main;
77
  $this->settings = $settings;
78
+ $this->option_group = Settings::OPTION_GROUP;
79
 
80
  $this->process_all_posts = $process_all_posts;
81
  if ( ! $this->process_all_posts ) {
82
+ $this->process_all_posts = new Post_Conversion_Process( $main );
83
  }
84
 
85
  $this->process_all_terms = $process_all_terms;
86
  if ( ! $this->process_all_terms ) {
87
+ $this->process_all_terms = new Term_Conversion_Process( $main );
88
  }
89
 
90
  $this->admin_notices = $admin_notices;
91
  if ( ! $this->admin_notices ) {
92
+ $this->admin_notices = new Admin_Notices();
93
  }
94
 
95
  $this->init_hooks();
99
  * Init class hooks.
100
  */
101
  public function init_hooks() {
102
+ add_action( 'admin_init', [ $this, 'process_handler' ] );
103
+ add_action( 'admin_init', [ $this, 'conversion_notices' ] );
104
  }
105
 
106
  /**
111
  $terms_process_running = $this->process_all_terms->is_process_running();
112
 
113
  if ( ! $posts_process_running && ! $terms_process_running ) {
114
+ add_action( 'admin_init', [ $this, 'start_conversion' ], 20 );
115
  }
116
 
117
  if ( $posts_process_running ) {
174
  *
175
  * @param array $args Arguments for query.
176
  */
177
+ public function convert_existing_slugs( $args = [] ) {
178
  global $wpdb;
179
 
180
+ $regexp = Main::PROHIBITED_CHARS_REGEX . '+';
181
 
182
+ $defaults = [
183
  'post_type' => get_post_types(),
184
+ 'post_status' => [ 'publish', 'future', 'private' ],
185
+ ];
186
 
187
  $args = wp_parse_args( $args, $defaults );
188
 
includes/class-cyr-to-lat-main.php → classes/class-main.php RENAMED
@@ -5,12 +5,16 @@
5
  * @package cyr-to-lat
6
  */
7
 
 
 
 
 
8
  use Cyr_To_Lat\Symfony\Polyfill\Mbstring\Mbstring;
9
 
10
  /**
11
- * Class Cyr_To_Lat_Main
12
  */
13
- class Cyr_To_Lat_Main {
14
 
15
  /**
16
  * Regex of prohibited chars in slugs
@@ -23,60 +27,60 @@ class Cyr_To_Lat_Main {
23
  /**
24
  * Plugin settings.
25
  *
26
- * @var Cyr_To_Lat_Settings
27
  */
28
- private $settings;
29
 
30
  /**
31
  * Converter instance.
32
  *
33
- * @var Cyr_To_Lat_Converter
34
  */
35
- private $converter;
36
 
37
  /**
38
- * Cyr_To_Lat_WP_CLI instance.
39
  *
40
- * @var Cyr_To_Lat_WP_CLI
41
  */
42
- private $cli;
43
 
44
  /**
45
- * Cyr_To_Lat_ACF instance.
46
  *
47
- * @var Cyr_To_Lat_ACF
48
  */
49
- private $acf;
50
 
51
  /**
52
- * Cyr_To_Lat_Main constructor.
53
  *
54
- * @param Cyr_To_Lat_Settings $settings Plugin settings.
55
- * @param Cyr_To_Lat_Converter $converter Converter instance.
56
- * @param Cyr_To_Lat_WP_CLI $cli CLI instance.
57
- * @param Cyr_To_Lat_ACF $acf ACF instance.
58
  */
59
  public function __construct( $settings = null, $converter = null, $cli = null, $acf = null ) {
60
  $this->settings = $settings;
61
  if ( ! $this->settings ) {
62
- $this->settings = new Cyr_To_Lat_Settings();
63
  }
64
 
65
  $this->converter = $converter;
66
  if ( ! $this->converter ) {
67
- $this->converter = new Cyr_To_Lat_Converter( $this, $this->settings );
68
  }
69
 
70
  $this->cli = $cli;
71
  if ( defined( 'WP_CLI' ) && WP_CLI ) {
72
  if ( ! $this->cli ) {
73
- $this->cli = new Cyr_To_Lat_WP_CLI( $this->converter );
74
  }
75
  }
76
 
77
  $this->acf = $acf;
78
  if ( ! $this->acf ) {
79
- $this->acf = new Cyr_To_Lat_ACF( $this->settings );
80
  }
81
 
82
  $this->init();
@@ -93,7 +97,7 @@ class Cyr_To_Lat_Main {
93
  *
94
  * @noinspection PhpParamsInspection
95
  */
96
- WP_CLI::add_command( 'cyr2lat', $this->cli );
97
  } catch ( Exception $e ) {
98
  return;
99
  }
@@ -106,9 +110,9 @@ class Cyr_To_Lat_Main {
106
  * Init class hooks.
107
  */
108
  public function init_hooks() {
109
- add_filter( 'sanitize_title', array( $this, 'ctl_sanitize_title' ), 9, 3 );
110
- add_filter( 'sanitize_file_name', array( $this, 'ctl_sanitize_filename' ), 10, 2 );
111
- add_filter( 'wp_insert_post_data', array( $this, 'ctl_sanitize_post_name' ), 10, 2 );
112
  }
113
 
114
  /**
@@ -141,7 +145,7 @@ class Cyr_To_Lat_Main {
141
 
142
  $is_term = false;
143
  // phpcs:disable WordPress.PHP.DevelopmentFunctions.error_log_debug_backtrace
144
- $backtrace = debug_backtrace( ~ DEBUG_BACKTRACE_PROVIDE_OBJECT | DEBUG_BACKTRACE_IGNORE_ARGS );
145
  // phpcs:enable
146
  foreach ( $backtrace as $backtrace_entry ) {
147
  if ( 'wp_insert_term' === $backtrace_entry['function'] ) {
@@ -179,11 +183,7 @@ class Cyr_To_Lat_Main {
179
  }
180
 
181
  if ( seems_utf8( $filename ) ) {
182
- if ( function_exists( 'mb_strtolower' ) ) {
183
- $filename = mb_strtolower( $filename, 'UTF-8' );
184
- } else {
185
- $filename = Mbstring::mb_strtolower( $filename );
186
- }
187
  }
188
 
189
  return $this->transliterate( $filename );
@@ -198,7 +198,7 @@ class Cyr_To_Lat_Main {
198
  */
199
  private function fix_mac_string( $string ) {
200
  $table = $this->get_filtered_table();
201
- $fix_table = Cyr_To_Lat_Conversion_Tables::get_fix_table_for_mac();
202
 
203
  $fix = [];
204
  foreach ( $fix_table as $key => $value ) {
@@ -210,6 +210,33 @@ class Cyr_To_Lat_Main {
210
  return strtr( $string, $fix );
211
  }
212
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
213
  /**
214
  * Get transliteration table.
215
  *
@@ -230,6 +257,7 @@ class Cyr_To_Lat_Main {
230
  $table = $this->get_filtered_table();
231
 
232
  $string = $this->fix_mac_string( $string );
 
233
  $string = strtr( $string, $table );
234
 
235
  if ( function_exists( 'iconv' ) ) {
@@ -250,6 +278,11 @@ class Cyr_To_Lat_Main {
250
  private function ctl_is_classic_editor_plugin_active() {
251
  if ( ! function_exists( 'is_plugin_active' ) ) {
252
  // @codeCoverageIgnoreStart
 
 
 
 
 
253
  include_once ABSPATH . 'wp-admin/includes/plugin.php';
254
  // @codeCoverageIgnoreEnd
255
  }
@@ -279,7 +312,7 @@ class Cyr_To_Lat_Main {
279
 
280
  if ( $this->ctl_is_classic_editor_plugin_active() ) {
281
  $editor_option = get_option( 'classic-editor-replace' );
282
- $block_editor_active = array( 'no-replace', 'block' );
283
 
284
  return in_array( $editor_option, $block_editor_active, true );
285
  }
@@ -295,7 +328,7 @@ class Cyr_To_Lat_Main {
295
  *
296
  * @return mixed
297
  */
298
- public function ctl_sanitize_post_name( $data, $postarr = array() ) {
299
  global $current_screen;
300
 
301
  if ( ! $this->ctl_is_gutenberg_editor_active() ) {
@@ -309,7 +342,7 @@ class Cyr_To_Lat_Main {
309
 
310
  if (
311
  ! $data['post_name'] && $data['post_title'] &&
312
- ! in_array( $data['post_status'], array( 'auto-draft', 'revision' ), true )
313
  ) {
314
  $data['post_name'] = sanitize_title( $data['post_title'] );
315
  }
5
  * @package cyr-to-lat
6
  */
7
 
8
+ namespace Cyr_To_Lat;
9
+
10
+ use wpdb;
11
+ use Exception;
12
  use Cyr_To_Lat\Symfony\Polyfill\Mbstring\Mbstring;
13
 
14
  /**
15
+ * Class Main
16
  */
17
+ class Main {
18
 
19
  /**
20
  * Regex of prohibited chars in slugs
27
  /**
28
  * Plugin settings.
29
  *
30
+ * @var Settings
31
  */
32
+ protected $settings;
33
 
34
  /**
35
  * Converter instance.
36
  *
37
+ * @var Converter
38
  */
39
+ protected $converter;
40
 
41
  /**
42
+ * WP_CLI instance.
43
  *
44
+ * @var WP_CLI
45
  */
46
+ protected $cli;
47
 
48
  /**
49
+ * ACF instance.
50
  *
51
+ * @var ACF
52
  */
53
+ protected $acf;
54
 
55
  /**
56
+ * Main constructor.
57
  *
58
+ * @param Settings $settings Plugin settings.
59
+ * @param Converter $converter Converter instance.
60
+ * @param WP_CLI $cli CLI instance.
61
+ * @param ACF $acf ACF instance.
62
  */
63
  public function __construct( $settings = null, $converter = null, $cli = null, $acf = null ) {
64
  $this->settings = $settings;
65
  if ( ! $this->settings ) {
66
+ $this->settings = new Settings();
67
  }
68
 
69
  $this->converter = $converter;
70
  if ( ! $this->converter ) {
71
+ $this->converter = new Converter( $this, $this->settings );
72
  }
73
 
74
  $this->cli = $cli;
75
  if ( defined( 'WP_CLI' ) && WP_CLI ) {
76
  if ( ! $this->cli ) {
77
+ $this->cli = new WP_CLI( $this->converter );
78
  }
79
  }
80
 
81
  $this->acf = $acf;
82
  if ( ! $this->acf ) {
83
+ $this->acf = new ACF( $this->settings );
84
  }
85
 
86
  $this->init();
97
  *
98
  * @noinspection PhpParamsInspection
99
  */
100
+ \WP_CLI::add_command( 'cyr2lat', $this->cli );
101
  } catch ( Exception $e ) {
102
  return;
103
  }
110
  * Init class hooks.
111
  */
112
  public function init_hooks() {
113
+ add_filter( 'sanitize_title', [ $this, 'ctl_sanitize_title' ], 9, 3 );
114
+ add_filter( 'sanitize_file_name', [ $this, 'ctl_sanitize_filename' ], 10, 2 );
115
+ add_filter( 'wp_insert_post_data', [ $this, 'ctl_sanitize_post_name' ], 10, 2 );
116
  }
117
 
118
  /**
145
 
146
  $is_term = false;
147
  // phpcs:disable WordPress.PHP.DevelopmentFunctions.error_log_debug_backtrace
148
+ $backtrace = debug_backtrace( ~DEBUG_BACKTRACE_PROVIDE_OBJECT | DEBUG_BACKTRACE_IGNORE_ARGS );
149
  // phpcs:enable
150
  foreach ( $backtrace as $backtrace_entry ) {
151
  if ( 'wp_insert_term' === $backtrace_entry['function'] ) {
183
  }
184
 
185
  if ( seems_utf8( $filename ) ) {
186
+ $filename = Mbstring::mb_strtolower( $filename );
 
 
 
 
187
  }
188
 
189
  return $this->transliterate( $filename );
198
  */
199
  private function fix_mac_string( $string ) {
200
  $table = $this->get_filtered_table();
201
+ $fix_table = Conversion_Tables::get_fix_table_for_mac();
202
 
203
  $fix = [];
204
  foreach ( $fix_table as $key => $value ) {
210
  return strtr( $string, $fix );
211
  }
212
 
213
+ /**
214
+ * Split Chinese string by hyphens.
215
+ *
216
+ * @param string $string String.
217
+ * @param array $table Conversion table.
218
+ *
219
+ * @return string
220
+ */
221
+ protected function split_chinese_string( $string, $table ) {
222
+ if ( ! $this->settings->is_chinese_locale() || Mbstring::mb_strlen( $string ) < 4 ) {
223
+ return $string;
224
+ }
225
+
226
+ $chars = Mbstring::mb_str_split( $string );
227
+ $string = '';
228
+
229
+ foreach ( $chars as $char ) {
230
+ if ( isset( $table[ $char ] ) ) {
231
+ $string .= '-' . $char . '-';
232
+ } else {
233
+ $string .= $char;
234
+ }
235
+ }
236
+
237
+ return $string;
238
+ }
239
+
240
  /**
241
  * Get transliteration table.
242
  *
257
  $table = $this->get_filtered_table();
258
 
259
  $string = $this->fix_mac_string( $string );
260
+ $string = $this->split_chinese_string( $string, $table );
261
  $string = strtr( $string, $table );
262
 
263
  if ( function_exists( 'iconv' ) ) {
278
  private function ctl_is_classic_editor_plugin_active() {
279
  if ( ! function_exists( 'is_plugin_active' ) ) {
280
  // @codeCoverageIgnoreStart
281
+ /**
282
+ * Do not inspect include path.
283
+ *
284
+ * @noinspection PhpIncludeInspection
285
+ */
286
  include_once ABSPATH . 'wp-admin/includes/plugin.php';
287
  // @codeCoverageIgnoreEnd
288
  }
312
 
313
  if ( $this->ctl_is_classic_editor_plugin_active() ) {
314
  $editor_option = get_option( 'classic-editor-replace' );
315
+ $block_editor_active = [ 'no-replace', 'block' ];
316
 
317
  return in_array( $editor_option, $block_editor_active, true );
318
  }
328
  *
329
  * @return mixed
330
  */
331
+ public function ctl_sanitize_post_name( $data, $postarr = [] ) {
332
  global $current_screen;
333
 
334
  if ( ! $this->ctl_is_gutenberg_editor_active() ) {
342
 
343
  if (
344
  ! $data['post_name'] && $data['post_title'] &&
345
+ ! in_array( $data['post_status'], [ 'auto-draft', 'revision' ], true )
346
  ) {
347
  $data['post_name'] = sanitize_title( $data['post_title'] );
348
  }
includes/class-cyr-to-lat-requirements.php → classes/class-requirements.php RENAMED
@@ -5,12 +5,14 @@
5
  * @package cyr-to-lat
6
  */
7
 
8
- if ( ! class_exists( 'Cyr_To_Lat_Requirements' ) ) {
 
 
9
 
10
  /**
11
- * Class Cyr_To_Lat_Requirements
12
  */
13
- class Cyr_To_Lat_Requirements {
14
 
15
  /**
16
  * Check if requirements are met.
@@ -28,7 +30,7 @@ if ( ! class_exists( 'Cyr_To_Lat_Requirements' ) ) {
28
  */
29
  private function is_php_version_required() {
30
  if ( version_compare( CYR_TO_LAT_MINIMUM_PHP_REQUIRED_VERSION, phpversion(), '>' ) ) {
31
- add_action( 'admin_notices', array( $this, 'php_requirement_message' ) );
32
 
33
  return false;
34
  }
5
  * @package cyr-to-lat
6
  */
7
 
8
+ namespace Cyr_To_Lat;
9
+
10
+ if ( ! class_exists( __NAMESPACE__ . '\Requirements' ) ) {
11
 
12
  /**
13
+ * Class Requirements
14
  */
15
+ class Requirements {
16
 
17
  /**
18
  * Check if requirements are met.
30
  */
31
  private function is_php_version_required() {
32
  if ( version_compare( CYR_TO_LAT_MINIMUM_PHP_REQUIRED_VERSION, phpversion(), '>' ) ) {
33
+ add_action( 'admin_notices', [ $this, 'php_requirement_message' ] );
34
 
35
  return false;
36
  }
includes/class-cyr-to-lat-settings.php → classes/class-settings.php RENAMED
@@ -5,12 +5,16 @@
5
  * @package cyr-to-lat
6
  */
7