Skip to content

Commit

Permalink
refactor labels arguments, add tests for Japanese and unicode
Browse files Browse the repository at this point in the history
  • Loading branch information
joemaller committed Feb 12, 2025
1 parent 83d1c9f commit 42a4714
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 11 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ The [PHPUnit](https://phpunit.de/) test suite can be run from Docker or Herd. Do

## Default Post_Type and Taxonomy Labels

Every available defalt label can be found in [`WP_Post_Type::get_default_labels`](https://github.com/WordPress/wordpress-develop/blob/b5b4e3ada690e86ada210760f0300471d8d48a4e/src/wp-includes/class-wp-post-type.php#L977-L1032) or [`WP_Taxonomy::get_default_labels`](https://github.com/WordPress/wordpress-develop/blob/b5b4e3ada690e86ada210760f0300471d8d48a4e/src/wp-includes/class-wp-taxonomy.php#L595-L651), where each value is an array with the hierarchical option first (Pages & Categories). Default labels can also be found by dumping the `$wp_post_types[$type]->labels` and `$wp_taxonomies[$taxonomy]->labels` objects.
Every available default label can be found in [`WP_Post_Type::get_default_labels`](https://github.com/WordPress/wordpress-develop/blob/b5b4e3ada690e86ada210760f0300471d8d48a4e/src/wp-includes/class-wp-post-type.php#L977-L1032) or [`WP_Taxonomy::get_default_labels`](https://github.com/WordPress/wordpress-develop/blob/b5b4e3ada690e86ada210760f0300471d8d48a4e/src/wp-includes/class-wp-taxonomy.php#L595-L651), where each value is an array with the hierarchical option first (Pages & Categories). Default labels can also be found by dumping the `$wp_post_types[$type]->labels` and `$wp_taxonomies[$taxonomy]->labels` objects.

WordPress defines labels as an Array, then sometimes stores them as an Object, but always [casts back to an Array](https://github.com/WordPress/wordpress-develop/blob/b5b4e3ada690e86ada210760f0300471d8d48a4e/src/wp-includes/taxonomy.php#L708) before applying them. Posts and Pages overlap cleanly, Tags and Categories include special-cases for hierarchical display.

Expand Down
35 changes: 31 additions & 4 deletions src/DataModel/Labels.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ class Labels
*/
public static function labels($singular, $plural, $is_post, $is_hierarchical = true)
{
// TODO: Should support 'post_type" or "taxonomy" as well.
// check for Boolean, then string match?
// It should accept the following: post_type, post, page, taxonomy, category, tag
// post, page, category, and tag should set $is_post and $is_hierarchical
if (in_array($is_post, ['post', 'page', 'category', 'tag', 'post_type', 'taxonomy'])) {
$is_hierarchical = in_array($is_post, ['page', 'category']);
$is_post = in_array($is_post, ['post', 'page', 'post_type']);
}

$default_labels = $is_post
? \WP_Post_Type::get_default_labels()
: \WP_Taxonomy::get_default_labels();
Expand Down Expand Up @@ -41,6 +50,8 @@ public static function labels($singular, $plural, $is_post, $is_hierarchical = t
* A copy of updateLabels which requires a singular and plural label definition
* so we can remove the inflector dependency.
*
* Note: strtolower and ucwords have no effect on Japanese text
*
* Note: WordPress is inconsistent about whether the labels property of the
* register_taxonomy and register_post_type functions should be an object
* or an array. But the value always gets cast to an array anyway, so just
Expand All @@ -54,6 +65,7 @@ public static function labels($singular, $plural, $is_post, $is_hierarchical = t
public static function updateLabels($_singular, $_plural, $_labels)
{
$labels = (object) $_labels;

$singularSrc = strtolower($labels->singular_name);
$singularSrcTitleCase = ucwords($singularSrc);
$pluralSrc = strtolower($labels->name);
Expand All @@ -65,11 +77,26 @@ public static function updateLabels($_singular, $_plural, $_labels)
$pluralTitleCase = ucwords($plural);

$patterns = [
"/\b$singularSrc\b/",
"/\b$singularSrcTitleCase\b/",
"/\b$pluralSrc\b/",
"/\b$pluralSrcTitleCase\b/",
preg_quote($singularSrc, '/'),
preg_quote($singularSrcTitleCase, '/'),
preg_quote($pluralSrc, '/'),
preg_quote($pluralSrcTitleCase, '/'),
];

/**
* Check for Japanese characters
*/
if (!preg_match('/[\p{Katakana}\p{Hiragana}\p{Han}]+/u', $labels->name)) {
/**
* Wrap non-japanese regex patterns in \b word boundary delimiters
*/
$patterns = array_map(fn($p) => '\b' . $p . '\b', $patterns);
}
/**
* Wrap regex patterns in /.../u
*/
$patterns = array_map(fn($p) => "/{$p}/u", $patterns);

$replacements = [$singular, $singularTitleCase, $plural, $pluralTitleCase];

$newLabels = new \stdClass();
Expand Down
84 changes: 78 additions & 6 deletions tests/LabelsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,53 @@ final class LabelsTest extends TestCase
{
public function testLabels()
{
global $i18n;

$i18n = [
'toad' => 'sapo',
'toads' => 'sapos',
];
$actual = DataModel\Labels::labels('toad', 'toads', true, false);
$this->assertObjectHasProperty('name', $actual);
}

public function testLabels_isPost_post()
{
$actual = DataModel\Labels::labels('place', 'places', 'post', false);
$this->assertObjectHasProperty('name', $actual);
$this->assertObjectHasProperty('featured_image', $actual);
$this->assertObjectNotHasProperty('most_used', $actual);
}
public function testLabels_isPost_page()
{
$actual = DataModel\Labels::labels('place', 'places', 'page', false);
$this->assertObjectHasProperty('name', $actual);
$this->assertObjectHasProperty('featured_image', $actual);
$this->assertObjectNotHasProperty('most_used', $actual);
}
public function testLabels_isPost_post_type()
{
$actual = DataModel\Labels::labels('place', 'places', 'post_type', false);
$this->assertObjectHasProperty('name', $actual);
$this->assertObjectHasProperty('featured_image', $actual);
$this->assertObjectNotHasProperty('most_used', $actual);
}
public function testLabels_isPost_category()
{
$actual = DataModel\Labels::labels('place', 'places', 'category', false);
$this->assertObjectHasProperty('name', $actual);
$this->assertObjectNotHasProperty('featured_image', $actual);
$this->assertObjectHasProperty('most_used', $actual);
}
public function testLabels_isPost_tag()
{
$actual = DataModel\Labels::labels('place', 'places', 'tag', false);
$this->assertObjectHasProperty('name', $actual);
$this->assertObjectNotHasProperty('featured_image', $actual);
$this->assertObjectHasProperty('most_used', $actual);
}
public function testLabels_isPost_taxonomy()
{
$actual = DataModel\Labels::labels('place', 'places', 'taxonomy', false);
$this->assertObjectHasProperty('name', $actual);
$this->assertObjectNotHasProperty('featured_image', $actual);
$this->assertObjectHasProperty('most_used', $actual);
}

public function testUpdateLabels()
{
global $i18n;
Expand Down Expand Up @@ -72,4 +109,39 @@ public function testTaxonomyLabelsHasMenuName()
$this->assertObjectHasProperty('menu_name', $actual);
$this->assertEqualsIgnoringCase('Colors', $actual->menu_name);
}

public function testLabelsUnicode()
{
global $i18n;

$i18n = [
'パンダ' => '🐼',
'' => '🐝🐝',
];
$labels = DataModel\Labels::labels('toad', 'toads', true, false);
$actual = DataModel\Labels::updateLabels(__('パンダ'), __(''), $labels);
$this->assertObjectHasProperty('name', $actual);
$this->assertEqualsIgnoringCase('🐝🐝', $actual->name);
$this->assertEqualsIgnoringCase('🐼', $actual->singular_name);
}

public function testLabelsJapanese()
{
global $i18n;
$i18n = [
'person' => '',
// 'people' => '人々', // not actually plural?
'people' => '',
];
$labels = DataModel\Labels::labels('固定ページ', '固定ページ', 'page');
$labels->view_item = '固定ページを表示';
$labels->view_items = '固定ページ一覧を表示';
$labels->featured_image = 'アイキャッチ画像';
$actual = DataModel\Labels::updateLabels(__('person'), __('people'), $labels);
$this->assertObjectHasProperty('name', $actual);
$this->assertEqualsIgnoringCase('', $actual->name);
$this->assertEqualsIgnoringCase('', $actual->singular_name);
$this->assertEqualsIgnoringCase('人を表示', $actual->view_item);
$this->assertEqualsIgnoringCase('人一覧を表示', $actual->view_items);
}
}

0 comments on commit 42a4714

Please sign in to comment.