Merge pull request #92 from bzick/develop

2.2
This commit is contained in:
Ivan Shalganov 2014-07-11 14:01:59 +04:00
commit 87105bf683
13 changed files with 346 additions and 4 deletions

18
docs/mods/ematch.md Normal file
View File

@ -0,0 +1,18 @@
Modifier ematch
==============
Perform a regular expression match.
[Read more](http://www.php.net/manual/en/reference.pcre.pattern.syntax.php) about regular expression.
```
{$string|ematch:$pattern}
```
Searches `$string` for a match to the regular expression given in `$pattern`.
```smarty
{if $color|ematch:'/^gr[ae]y$/i'}
some form of gray ...
{/if}
```

23
docs/mods/ereplace.md Normal file
View File

@ -0,0 +1,23 @@
Modifier ereplace
=================
Perform a regular expression search and replace.
[Read more](http://www.php.net/manual/en/reference.pcre.pattern.syntax.php) about regular expression.
```
{$string|replace:$pattern:$replacement}
```
Searches `$string` for matches to `$pattern` and replaces them with `$replacement`.
`$replacement` may contain references of the form `\n`, `$n` or `${n}`, with the latter form being the preferred one.
Every such reference will be replaced by the text captured by the n'th parenthesized pattern. n can be from 0 to 99,
and `\0` or `$0` refers to the text matched by the whole pattern.
Opening parentheses are counted from left to right (starting from 1) to obtain the number of the capturing subpattern.
To use backslash in replacement, it must be doubled.
```smarty
{var $string = 'April 15, 2014'}
{$string|ereplace:'/(\w+) (\d+), (\d+)/i':'${1}1, $3'} {* April1, 2014 *}
```

19
docs/mods/esplit.md Normal file
View File

@ -0,0 +1,19 @@
Modifier esplit
===============
Split string by a regular expression.
[Read more](http://www.php.net/manual/en/reference.pcre.pattern.syntax.php) about regular expression.
```
{$string|esplit:$pattern = '/,\s*/'}
```
My default modifier split string by comma with spaces.
```smarty
{var $fruits1 = "banana, apple, pear"|esplit}
$fruits1 is array ["banana", "apple", "pear"]
{var $fruits2 = "banana; apple; pear"|esplit:'/;\s/'} is ["banana", "apple", "pear"]
$fruits2 is array ["banana", "apple", "pear"] too
```

16
docs/mods/join.md Normal file
View File

@ -0,0 +1,16 @@
Modifier split
==============
Join array elements with a string.
```
{$string|join:$delimiter = ","}
```
Returns an array of strings, each of which is a substring of `$string` formed by splitting it on boundaries formed by the string `$delimiter`.
```smarty
{var $fruits1 = ["banana", "apple", "pear"]}
{$fruits1|join} output banana, apple, pear
{$fruits1|join:" is not "} output banana is not apple is not pear
```

24
docs/mods/match.md Normal file
View File

@ -0,0 +1,24 @@
Modifier match
==============
Match string against a pattern.
The average user may be used to shell patterns or at least in their simplest form to `?` and `*` wildcards so using `match`
instead of `ematch` for frontend search expression input may be way more convenient for non-programming users.
```
{$string|match:$pattern}
```
Special pattern symbols:
* `?` — match one or zero unknown characters. `?at` matches `Cat`, `cat`, `Bat` or `bat`, `but` not `at`.
* `*` — match any number of unknown characters. `Law*` matches `Law`, `Laws`, or `Lawyer`.
* `[characters]` — Match a character as part of a group of characters. `[CB]at` matches `Cat` or `Bat` but not `cat`, `rat` or `bat`.
* `\` - Escape character. `Law\*` will only match `Law*`
```smarty
{if $color|match:"*gr[ae]y"}
some form of gray ...
{/if}
```

14
docs/mods/replace.md Normal file
View File

@ -0,0 +1,14 @@
Modifier replace
================
Replace all occurrences of the search string with the replacement string
```
{$string|replace:$search:$replace}
```
This modifier returns a string with all occurrences of `$search` in subject replaced with the given `$replace` value.
```smarty
{$fruits|replace:"pear":"orange"}
```

18
docs/mods/split.md Normal file
View File

@ -0,0 +1,18 @@
Modifier split
==============
Split a string by string
```
{$string|split:$delimiter = ","}
```
Returns an array of strings, each of which is a substring of `$string` formed by splitting it on boundaries formed by the string `$delimiter`.
```smarty
{var $fruits1 = "banana,apple,pear"|split}
$fruits1 is array ["banana", "apple", "pear"]
{var $fruits2 = "banana,apple,pear"|split:',apple,'}
$fruits2 is array ["banana", "pear"]
```

View File

@ -52,6 +52,13 @@ Documentation
* [strip](./mods/strip.md) — remove extra whitespaces
* [length](./mods/length.md) — calculate length of string, array, object
* [in](./mods/in.md) — find value in string or array
* [match](./mods/match.md) — match string against a pattern.
* [ematch](./mods/ematch.md) — perform a regular expression match.
* [replace](./mods/replace.md) — replace all occurrences of the search string with the replacement string.
* [ereplace](./mods/ereplace.md) — perform a regular expression search and replace.
* [split](./mods/split.md) — split a string by string.
* [esplit](./mods/esplit.md) — split string by a regular expression.
* [join](./mods/join.md) — join array elements with a string.
* allowed functions: `json_encode`, `json_decode`, `count`, `is_string`, `is_array`, `is_numeric`, `is_int`, `is_object`,
`strtotime`, `gettype`, `is_double`, `ip2long`, `long2ip`, `strip_tags`, `nl2br`
* or [add](./ext/extend.md#add-modifiers) yours

View File

@ -131,7 +131,15 @@ class Fenom
"unescape" => 'Fenom\Modifier::unescape',
"strip" => 'Fenom\Modifier::strip',
"length" => 'Fenom\Modifier::length',
"iterable" => 'Fenom\Modifier::isIterable'
"iterable" => 'Fenom\Modifier::isIterable',
"replace" => 'Fenom\Modifier::replace',
"ereplace" => 'Fenom\Modifier::ereplace',
"match" => 'Fenom\Modifier::match',
"ematch" => 'Fenom\Modifier::ematch',
"split" => 'Fenom\Modifier::split',
"esplit" => 'Fenom\Modifier::esplit',
"join" => 'Fenom\Modifier::join',
"in" => 'Fenom\Modifier::in',
);
/**

View File

@ -668,7 +668,7 @@ class Compiler
*/
public static function smartFuncParser(Tokenizer $tokens, Tag $tag)
{
if (strpos($tag->callback, "::")) {
if (strpos($tag->callback, "::") || is_array($tag->callback)) {
list($class, $method) = explode("::", $tag->callback, 2);
$ref = new \ReflectionMethod($class, $method);
} else {

View File

@ -130,7 +130,7 @@ class Modifier
}
/**
* Strip spaces symbols on edge of string end multiple spaces in string
* Strip spaces symbols on edge of string end multiple spaces in the string
*
* @param string $str
* @param bool $to_line strip line ends
@ -181,11 +181,102 @@ class Modifier
}
/**
* @param $value
* @param mixed $value
* @return bool
*/
public static function isIterable($value)
{
return is_array($value) || ($value instanceof \Iterator);
}
/**
* Replace all occurrences of the search string with the replacement string
* @param string $value The string being searched and replaced on, otherwise known as the haystack.
* @param string $search The value being searched for, otherwise known as the needle.
* @param string $replace The replacement value that replaces found search
* @return mixed
*/
public static function replace($value, $search, $replace)
{
return str_replace($search, $replace, $value);
}
/**
* @param string $value
* @param string $pattern
* @param string $replacement
* @return mixed
*/
public static function ereplace($value, $pattern, $replacement)
{
return preg_replace($pattern, $replacement, $value);
}
/**
* @param string $string
* @param string $pattern
* @return bool
*/
public static function match($string, $pattern)
{
return fnmatch($pattern, $string);
}
/**
* @param string $string
* @param string $pattern
* @return int
*/
public static function ematch($string, $pattern)
{
return preg_match($pattern, $string);
}
/**
* @param string $value
* @param string $delimiter
* @return array
*/
public static function split($value, $delimiter = ",")
{
if(is_string($value)) {
return explode($delimiter, $value);
} elseif(is_array($value)) {
return $value;
} else {
return array();
}
}
/**
* @param $value
* @param string $pattern
* @return array
*/
public static function esplit($value, $pattern = '/,\s*/S')
{
if(is_string($value)) {
return preg_split($pattern, $value);
} elseif(is_array($value)) {
return $value;
} else {
return array();
}
}
/**
* @param $value
* @param string $glue
* @return string
*/
public static function join($value, $glue = ",")
{
if(is_array($value)) {
return implode($glue, $value);
} elseif(is_string($value)) {
return $value;
} else {
return "";
}
}
}

View File

@ -16,12 +16,16 @@ class ModifiersTest extends TestCase
array($lorem, 'Lorem...', 8, '...', true),
array($lorem, 'Lorem ip...sit amet', 8, '...', false, true),
array($lorem, 'Lorem...amet', 8, '...', true, true),
array($lorem, $lorem, 100, '...', true, true),
array($lorem, $lorem, 100, '...', true, false),
// unicode
array($uni, 'Лорем ип...', 8),
array($uni, 'Лорем ип!!!', 8, '!!!'),
array($uni, 'Лорем...', 8, '...', true),
array($uni, 'Лорем ип...сит амет', 8, '...', false, true),
array($uni, 'Лорем...амет', 8, '...', true, true),
array($uni, $uni, 100, '...', true, true),
array($uni, $uni, 100, '...', true, false),
);
}
@ -119,4 +123,103 @@ class ModifiersTest extends TestCase
);
}
public static function providerIn()
{
return array(
array('"b"|in:["a", "b", "c"]', true),
array('"d"|in:["a", "b", "c"]', false),
array('2|in:["a", "b", "c"]', true),
array('3|in:["a", "b", "c"]', false),
array('"b"|in:"abc"', true),
array('"d"|in:"abc"', false),
);
}
/**
* @dataProvider providerIn
*/
public function testIn($code, $valid)
{
$tpl = $this->fenom->compileCode('{if '.$code.'}valid{else}invalid{/if}');
$this->assertEquals($valid ? "valid" : "invalid", $tpl->fetch(array()));
}
public function testJoin()
{
$tpl = $this->fenom->compileCode('{if "a;b;c" === ["a", "b", "c"]|join:";"}equal{/if}');
$this->assertEquals("equal", $tpl->fetch(array()));
}
public function testJoinString()
{
$tpl = $this->fenom->compileCode('{if "a;b;c" === "a;b;c"|join:","}equal{/if}');
$this->assertEquals("equal", $tpl->fetch(array()));
}
public function testJoinOther()
{
$tpl = $this->fenom->compileCode('{if "" === true|join:","}equal{/if}');
$this->assertEquals("equal", $tpl->fetch(array()));
}
public function testSplit()
{
$tpl = $this->fenom->compileCode('{if ["a", "b", "c"] === "a,b,c"|split:","}equal{/if}');
$this->assertEquals("equal", $tpl->fetch(array()));
}
public function testSplitArray()
{
$tpl = $this->fenom->compileCode('{if ["a", "b", "c"] === ["a", "b", "c"]|split:","}equal{/if}');
$this->assertEquals("equal", $tpl->fetch(array()));
}
public function testSplitOther()
{
$tpl = $this->fenom->compileCode('{if [] === true|split:","}equal{/if}');
$this->assertEquals("equal", $tpl->fetch(array()));
}
public function testESplit()
{
$tpl = $this->fenom->compileCode('{if ["a", "b", "c"] === "a:b:c"|esplit:"/:/"}equal{/if}');
$this->assertEquals("equal", $tpl->fetch(array()));
}
public function testESplitArray()
{
$tpl = $this->fenom->compileCode('{if ["a", "b", "c"] === ["a", "b", "c"]|esplit:"/:/"}equal{/if}');
$this->assertEquals("equal", $tpl->fetch(array()));
}
public function testESplitOther()
{
$tpl = $this->fenom->compileCode('{if [] === true|esplit:"/:/"}equal{/if}');
$this->assertEquals("equal", $tpl->fetch(array()));
}
public function testReplace()
{
$tpl = $this->fenom->compileCode('{if "a;c" === "a,b,c"|replace:",b,":";"}equal{/if}');
$this->assertEquals("equal", $tpl->fetch(array()));
}
public function testEReplace()
{
$tpl = $this->fenom->compileCode('{if "a;c" === "a,b,c"|ereplace:"/,b,?/miS":";"}equal{/if}');
$this->assertEquals("equal", $tpl->fetch(array()));
}
public function testMatch()
{
$tpl = $this->fenom->compileCode('{if "a,b,c"|match:"a,[bd]*c":";"}match{/if}');
$this->assertEquals("match", $tpl->fetch(array()));
}
public function testEMatch()
{
$tpl = $this->fenom->compileCode('{if "a,b,c"|ematch:"/^a,[bd].*?c$/":";"}match{/if}');
$this->assertEquals("match", $tpl->fetch(array()));
}
}

View File

@ -163,6 +163,7 @@ class TemplateTest extends TestCase
array('Mod: {$rescue|escape:"html"}!', $b, 'Mod: Chip & Dale!'),
array('Mod: {$rescue|escape:"url"}!', $b, 'Mod: Chip+%26+Dale!'),
array('Mod: {$rescue|escape:"unknown"}!', $b, 'Mod: Chip & Dale!'),
array('Mod: {$rescue|escape:"js"}!', $b, 'Mod: "Chip & Dale"!'),
array('Mod: {$rescue_html|unescape}!', $b, 'Mod: Chip & Dale!'),
array('Mod: {$rescue_html|unescape:"html"}!', $b, 'Mod: Chip & Dale!'),
array('Mod: {$rescue_url|unescape:"url"}!', $b, 'Mod: Chip & Dale!'),