diff --git a/src/Forms/FormField.php b/src/Forms/FormField.php index 5a9b65bef..c0920fa7b 100644 --- a/src/Forms/FormField.php +++ b/src/Forms/FormField.php @@ -295,8 +295,8 @@ class FormField extends RequestHandler * * Examples: * - * - 'TotalAmount' will return 'Total Amount' - * - 'Organisation.ZipCode' will return 'Organisation Zip Code' + * - 'TotalAmount' will return 'Total amount' + * - 'Organisation.ZipCode' will return 'Organisation zip code' * * @param string $fieldName * @@ -304,15 +304,27 @@ class FormField extends RequestHandler */ public static function name_to_label($fieldName) { + // Handle dot delimiters if (strpos($fieldName, '.') !== false) { $parts = explode('.', $fieldName); - - $label = $parts[count($parts) - 2] . ' ' . $parts[count($parts) - 1]; + // Ensure that any letter following a dot is uppercased, so that the regex below can break it up + // into words + $label = implode(array_map('ucfirst', $parts)); } else { $label = $fieldName; } - return preg_replace('/([a-z]+)([A-Z])/', '$1 $2', $label); + // Replace any capital letter that is followed by a lowercase letter with a space, the lowercased + // version of itself then the remaining lowercase letters. + $labelWithSpaces = preg_replace_callback('/([A-Z])([a-z]+)/', function ($matches) { + return ' ' . strtolower($matches[1]) . $matches[2]; + }, $label); + + // Add a space before any capital letter block that is at the end of the string + $labelWithSpaces = preg_replace('/([a-z])([A-Z]+)$/', '$1 $2', $labelWithSpaces); + + // The first letter should be uppercase + return ucfirst(trim($labelWithSpaces)); } /** diff --git a/tests/php/Forms/FieldListTest.php b/tests/php/Forms/FieldListTest.php index 5309e88f1..37a6e1498 100644 --- a/tests/php/Forms/FieldListTest.php +++ b/tests/php/Forms/FieldListTest.php @@ -482,29 +482,29 @@ class FieldListTest extends SapphireTest ); $this->assertEquals( - $tabSetWithTitle->Title(), 'My TabSet Title', - 'Automatic conversion of tab identifiers through findOrMakeTab() with FormField::name_to_label()' + $tabSetWithTitle->Title(), + 'Existing field title should be used' ); $tabWithoutTitle = $set->findOrMakeTab('Root.TabWithoutTitle'); $this->assertEquals( + 'Tab without title', $tabWithoutTitle->Title(), - 'Tab Without Title', 'Automatic conversion of tab identifiers through findOrMakeTab() with FormField::name_to_label()' ); $tabWithTitle = $set->findOrMakeTab('Root.TabWithTitle', 'My Tab with Title'); $this->assertEquals( - $tabWithTitle->Title(), 'My Tab with Title', + $tabWithTitle->Title(), 'Setting of simple tab titles through findOrMakeTab()' ); $childTabWithTitle = $set->findOrMakeTab('Root.TabSetWithoutTitle.NewChildTab', 'My Child Tab Title'); $this->assertEquals( - $childTabWithTitle->Title(), 'My Child Tab Title', + $childTabWithTitle->Title(), 'Setting of nested tab titles through findOrMakeTab() works on last child tab' ); } diff --git a/tests/php/Forms/FormFieldTest.php b/tests/php/Forms/FormFieldTest.php index b63cbec76..208b06e3f 100644 --- a/tests/php/Forms/FormFieldTest.php +++ b/tests/php/Forms/FormFieldTest.php @@ -402,4 +402,31 @@ class FormFieldTest extends SapphireTest $field = new FormField('Test'); $field->Link('bar'); } + + /** + * @param string $name + * @param string $expected + * @dataProvider nameToLabelProvider + */ + public function testNameToLabel($name, $expected) + { + $this->assertSame($expected, FormField::name_to_label($name)); + } + + /** + * @return array[] + */ + public function nameToLabelProvider() + { + return [ + ['TotalAmount', 'Total amount'], + ['Organisation.ZipCode', 'Organisation zip code'], + ['Organisation.zipCode', 'Organisation zip code'], + ['FooBarBaz', 'Foo bar baz'], + ['URLSegment', 'URL segment'], + ['ONLYCAPS', 'ONLYCAPS'], + ['onlylower', 'Onlylower'], + ['SpecialURL', 'Special URL'], + ]; + } } diff --git a/tests/php/Forms/FormTest.php b/tests/php/Forms/FormTest.php index 3322eb1b5..87336ddc8 100644 --- a/tests/php/Forms/FormTest.php +++ b/tests/php/Forms/FormTest.php @@ -415,7 +415,7 @@ class FormTest extends FunctionalTest // Firstly, assert that required fields still work when not using an exempt action $this->assertPartialMatchBySelector( '#Form_Form_SomeRequiredField_Holder .required', - array('"Some Required Field" is required'), + array('"Some required field" is required'), 'Required fields show a notification on field when left blank' ); @@ -487,7 +487,7 @@ class FormTest extends FunctionalTest $this->assertPartialMatchBySelector( '#Form_Form_SomeRequiredField_Holder span.required', array( - '"Some Required Field" is required' + '"Some required field" is required' ), 'Required fields show a notification on field when left blank' ); diff --git a/tests/php/i18n/i18nTest.php b/tests/php/i18n/i18nTest.php index be0e85f7d..34237e72a 100644 --- a/tests/php/i18n/i18nTest.php +++ b/tests/php/i18n/i18nTest.php @@ -102,7 +102,7 @@ class i18nTest extends SapphireTest $obj->fieldLabel('MyProperty') ); $this->assertEquals( - 'My Untranslated Property', + 'My untranslated property', $obj->fieldLabel('MyUntranslatedProperty') ); }