Skip to content

Commit

Permalink
Merge pull request #150 from mihdan/v6.0.8
Browse files Browse the repository at this point in the history
V6.0.8
  • Loading branch information
kagg-design authored Feb 14, 2024
2 parents 837a35f + 60d8801 commit b58ec76
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 79 deletions.
4 changes: 2 additions & 2 deletions cyr-to-lat.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* Plugin Name: Cyr-To-Lat
* Plugin URI: https://wordpress.org/plugins/cyr2lat/
* Description: Convert Non-Latin characters in post and term slugs to Latin characters. Useful for creating human-readable URLs. Based on the original plugin by Anton Skorobogatov.
* Version: 6.0.7
* Version: 6.0.8
* Requires at least: 5.1
* Requires PHP: 7.0.0
* Author: Sergey Biryukov, Mikhail Kobzarev, Igor Gergel
Expand Down Expand Up @@ -43,7 +43,7 @@
/**
* Plugin version.
*/
define( 'CYR_TO_LAT_VERSION', '6.0.7' );
define( 'CYR_TO_LAT_VERSION', '6.0.8' );

/**
* Path to the plugin dir.
Expand Down
6 changes: 5 additions & 1 deletion readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Contributors: SergeyBiryukov, mihdan, karevn, webvitaly, kaggdesign
Tags: cyrillic, belorussian, ukrainian, bulgarian, macedonian, georgian, kazakh, latin, l10n, russian, cyr-to-lat, cyr2lat, rustolat, slugs, translations, transliteration
Requires at least: 5.1
Tested up to: 6.4
Stable tag: 6.0.7
Stable tag: 6.0.8
Requires PHP: 7.0.0
License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Expand Down Expand Up @@ -221,6 +221,10 @@ Yes, you can!

== Changelog ==

= 6.0.8 (14.02.2024) =
* Improved detection of the Gutenberg editor.
* Fixed processing of product attributes.

= 6.0.7 (11.02.2024) =
* Tested with WooCommerce 8.5.
* Added redirect from the cyrillic post title when creating a new post.
Expand Down
65 changes: 27 additions & 38 deletions src/php/Main.php
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ public function woocommerce_after_template_part_filter() {
* @noinspection PhpUndefinedFunctionInspection
*/
protected function is_wc_attribute_taxonomy( string $title ): bool {
$title = str_replace( 'pa_', '', $title );
$title = preg_replace( '/^pa_/', '', $title );

foreach ( wc_get_attribute_taxonomies() as $attribute_taxonomy ) {
if ( $title === $attribute_taxonomy->attribute_name ) {
Expand All @@ -396,22 +396,28 @@ protected function is_wc_attribute_taxonomy( string $title ): bool {
}

/**
* Check if title is a product attribute.
* Check if title is a product not converted attribute.
*
* @param string $title Title.
*
* @return bool
* @noinspection PhpUndefinedFunctionInspection
*/
protected function is_wc_product_attribute( string $title ): bool {
protected function is_wc_product_not_converted_attribute( string $title ): bool {

global $product;

if ( null === $product ) {
if ( ! is_a( $product, 'WC_Product' ) ) {
return false;
}

foreach ( $product->get_attributes() as $attribute ) {
if ( $title === $attribute->get_name() ) {
// We have to get attributes from postmeta here to see the converted slug.
$attributes = (array) get_post_meta( $product->get_id(), '_product_attributes', true );

foreach ( $attributes as $slug => $attribute ) {
$name = $attribute['name'] ?? '';

if ( $name === $title && sanitize_title_with_dashes( $title ) === $slug ) {
return true;
}
}
Expand All @@ -432,7 +438,7 @@ protected function is_wc_attribute( string $title ): bool {
return false;
}

return $this->is_wc_attribute_taxonomy( $title ) || $this->is_wc_product_attribute( $title );
return $this->is_wc_attribute_taxonomy( $title ) || $this->is_wc_product_not_converted_attribute( $title );
}

/**
Expand Down Expand Up @@ -536,48 +542,31 @@ public function transliterate( string $str ): string {
}

/**
* Check if Classic Editor plugin is active.
*
* @link https://kagg.eu/how-to-catch-gutenberg/
* Check if the Block Editor is active.
* Must only be used after plugins_loaded action is fired.
*
* @return bool
* @noinspection PhpUndefinedFunctionInspection
*/
private function is_classic_editor_plugin_active(): bool {
private function is_gutenberg_editor_active(): bool {
// Gutenberg plugin is installed and activated.
// This filter was removed in WP 5.5.
if ( has_filter( 'replace_editor', 'gutenberg_init' ) ) {
return true;
}

// @codeCoverageIgnoreStart
if ( ! function_exists( 'is_plugin_active' ) ) {
include_once ABSPATH . 'wp-admin/includes/plugin.php';
}

// @codeCoverageIgnoreEnd

return is_plugin_active( 'classic-editor/classic-editor.php' );
}

/**
* Check if Block Editor is active.
* Must only be used after plugins_loaded action is fired.
*
* @link https://kagg.eu/how-to-catch-gutenberg/
*
* @return bool
*/
private function is_gutenberg_editor_active(): bool {

// Gutenberg plugin is installed and activated.
$gutenberg = ! ( false === has_filter( 'replace_editor', 'gutenberg_init' ) );

// Block editor since 5.0.
$block_editor = version_compare( $GLOBALS['wp_version'], '5.0-beta', '>' );

if ( ! $gutenberg && ! $block_editor ) {
return false;
if ( is_plugin_active( 'classic-editor/classic-editor.php' ) ) {
return in_array( get_option( 'classic-editor-replace' ), [ 'no-replace', 'block' ], true );
}

if ( $this->is_classic_editor_plugin_active() ) {
$editor_option = get_option( 'classic-editor-replace' );
$block_editor_active = [ 'no-replace', 'block' ];

return in_array( $editor_option, $block_editor_active, true );
if ( is_plugin_active( 'disable-gutenberg/disable-gutenberg.php' ) ) {
return ! disable_gutenberg();
}

return true;
Expand Down
111 changes: 74 additions & 37 deletions tests/unit/MainTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class MainTest extends CyrToLatTestCase {
public function tearDown(): void {
// phpcs:disable WordPress.Security.NonceVerification.Missing
// phpcs:disable WordPress.Security.NonceVerification.Recommended
unset( $GLOBALS['wp_version'], $GLOBALS['wpdb'], $GLOBALS['current_screen'], $GLOBALS['product'], $_POST, $_GET );
unset( $GLOBALS['wpdb'], $GLOBALS['current_screen'], $GLOBALS['product'], $_POST, $_GET );
// phpcs:enable WordPress.Security.NonceVerification.Recommended
// phpcs:enable WordPress.Security.NonceVerification.Missing
}
Expand Down Expand Up @@ -779,36 +779,30 @@ static function ( $function_name ) use ( $is_wc ) {
}

/**
* Test is_wc_product_attribute().
* Test is_wc_product_not_converted_attribute().
*
* @param string $title Title.
* @param bool $is_product Whether it is a product page.
* @param array $names Attribute names.
* @param array $attributes Attribute names.
* @param bool $expected Expected result.
*
* @dataProvider dp_test_is_wc_product_attribute
* @throws ReflectionException ReflectionException.
*/
public function test_is_wc_product_attribute( string $title, bool $is_product, array $names, bool $expected ) {
$method = 'is_wc_product_attribute';
$subject = $this->get_subject();
public function test_is_wc_product_not_converted_attribute( string $title, bool $is_product, array $attributes, bool $expected ) {
$product_id = 5;
$method = 'is_wc_product_not_converted_attribute';
$subject = $this->get_subject();

$this->set_method_accessibility( $subject, $method );

$attributes = [];

foreach ( $names as $name ) {
$attribute = Mockery::mock( 'WC_Product_Attribute' );

$attribute->shouldReceive( 'get_name' )->andReturn( $name );

$attributes[] = $attribute;
}

$product = Mockery::mock( 'WC_Product' );
$product->shouldReceive( 'get_attributes' )->andReturn( $attributes );
$product->shouldReceive( 'get_id' )->andReturn( $product_id );
$GLOBALS['product'] = $is_product ? $product : null;

WP_Mock::userFunction( 'get_post_meta' )->with( $product_id, '_product_attributes', true )->andReturn( $attributes );
WP_Mock::passthruFunction( 'sanitize_title_with_dashes' );

self::assertSame( $expected, $subject->$method( $title ) );
}

Expand All @@ -821,8 +815,16 @@ public function dp_test_is_wc_product_attribute(): array {
return [
'not a product page' => [ 'атрибут 1', false, [], false ],
'no attributes' => [ 'атрибут 1', true, [], false ],
'no matching' => [ 'атрибут 1', true, [ 'some' ], false ],
'matching' => [ 'атрибут 1', true, [ 'some', 'атрибут 1' ], true ],
'no matching' => [ 'атрибут 1', true, [ 'some' => [ 'name' => 'some' ] ], false ],
'matching' => [
'атрибут 1',
true,
[
'some' => [ 'name' => 'some' ],
'атрибут 1' => [ 'name' => 'атрибут 1' ],
],
true,
],
];
}

Expand Down Expand Up @@ -1135,8 +1137,6 @@ public static function dp_test_min_suffix(): array {
* Test that sanitize_post_name() does nothing if no Block/Gutenberg editor is active
*/
public function test_sanitize_post_name_without_gutenberg() {
$subject = Mockery::mock( Main::class )->makePartial()->shouldAllowMockingProtectedMethods();

$data = [ 'something' ];

WP_Mock::userFunction(
Expand All @@ -1146,13 +1146,6 @@ public function test_sanitize_post_name_without_gutenberg() {
'return' => false,
]
);

// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
$GLOBALS['wp_version'] = '4.9';
self::assertSame( $data, $subject->sanitize_post_name( $data ) );

FunctionMocker::replace( 'function_exists', true );

WP_Mock::userFunction(
'is_plugin_active',
[
Expand All @@ -1161,7 +1154,6 @@ public function test_sanitize_post_name_without_gutenberg() {
'return' => true,
]
);

WP_Mock::userFunction(
'get_option',
[
Expand All @@ -1171,8 +1163,45 @@ public function test_sanitize_post_name_without_gutenberg() {
]
);

// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
$GLOBALS['wp_version'] = '5.0';
$subject = Mockery::mock( Main::class )->makePartial()->shouldAllowMockingProtectedMethods();

self::assertSame( $data, $subject->sanitize_post_name( $data ) );
}

/**
* Test that sanitize_post_name() does nothing if Disable Gutenberg plugin is active
*/
public function test_sanitize_post_name_with_disable_gutenberg_plugin() {
$data = [ 'something' ];

WP_Mock::userFunction(
'has_filter',
[
'args' => [ 'replace_editor', 'gutenberg_init' ],
'return' => false,
]
);
WP_Mock::userFunction(
'is_plugin_active',
[
'times' => 1,
'args' => [ 'classic-editor/classic-editor.php' ],
'return' => false,
]
);
WP_Mock::userFunction(
'is_plugin_active',
[
'times' => 1,
'args' => [ 'disable-gutenberg/disable-gutenberg.php' ],
'return' => true,
]
);

$subject = Mockery::mock( Main::class )->makePartial()->shouldAllowMockingProtectedMethods();

FunctionMocker::replace( 'disable_gutenberg', true );

self::assertSame( $data, $subject->sanitize_post_name( $data ) );
}

Expand All @@ -1190,9 +1219,6 @@ public function test_sanitize_post_name_not_post_edit_screen() {
]
);

// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
$GLOBALS['wp_version'] = '5.0';

$subject = Mockery::mock( Main::class )->makePartial()->shouldAllowMockingProtectedMethods();
FunctionMocker::replace( 'function_exists', true );

Expand All @@ -1203,6 +1229,13 @@ public function test_sanitize_post_name_not_post_edit_screen() {
'return' => false,
]
);
WP_Mock::userFunction(
'is_plugin_active',
[
'args' => [ 'disable-gutenberg/disable-gutenberg.php' ],
'return' => false,
]
);

$current_screen = Mockery::mock( WP_Screen::class );
$current_screen->base = 'not post';
Expand All @@ -1226,9 +1259,6 @@ public function test_sanitize_post_name_not_post_edit_screen() {
*/
public function test_sanitize_post_name( array $data, array $expected ) {

// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
$GLOBALS['wp_version'] = '5.0';

$subject = Mockery::mock( Main::class )->makePartial()->shouldAllowMockingProtectedMethods();
FunctionMocker::replace( 'function_exists', true );

Expand All @@ -1239,6 +1269,13 @@ public function test_sanitize_post_name( array $data, array $expected ) {
'return' => false,
]
);
WP_Mock::userFunction(
'is_plugin_active',
[
'args' => [ 'disable-gutenberg/disable-gutenberg.php' ],
'return' => false,
]
);

$current_screen = Mockery::mock( WP_Screen::class );
$current_screen->base = 'post';
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
/**
* Plugin version.
*/
const CYR_TO_LAT_TEST_VERSION = '6.0.7';
const CYR_TO_LAT_TEST_VERSION = '6.0.8';

/**
* Path to the plugin dir.
Expand Down

0 comments on commit b58ec76

Please sign in to comment.