Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds a rule to slug #47

Merged
merged 11 commits into from Jul 11, 2016
36 changes: 33 additions & 3 deletions docs/filter-rules.md
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -200,7 +201,7 @@ $result = $f->filter([
* array(2) {
* ["price"]=> string(4) "5.00"
* ["discount"]=> string(4) "2.93"
* }
* }
*/
```

Expand Down Expand Up @@ -270,6 +271,35 @@ $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 !']);
// 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.
Expand Down
11 changes: 11 additions & 0 deletions src/FilterResource.php
Expand Up @@ -229,6 +229,17 @@ public function replace($search, $replace)
return $this->addRule(new FilterRule\Replace($search, $replace));
}

/**
* Results that returns a value slugged
*
* @param string|null $fieldToSlugFrom
* @return $this
*/
public function slug($fieldToSlugFrom = null)
{
return $this->addRule(new FilterRule\Slug($fieldToSlugFrom));
}

/**
* Returns rule that results a casted string
*
Expand Down
67 changes: 67 additions & 0 deletions src/FilterRule/Slug.php
@@ -0,0 +1,67 @@
<?php
/**
* Particle.
*
* @link http://github.com/particle-php for the canonical source repository
* @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;

use Particle\Filter\FilterRule;

/**
* Class Slug
*
* @package Particle\Filter\FilterRule
*/
class Slug extends FilterRule
{
/**
* Allows a default value to be set if no data key was provided
*
* @var bool
*/
protected $allowNotSet = true;

/**
* @var string
*/
private $fieldToSlugFrom;

/**
* @var string
*/
private $transliterator = 'Any-Latin; Latin-ASCII; NFD; [:Nonspacing Mark:] Remove; NFC; [:Punctuation:] Remove; Lower();';

/**
* @param string $fieldToSlugFrom
*/
public function __construct($fieldToSlugFrom)
{
$this->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];
}

if (is_null($value)) {
return $this->setEmpty();
}

$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);
}
}
69 changes: 69 additions & 0 deletions tests/FilterRule/SlugTest.php
@@ -0,0 +1,69 @@
<?php
namespace Particle\Tests\Filter\FilterRule;

use Particle\Filter\Filter;

class SlugTest extends \PHPUnit_Framework_TestCase
{
/**
* @var Filter
*/
protected $filter;

/**
* Prepare the filter
*/
public function setUp()
{
$this->filter = new Filter();
}

/**
* @dataProvider getSlugResults
* @param string $value
* @param string $filteredValue
* @param string $field
* @param string $fieldValue
*/
public function testSlugFilterRule($value, $filteredValue, $field, $fieldValue)
{
$this->filter->value('test')->slug($field);

$result = $this->filter->filter([
'test' => $value,
$field => $fieldValue,
]);

$this->assertSame($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'],
];
}

/**
* 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([
'not-title' => 'Definitely not a title to slug',
]);

$this->assertSame(['not-title' => 'Definitely not a title to slug'], $result);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jhuet

How about introducing an explaining variable here to improve clarity?

$data = [            
    'test' => 'test',
];

$this->assertSame($data, $this->filter->filter($data));

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, you got it, i'm in a good mood today :)

}