From b91b0efaaf1912121489e209b1a71319c61003a8 Mon Sep 17 00:00:00 2001 From: Lonnie Ezell Date: Tue, 27 Feb 2018 00:11:56 -0600 Subject: [PATCH] Added local_number view parser filter for #536 --- system/Config/View.php | 61 +-- system/View/Filters.php | 370 ++++++++++-------- tests/system/View/ParserFilterTest.php | 57 +++ user_guide_src/source/general/view_parser.rst | 3 + 4 files changed, 291 insertions(+), 200 deletions(-) diff --git a/system/Config/View.php b/system/Config/View.php index cf3037de1a9b..539338cdf230 100644 --- a/system/Config/View.php +++ b/system/Config/View.php @@ -27,45 +27,46 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * - * @package CodeIgniter - * @author CodeIgniter Dev Team - * @copyright 2014-2018 British Columbia Institute of Technology (https://bcit.ca/) - * @license https://opensource.org/licenses/MIT MIT License - * @link https://codeigniter.com - * @since Version 3.0.0 + * @package CodeIgniter + * @author CodeIgniter Dev Team + * @copyright 2014-2018 British Columbia Institute of Technology (https://bcit.ca/) + * @license https://opensource.org/licenses/MIT MIT License + * @link https://codeigniter.com + * @since Version 4.0.0 * @filesource */ class View extends BaseConfig { protected $coreFilters = [ - 'abs' => '\abs', - 'capitalize' => '\CodeIgniter\View\Filters::capitalize', - 'date' => '\CodeIgniter\View\Filters::date', - 'date_modify' => '\CodeIgniter\View\Filters::date_modify', - 'default' => '\CodeIgniter\View\Filters::default', - 'esc' => '\CodeIgniter\View\Filters::esc', - 'excerpt' => '\CodeIgniter\View\Filters::excerpt', - 'highlight' => '\CodeIgniter\View\Filters::highlight', + 'abs' => '\abs', + 'capitalize' => '\CodeIgniter\View\Filters::capitalize', + 'date' => '\CodeIgniter\View\Filters::date', + 'date_modify' => '\CodeIgniter\View\Filters::date_modify', + 'default' => '\CodeIgniter\View\Filters::default', + 'esc' => '\CodeIgniter\View\Filters::esc', + 'excerpt' => '\CodeIgniter\View\Filters::excerpt', + 'highlight' => '\CodeIgniter\View\Filters::highlight', 'highlight_code' => '\CodeIgniter\View\Filters::highlight_code', - 'limit_words' => '\CodeIgniter\View\Filters::limit_words', - 'limit_chars' => '\CodeIgniter\View\Filters::limit_chars', - 'lower' => '\strtolower', - 'nl2br' => '\CodeIgniter\View\Filters::nl2br', - 'number_format' => '\number_format', - 'prose' => '\CodeIgniter\View\Filters::prose', - 'round' => '\CodeIgniter\View\Filters::round', - 'strip_tags' => '\strip_tags', - 'title' => '\CodeIgniter\View\Filters::title', - 'upper' => '\strtoupper', + 'limit_words' => '\CodeIgniter\View\Filters::limit_words', + 'limit_chars' => '\CodeIgniter\View\Filters::limit_chars', + 'local_number' => '\CodeIgniter\View\Filters::local_number', + 'lower' => '\strtolower', + 'nl2br' => '\CodeIgniter\View\Filters::nl2br', + 'number_format' => '\number_format', + 'prose' => '\CodeIgniter\View\Filters::prose', + 'round' => '\CodeIgniter\View\Filters::round', + 'strip_tags' => '\strip_tags', + 'title' => '\CodeIgniter\View\Filters::title', + 'upper' => '\strtoupper', ]; protected $corePlugins = [ - 'current_url' => '\CodeIgniter\View\Plugins::currentURL', - 'previous_url' => '\CodeIgniter\View\Plugins::previousURL', - 'mailto' => '\CodeIgniter\View\Plugins::mailto', - 'safe_mailto' => '\CodeIgniter\View\Plugins::safeMailto', - 'lang' => '\CodeIgniter\View\Plugins::lang', - 'validation_errors' => '\CodeIgniter\View\Plugins::validationErrors', + 'current_url' => '\CodeIgniter\View\Plugins::currentURL', + 'previous_url' => '\CodeIgniter\View\Plugins::previousURL', + 'mailto' => '\CodeIgniter\View\Plugins::mailto', + 'safe_mailto' => '\CodeIgniter\View\Plugins::safeMailto', + 'lang' => '\CodeIgniter\View\Plugins::lang', + 'validation_errors' => '\CodeIgniter\View\Plugins::validationErrors', ]; public function __construct() diff --git a/system/View/Filters.php b/system/View/Filters.php index 8def5aba861e..d096280b754e 100644 --- a/system/View/Filters.php +++ b/system/View/Filters.php @@ -27,12 +27,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * - * @package CodeIgniter - * @author CodeIgniter Dev Team - * @copyright 2014-2018 British Columbia Institute of Technology (https://bcit.ca/) - * @license https://opensource.org/licenses/MIT MIT License - * @link https://codeigniter.com - * @since Version 3.0.0 + * @package CodeIgniter + * @author CodeIgniter Dev Team + * @copyright 2014-2018 British Columbia Institute of Technology (https://bcit.ca/) + * @license https://opensource.org/licenses/MIT MIT License + * @link https://codeigniter.com + * @since Version 3.0.0 * @filesource */ class Filters @@ -88,6 +88,7 @@ public static function date($value, string $format): string public static function date_modify($value, string $adjustment): string { $value = self::date($value, 'Y-m-d H:i:s'); + return strtotime($adjustment, strtotime($value)); } @@ -103,204 +104,233 @@ public static function date_modify($value, string $adjustment): string */ public static function default($value, string $default): string { - return empty($value) - ? $default - : $value; -} - -//-------------------------------------------------------------------- - -/** - * Escapes the given value with our `esc()` helper function. - * - * @param $value - * @param string $context - * - * @return string - */ -public static function esc($value, string $context = 'html'): string -{ - return esc($value, $context); -} + return empty($value) + ? $default + : $value; + } -//-------------------------------------------------------------------- + //-------------------------------------------------------------------- -/** - * Returns an excerpt of the given string. - * - * @param string $value - * @param string $phrase - * @param int $radius - * - * @return string - */ -public static function excerpt(string $value, string $phrase, int $radius = 100): string -{ - helper('text'); + /** + * Escapes the given value with our `esc()` helper function. + * + * @param $value + * @param string $context + * + * @return string + */ + public static function esc($value, string $context = 'html'): string + { + return esc($value, $context); + } - return excerpt($value, $phrase, $radius); -} + //-------------------------------------------------------------------- -//-------------------------------------------------------------------- + /** + * Returns an excerpt of the given string. + * + * @param string $value + * @param string $phrase + * @param int $radius + * + * @return string + */ + public static function excerpt(string $value, string $phrase, int $radius = 100): string + { + helper('text'); -/** - * Highlights a given phrase within the text using '' tags. - * - * @param string $value - * @param string $phrase - * - * @return string - */ -public static function highlight(string $value, string $phrase): string -{ - helper('text'); + return excerpt($value, $phrase, $radius); + } - return highlight_phrase($value, $phrase); -} + //-------------------------------------------------------------------- -//-------------------------------------------------------------------- + /** + * Highlights a given phrase within the text using '' tags. + * + * @param string $value + * @param string $phrase + * + * @return string + */ + public static function highlight(string $value, string $phrase): string + { + helper('text'); -/** - * Highlights code samples with HTML/CSS. - * - * @param $value - * - * @return string - */ -public static function highlight_code($value): string -{ - helper('text'); + return highlight_phrase($value, $phrase); + } - return highlight_code($value); -} + //-------------------------------------------------------------------- -//-------------------------------------------------------------------- + /** + * Highlights code samples with HTML/CSS. + * + * @param $value + * + * @return string + */ + public static function highlight_code($value): string + { + helper('text'); -/** - * Limits the number of chracters to $limit, and trails of with an ellipsis. - * Will break at word break so may be more or less than $limit. - * - * @param $value - * @param int $limit - * - * @return string - */ -public static function limit_chars($value, int $limit = 500): string -{ - helper('text'); + return highlight_code($value); + } - return character_limiter($value, $limit); -} + //-------------------------------------------------------------------- -//-------------------------------------------------------------------- + /** + * Limits the number of chracters to $limit, and trails of with an ellipsis. + * Will break at word break so may be more or less than $limit. + * + * @param $value + * @param int $limit + * + * @return string + */ + public static function limit_chars($value, int $limit = 500): string + { + helper('text'); -/** - * Limits the number of words to $limit, and trails of with an ellipsis. - * - * @param $value - * @param int $limit - * - * @return string - */ -public static function limit_words($value, int $limit = 100): string -{ - helper('text'); + return character_limiter($value, $limit); + } - return word_limiter($value, $limit); -} + //-------------------------------------------------------------------- -//-------------------------------------------------------------------- + /** + * Limits the number of words to $limit, and trails of with an ellipsis. + * + * @param $value + * @param int $limit + * + * @return string + */ + public static function limit_words($value, int $limit = 100): string + { + helper('text'); -/** - * Returns a string with all instances of newline character (\n) - * converted to an HTML
tag. - * - * @param string $value - * - * @return string - */ -public static function nl2br(string $value): string -{ - $typography = \Config\Services::typography(); + return word_limiter($value, $limit); + } - return $typography->nl2brExceptPre($value); -} + //-------------------------------------------------------------------- + /** + * Returns the $value displayed in the current + * + * @param $value + * @param int $precision + * @param string $type + * @param string|null $locale + * + * @return string + */ + public static function local_number($value, string $type='decimal', $precision=4, string $locale = null): string + { + helper('number'); + + $types = [ + 'decimal' => \NumberFormatter::DECIMAL, + 'currency' => \NumberFormatter::CURRENCY, + 'percent' => \NumberFormatter::PERCENT, + 'scientific' => \NumberFormatter::SCIENTIFIC, + 'spellout' => \NumberFormatter::SPELLOUT, + 'ordinal' => \NumberFormatter::ORDINAL, + 'duration' => \NumberFormatter::DURATION, + ]; + + return format_number($value, (int)$precision, $locale, ['type' => $types[$type]]); + } -//-------------------------------------------------------------------- + //-------------------------------------------------------------------- -/** - * Takes a body of text and uses the auto_typography() method to - * turn it into prettier, easier-to-read, prose. - * - * @param string $value - * - * @return string - */ -public static function prose(string $value): string -{ - $typography = \Config\Services::typography(); + /** + * Returns a string with all instances of newline character (\n) + * converted to an HTML
tag. + * + * @param string $value + * + * @return string + */ + public static function nl2br(string $value): string + { + $typography = \Config\Services::typography(); - return $typography->autoTypography($value); -} + return $typography->nl2brExceptPre($value); + } -//-------------------------------------------------------------------- -/** - * Rounds a given $value in one of 3 ways; - * - * - common Normal rounding - * - ceil always rounds up - * - floor always rounds down - * - * @param string $value - * @param int $precision - * @param string $type - * - * @return string - */ -public static function round($value, $precision = 2, $type = 'common') -{ + //-------------------------------------------------------------------- - if ( ! is_numeric($precision)) + /** + * Takes a body of text and uses the auto_typography() method to + * turn it into prettier, easier-to-read, prose. + * + * @param string $value + * + * @return string + */ + public static function prose(string $value): string { - $type = $precision; - $precision = 2; + $typography = \Config\Services::typography(); + + return $typography->autoTypography($value); } - switch ($type) + //-------------------------------------------------------------------- + + /** + * Rounds a given $value in one of 3 ways; + * + * - common Normal rounding + * - ceil always rounds up + * - floor always rounds down + * + * @param string $value + * @param int $precision + * @param string $type + * + * @return string + */ + public static function round($value, $precision = 2, $type = 'common') { - case 'common': - return round($value, $precision); - break; - case 'ceil': - return ceil($value); - break; - case 'floor': - return floor($value); - break; - } - // Still here, just return the value. - return $value; -} + if (! is_numeric($precision)) + { + $type = $precision; + $precision = 2; + } + switch ($type) + { + case 'common': + return round($value, $precision); + break; + case 'ceil': + return ceil($value); + break; + case 'floor': + return floor($value); + break; + } -//-------------------------------------------------------------------- + // Still here, just return the value. + return $value; + } -/** - * Returns a "title case" version of the string. - * - * @param string $value - * - * @return string - */ -public static function title(string $value): string -{ - return ucwords(strtolower($value)); -} -//-------------------------------------------------------------------- + //-------------------------------------------------------------------- + + /** + * Returns a "title case" version of the string. + * + * @param string $value + * + * @return string + */ + public static function title(string $value): string + { + return ucwords(strtolower($value)); + } + + //-------------------------------------------------------------------- } diff --git a/tests/system/View/ParserFilterTest.php b/tests/system/View/ParserFilterTest.php index 394d42f66630..0526b78725aa 100644 --- a/tests/system/View/ParserFilterTest.php +++ b/tests/system/View/ParserFilterTest.php @@ -302,4 +302,61 @@ public function testUpper() } //-------------------------------------------------------------------- + + public function testLocalNumberBase() + { + $parser = new Parser($this->config, $this->viewsDir, $this->loader); + + $data = [ + 'mynum' => 1234567.891234567890000 + ]; + + $template = '{ mynum|local_number }'; + + $parser->setData($data); + $this->assertEquals('1,234,567.8912', $parser->renderString($template)); + } + + public function testLocalNumberPrecision() + { + $parser = new Parser($this->config, $this->viewsDir, $this->loader); + + $data = [ + 'mynum' => 1234567.891234567890000 + ]; + + $template = '{ mynum|local_number(decimal,2) }'; + + $parser->setData($data); + $this->assertEquals('1,234,567.89', $parser->renderString($template)); + } + + public function testLocalNumberType() + { + $parser = new Parser($this->config, $this->viewsDir, $this->loader); + + $data = [ + 'mynum' => 1234567.891234567890000 + ]; + + + $template = '{ mynum|local_number(spellout) }'; + + $parser->setData($data); + $this->assertEquals('one million two hundred thirty-four thousand five hundred sixty-seven point eight nine one two three four six', $parser->renderString($template)); + } + + public function testLocalNumberLocale() + { + $parser = new Parser($this->config, $this->viewsDir, $this->loader); + + $data = [ + 'mynum' => 1234567.891234567890000 + ]; + + $template = '{ mynum|local_number(decimal,4,de_DE) }'; + + $parser->setData($data); + $this->assertEquals('1.234.567,8912', $parser->renderString($template)); + } } diff --git a/user_guide_src/source/general/view_parser.rst b/user_guide_src/source/general/view_parser.rst index 87676561a8ea..d8ec101a6f37 100644 --- a/user_guide_src/source/general/view_parser.rst +++ b/user_guide_src/source/general/view_parser.rst @@ -403,6 +403,9 @@ highlight phrase Highlights a given phrase within highlight_code Highlights code samples with HTML/CSS. { v|highlight_code } limit_chars limit Limits the number of chracters to $limit. { v|limit_chars(100) } limit_words limit Limits the number of words to $limit. { v|limit_words(20) } +local_number type, precision, locale Displays a localized version of a number. "type" can be one of: { v|local_number(decimal,2,en_US) } + decimal, currency, percent, scientific, spellout, ordinal, duration. + See `PHP's NumberFormatter `_ for details. lower Converts a string to lowercase. { v|lower } nl2br Replaces all newline characters (\n) to an HTML
tag. { v|nl2br } number_format places Wraps PHP **number_format** function for use within the parser. { v|number_format(3) }