From 9e6905c0b495e834d9ceb0112df7e114f9d54fa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Huet?= Date: Thu, 30 Jun 2016 09:59:13 +0000 Subject: [PATCH 01/10] Adds a rule to slug a field with its own value or from another field's --- docs/filter-rules.md | 37 +++++++++++++++++++++-- src/FilterResource.php | 8 +++++ src/FilterRule/Slug.php | 56 +++++++++++++++++++++++++++++++++++ tests/FilterRule/SlugTest.php | 53 +++++++++++++++++++++++++++++++++ 4 files changed, 151 insertions(+), 3 deletions(-) create mode 100644 src/FilterRule/Slug.php create mode 100644 tests/FilterRule/SlugTest.php diff --git a/docs/filter-rules.md b/docs/filter-rules.md index 5062f02..ac7260e 100644 --- a/docs/filter-rules.md +++ b/docs/filter-rules.md @@ -21,6 +21,7 @@ filters, take a look at the callback filter-rule, or check out "Extending the Fi * [remove](#remove)() * [removeNull](#removenull)() * [replace](#replace)($search, $replace) +* [slug](#slug)($fieldToSlugFrom) * [string](#string)() * [stripHtml](#striphtml)($excludeTags = null) * [trim](#trim)($characters = null) @@ -149,7 +150,7 @@ Make sure the value is a float. $f = new Filter; $f->value('value')->float(); $result = $f->filter(['value' => '123.123']); -// array(1) { ["value"]=> float(123.123) } +// array(1) { ["value"]=> float(123.123) } ``` ## Int @@ -160,7 +161,7 @@ Make sure the value is a int. $f = new Filter; $f->value('value')->int(); $result = $f->filter(['value' => '123.123']); -// array(1) { ["value"]=> int(123) } +// array(1) { ["value"]=> int(123) } ``` ## Letters @@ -200,7 +201,7 @@ $result = $f->filter([ * array(2) { * ["price"]=> string(4) "5.00" * ["discount"]=> string(4) "2.93" - * } + * } */ ``` @@ -270,6 +271,36 @@ $result = $f->filter(['name' => 'hello im john']); // array(1) { ["name"]=> string(13) "hello-im-john" } ``` +## Slug + +Slugs the value of the field or the value of another one for use in an URL. + +```php +$f = new Filter; +$f->value('slug')->slug(); +$result = $f->filter(['slug' => 'Slug this !']); +// array(1) { ["slug"]=> string(9) "slug-this" } +``` + +Here we'll slug the value from another field. + +```php +$f = new Filter; +$f->value('slug')->slug('title'); +$result = $f->filter(['title' => 'Slug this title !', 'slug' => '']); +// array(2) { ["title"]=> string(17) "Slug this title !" ["slug"]=> string(15) "slug-this-title" } +``` + +If you don't set an empty `slug` value, nothing will be done as the field hasn't been set. If you don't want to provide it everytime, you can default the value to an empty string before calling slug. + +```php +$f = new Filter; +$f->value('slug')->defaults('')->slug('title'); +$result = $f->filter(['title' => 'Slug this title !']); +// array(2) { ["title"]=> string(17) "Slug this title !" ["slug"]=> string(15) "slug-this-title" } +``` + + ## String Make sure the value is a string. diff --git a/src/FilterResource.php b/src/FilterResource.php index a263496..61bb6af 100644 --- a/src/FilterResource.php +++ b/src/FilterResource.php @@ -229,6 +229,14 @@ public function replace($search, $replace) return $this->addRule(new FilterRule\Replace($search, $replace)); } + /** + * @param type $fieldToSlugFrom + */ + public function slug($fieldToSlugFrom = null) + { + return $this->addRule(new FilterRule\Slug($fieldToSlugFrom)); + } + /** * Returns rule that results a casted string * diff --git a/src/FilterRule/Slug.php b/src/FilterRule/Slug.php new file mode 100644 index 0000000..bff768f --- /dev/null +++ b/src/FilterRule/Slug.php @@ -0,0 +1,56 @@ +fieldToSlugFrom = $fieldToSlugFrom; + } + + /** + * Slug the value of either the actual field of the given one. + * + * @param mixed $value + * @return string + */ + public function filter($value) + { + if (empty($value) && isset($this->filterData[$this->fieldToSlugFrom])) { + $value = $this->filterData[$this->fieldToSlugFrom]; + } + + $value = transliterator_transliterate($this->transliterator, $value); + $value = iconv("UTF-8", "ASCII//TRANSLIT//IGNORE", $value); + $value = preg_replace('/[-$?\s]+/', '-', $value); + $value = trim($value, '-'); + return strtolower($value); + } +} diff --git a/tests/FilterRule/SlugTest.php b/tests/FilterRule/SlugTest.php new file mode 100644 index 0000000..11d0aa6 --- /dev/null +++ b/tests/FilterRule/SlugTest.php @@ -0,0 +1,53 @@ +filter = new Filter(); + } + + /** + * @dataProvider getSlugResults + * @param string $value + * @param string $filteredValue + */ + public function testSlugFilterRule($value, $filteredValue, $field, $fieldValue) + { + $this->filter->value('test')->slug($field); + + $result = $this->filter->filter([ + 'test' => $value, + $field => $fieldValue, + ]); + + $this->assertEquals($filteredValue, $result['test']); + } + + /** + * @return array + */ + public function getSlugResults() + { + return [ + ['', '', '', ''], + ['This is a great stuff to slug !', 'this-is-a-great-stuff-to-slug', '', ''], + ['That too with somê spéciàl châractèr$ from €ope !', 'that-too-with-some-special-character-from-europe', '', ''], + ['A æ Übérmensch på høyeste nivå! И я люблю PHP ! fi', 'a-ae-ubermensch-pa-hoyeste-niva-i-a-lublu-php-fi', '', ''], + ['', 'this-is-a-great-stuff-to-slug', 'test', 'This is a great stuff to slug !'], + ['', 'that-too-with-some-special-character-from-europe', 'test', 'That too with somê spéciàl châractèr$ from €ope !'], + ['', 'a-ae-ubermensch-pa-hoyeste-niva-i-a-lublu-php-fi', 'test', 'A æ Übérmensch på høyeste nivå! И я люблю PHP ! fi'], + ]; + } +} From c5821afee4e7672647e837ee3856c0cd35e08d94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Huet?= Date: Thu, 30 Jun 2016 12:04:06 +0000 Subject: [PATCH 02/10] Completing annotations / comments --- src/FilterResource.php | 2 ++ tests/FilterRule/SlugTest.php | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/FilterResource.php b/src/FilterResource.php index 61bb6af..ce637ae 100644 --- a/src/FilterResource.php +++ b/src/FilterResource.php @@ -230,6 +230,8 @@ public function replace($search, $replace) } /** + * Results that returns a value slugged + * * @param type $fieldToSlugFrom */ public function slug($fieldToSlugFrom = null) diff --git a/tests/FilterRule/SlugTest.php b/tests/FilterRule/SlugTest.php index 11d0aa6..af45006 100644 --- a/tests/FilterRule/SlugTest.php +++ b/tests/FilterRule/SlugTest.php @@ -22,6 +22,8 @@ public function setUp() * @dataProvider getSlugResults * @param string $value * @param string $filteredValue + * @param string $field + * @param string $fieldValue */ public function testSlugFilterRule($value, $filteredValue, $field, $fieldValue) { From 51b1405b50f115584cc7995d04efb6caebe929bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Huet?= Date: Fri, 1 Jul 2016 07:49:41 +0000 Subject: [PATCH 03/10] Using allowNotSet = true --- src/FilterRule/Slug.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/FilterRule/Slug.php b/src/FilterRule/Slug.php index bff768f..29fb840 100644 --- a/src/FilterRule/Slug.php +++ b/src/FilterRule/Slug.php @@ -17,6 +17,13 @@ */ class Slug extends FilterRule { + /** + * Allows a default value to be set if no data key was provided + * + * @var bool + */ + protected $allowNotSet = true; + /** * @var string */ @@ -44,7 +51,11 @@ public function __construct($fieldToSlugFrom) public function filter($value) { if (empty($value) && isset($this->filterData[$this->fieldToSlugFrom])) { - $value = $this->filterData[$this->fieldToSlugFrom]; + $value = $this->filterData[$this->fieldToSlugFrom]; + } + + if (is_null($value)) { + return; } $value = transliterator_transliterate($this->transliterator, $value); From 043e29941c5cfa52c84b24143d818b39405c421c Mon Sep 17 00:00:00 2001 From: Rick van der Staaij Date: Fri, 8 Jul 2016 16:18:43 +0200 Subject: [PATCH 04/10] Make the slug non existant if null with setEmpty --- src/FilterRule/Slug.php | 4 ++-- tests/FilterRule/SlugTest.php | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/FilterRule/Slug.php b/src/FilterRule/Slug.php index 29fb840..d4f1ddb 100644 --- a/src/FilterRule/Slug.php +++ b/src/FilterRule/Slug.php @@ -32,7 +32,7 @@ class Slug extends FilterRule /** * @var string */ - private $transliterator = "Any-Latin; Latin-ASCII; NFD; [:Nonspacing Mark:] Remove; NFC; [:Punctuation:] Remove; Lower();"; + private $transliterator = 'Any-Latin; Latin-ASCII; NFD; [:Nonspacing Mark:] Remove; NFC; [:Punctuation:] Remove; Lower();'; /** * @param string $fieldToSlugFrom @@ -55,7 +55,7 @@ public function filter($value) } if (is_null($value)) { - return; + return $this->setEmpty(); } $value = transliterator_transliterate($this->transliterator, $value); diff --git a/tests/FilterRule/SlugTest.php b/tests/FilterRule/SlugTest.php index af45006..7216c5b 100644 --- a/tests/FilterRule/SlugTest.php +++ b/tests/FilterRule/SlugTest.php @@ -52,4 +52,18 @@ public function getSlugResults() ['', 'a-ae-ubermensch-pa-hoyeste-niva-i-a-lublu-php-fi', 'test', 'A æ Übérmensch på høyeste nivå! И я люблю PHP ! fi'], ]; } + + /** + * Test that a slug based of a non existing key, does not exist. + */ + public function testSlugFilterEmptyIfNotAvailable() + { + $this->filter->value('slug')->slug('title'); + + $result = $this->filter->filter([ + 'test' => 'test', + ]); + + $this->assertEquals(['test' => 'test'], $result); + } } From 106bccc37eff039e4ba7ec6ef7a210dc4df63520 Mon Sep 17 00:00:00 2001 From: Rick van der Staaij Date: Fri, 8 Jul 2016 16:23:59 +0200 Subject: [PATCH 05/10] Fix PR comments --- src/FilterResource.php | 3 ++- src/FilterRule/Slug.php | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/FilterResource.php b/src/FilterResource.php index ce637ae..0c21931 100644 --- a/src/FilterResource.php +++ b/src/FilterResource.php @@ -232,7 +232,8 @@ public function replace($search, $replace) /** * Results that returns a value slugged * - * @param type $fieldToSlugFrom + * @param string|null $fieldToSlugFrom + * @return $this */ public function slug($fieldToSlugFrom = null) { diff --git a/src/FilterRule/Slug.php b/src/FilterRule/Slug.php index d4f1ddb..8d19e2b 100644 --- a/src/FilterRule/Slug.php +++ b/src/FilterRule/Slug.php @@ -3,7 +3,7 @@ * Particle. * * @link http://github.com/particle-php for the canonical source repository - * @copyright Copyright (c) 2005-2015 Particle (http://particle-php.com) + * @copyright Copyright (c) 2005-2016 Particle (http://particle-php.com) * @license https://github.com/particle-php/Filter/blob/master/LICENSE New BSD License */ namespace Particle\Filter\FilterRule; From 8cc1c4fb24493b6c3ce81a0613ac15ade7315cf8 Mon Sep 17 00:00:00 2001 From: Rick van der Staaij Date: Fri, 8 Jul 2016 16:30:15 +0200 Subject: [PATCH 06/10] Fix gap in the filter-rules.md --- docs/filter-rules.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/filter-rules.md b/docs/filter-rules.md index ac7260e..f5d2f95 100644 --- a/docs/filter-rules.md +++ b/docs/filter-rules.md @@ -300,7 +300,6 @@ $result = $f->filter(['title' => 'Slug this title !']); // array(2) { ["title"]=> string(17) "Slug this title !" ["slug"]=> string(15) "slug-this-title" } ``` - ## String Make sure the value is a string. From 61161e3524a5407ec41ddac84d7ae0910e613144 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Huet?= Date: Sat, 9 Jul 2016 12:55:50 +0200 Subject: [PATCH 07/10] Removing now useless documentation --- docs/filter-rules.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/docs/filter-rules.md b/docs/filter-rules.md index f5d2f95..a413e40 100644 --- a/docs/filter-rules.md +++ b/docs/filter-rules.md @@ -291,15 +291,6 @@ $result = $f->filter(['title' => 'Slug this title !', 'slug' => '']); // array(2) { ["title"]=> string(17) "Slug this title !" ["slug"]=> string(15) "slug-this-title" } ``` -If you don't set an empty `slug` value, nothing will be done as the field hasn't been set. If you don't want to provide it everytime, you can default the value to an empty string before calling slug. - -```php -$f = new Filter; -$f->value('slug')->defaults('')->slug('title'); -$result = $f->filter(['title' => 'Slug this title !']); -// array(2) { ["title"]=> string(17) "Slug this title !" ["slug"]=> string(15) "slug-this-title" } -``` - ## String Make sure the value is a string. From d8afa70cbf9eaf4ca6e4fca92322ca901dee0351 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Huet?= Date: Sat, 9 Jul 2016 13:00:19 +0200 Subject: [PATCH 08/10] Precising Slug behavior if no value is given --- docs/filter-rules.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/filter-rules.md b/docs/filter-rules.md index a413e40..166d792 100644 --- a/docs/filter-rules.md +++ b/docs/filter-rules.md @@ -287,10 +287,19 @@ Here we'll slug the value from another field. ```php $f = new Filter; $f->value('slug')->slug('title'); -$result = $f->filter(['title' => 'Slug this title !', 'slug' => '']); +$result = $f->filter(['title' => 'Slug this title !']); // array(2) { ["title"]=> string(17) "Slug this title !" ["slug"]=> string(15) "slug-this-title" } ``` +If there is no value in the other field, the slug field won't appear in the filtered result : + +```php +$f = new Filter; +$f->value('slug')->slug('title'); +$result = $f->filter(['foo' => 'bar']); +// array(1) { ["foo"]=> string(3) "bar" } +``` + ## String Make sure the value is a string. From d6a0884ebf8006152cf25428984c781751b0e6d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Huet?= Date: Sat, 9 Jul 2016 11:58:25 +0000 Subject: [PATCH 09/10] Asserting identity on test result --- tests/FilterRule/SlugTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/FilterRule/SlugTest.php b/tests/FilterRule/SlugTest.php index 7216c5b..3a760d4 100644 --- a/tests/FilterRule/SlugTest.php +++ b/tests/FilterRule/SlugTest.php @@ -34,7 +34,7 @@ public function testSlugFilterRule($value, $filteredValue, $field, $fieldValue) $field => $fieldValue, ]); - $this->assertEquals($filteredValue, $result['test']); + $this->assertSame($filteredValue, $result['test']); } /** From 4199725435ed3cb04a64995673f7e637dab7be76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Huet?= Date: Sat, 9 Jul 2016 12:06:08 +0000 Subject: [PATCH 10/10] Test readability is key --- tests/FilterRule/SlugTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/FilterRule/SlugTest.php b/tests/FilterRule/SlugTest.php index 3a760d4..780642d 100644 --- a/tests/FilterRule/SlugTest.php +++ b/tests/FilterRule/SlugTest.php @@ -61,9 +61,9 @@ public function testSlugFilterEmptyIfNotAvailable() $this->filter->value('slug')->slug('title'); $result = $this->filter->filter([ - 'test' => 'test', + 'not-title' => 'Definitely not a title to slug', ]); - $this->assertEquals(['test' => 'test'], $result); + $this->assertSame(['not-title' => 'Definitely not a title to slug'], $result); } }