From f4b2d9b1df89410bd557c5e77dae7e6da97c24ed Mon Sep 17 00:00:00 2001 From: Yuri Kuznetsov Date: Wed, 15 Jul 2020 12:39:59 +0300 Subject: [PATCH] formula functions change --- .../Core/Formula/Functions/BaseFunction.php | 22 ++++++++++++++--- .../StringGroup/ConcatenationType.php | 11 ++++++--- .../Functions/StringGroup/LengthType.php | 15 +++++++----- .../Functions/StringGroup/LowerCaseType.php | 15 +++++++----- .../Functions/StringGroup/MatchAllType.php | 15 ++++++++---- .../Functions/StringGroup/MatchType.php | 15 ++++++++---- .../Formula/Functions/StringGroup/PadType.php | 24 +++++++++++++------ .../Formula/Functions/StringGroup/PosType.php | 19 +++++++++------ .../Functions/StringGroup/ReplaceType.php | 22 ++++++++++------- .../Functions/StringGroup/SubstringType.php | 23 +++++++++++------- .../Functions/StringGroup/TestType.php | 19 +++++++++------ .../Functions/StringGroup/TrimType.php | 17 ++++++++----- .../Functions/StringGroup/UpperCaseType.php | 16 ++++++++----- .../unit/Espo/Core/Formula/EvaluatorTest.php | 9 +++++++ tests/unit/Espo/Core/Formula/FormulaTest.php | 5 +++- 15 files changed, 167 insertions(+), 80 deletions(-) diff --git a/application/Espo/Core/Formula/Functions/BaseFunction.php b/application/Espo/Core/Formula/Functions/BaseFunction.php index 93f784c5fc..2ab9b7d554 100644 --- a/application/Espo/Core/Formula/Functions/BaseFunction.php +++ b/application/Espo/Core/Formula/Functions/BaseFunction.php @@ -41,6 +41,8 @@ use Espo\Core\Formula\{ Exceptions\NotPassedEntity, }; +use Espo\Core\Utils\Log; + use StdClass; abstract class BaseFunction @@ -53,6 +55,8 @@ abstract class BaseFunction protected $name; + protected $log; + protected function getVariables() : StdClass { return $this->variables; @@ -66,12 +70,14 @@ abstract class BaseFunction return $this->entity; } - public function __construct(string $name, Processor $processor, ?Entity $entity = null, ?StdClass $variables = null) - { + public function __construct( + string $name, Processor $processor, ?Entity $entity = null, ?StdClass $variables = null, ?Log $log = null + ) { $this->name = $name; $this->processor = $processor; $this->entity = $entity; $this->variables = $variables; + $this->log = $log; } /** @@ -97,12 +103,22 @@ abstract class BaseFunction throw new TooFewArguments('function: ' . $this->name); } - protected function throwBadArgumentType(?int $index = null) + protected function throwBadArgumentType(?int $index = null, ?string $type = null) { $msg = 'function: ' . $this->name; if ($index !== null) { $msg .= ', index: ' . $index; + if ($type) { + $msg .= ', should be: ' . $type; + } } throw new BadArgumentType($msg); } + + protected function logBadArgumentType(int $index, string $type) + { + if (!$this->log) return; + + $this->log->warning("Formula function: {$this->name}, argument {$index} should be '{$type}'."); + } } diff --git a/application/Espo/Core/Formula/Functions/StringGroup/ConcatenationType.php b/application/Espo/Core/Formula/Functions/StringGroup/ConcatenationType.php index 53b676ff56..d41d505a05 100644 --- a/application/Espo/Core/Formula/Functions/StringGroup/ConcatenationType.php +++ b/application/Espo/Core/Formula/Functions/StringGroup/ConcatenationType.php @@ -29,13 +29,18 @@ namespace Espo\Core\Formula\Functions\StringGroup; -class ConcatenationType extends \Espo\Core\Formula\Functions\Base +use Espo\Core\Formula\{ + Functions\BaseFunction, + ArgumentList, +}; + +class ConcatenationType extends BaseFunction { - public function process(\StdClass $item) + public function process(ArgumentList $args) { $result = ''; - foreach ($item->value as $subItem) { + foreach ($args as $subItem) { $part = $this->evaluate($subItem); if (!is_string($part)) { diff --git a/application/Espo/Core/Formula/Functions/StringGroup/LengthType.php b/application/Espo/Core/Formula/Functions/StringGroup/LengthType.php index 1bcd4838aa..dc04227330 100644 --- a/application/Espo/Core/Formula/Functions/StringGroup/LengthType.php +++ b/application/Espo/Core/Formula/Functions/StringGroup/LengthType.php @@ -29,17 +29,20 @@ namespace Espo\Core\Formula\Functions\StringGroup; -use Espo\Core\Exceptions\Error; +use Espo\Core\Formula\{ + Functions\BaseFunction, + ArgumentList, +}; -class LengthType extends \Espo\Core\Formula\Functions\Base +class LengthType extends BaseFunction { - public function process(\StdClass $item) + public function process(ArgumentList $args) { - if (count($item->value) < 1) { - throw new Error(); + if (count($args) < 1) { + $this->throwTooFewArguments(); } - $value = $this->evaluate($item->value[0]); + $value = $this->evaluate($args[0]); if (!is_string($value)) { $value = strval($value); diff --git a/application/Espo/Core/Formula/Functions/StringGroup/LowerCaseType.php b/application/Espo/Core/Formula/Functions/StringGroup/LowerCaseType.php index ae64e17d36..88fbb93ea0 100644 --- a/application/Espo/Core/Formula/Functions/StringGroup/LowerCaseType.php +++ b/application/Espo/Core/Formula/Functions/StringGroup/LowerCaseType.php @@ -29,17 +29,20 @@ namespace Espo\Core\Formula\Functions\StringGroup; -use Espo\Core\Exceptions\Error; +use Espo\Core\Formula\{ + Functions\BaseFunction, + ArgumentList, +}; -class LowerCaseType extends \Espo\Core\Formula\Functions\Base +class LowerCaseType extends BaseFunction { - public function process(\StdClass $item) + public function process(ArgumentList $args) { - if (count($item->value) < 1) { - throw new Error(); + if (count($args) < 1) { + $this->throwTooFewArguments(); } - $value = $this->evaluate($item->value[0]); + $value = $this->evaluate($args[0]); if (!is_string($value)) { $value = strval($value); diff --git a/application/Espo/Core/Formula/Functions/StringGroup/MatchAllType.php b/application/Espo/Core/Formula/Functions/StringGroup/MatchAllType.php index 0c498f7392..0e54759f8c 100644 --- a/application/Espo/Core/Formula/Functions/StringGroup/MatchAllType.php +++ b/application/Espo/Core/Formula/Functions/StringGroup/MatchAllType.php @@ -29,15 +29,20 @@ namespace Espo\Core\Formula\Functions\StringGroup; -use Espo\Core\Exceptions\Error; +use Espo\Core\Formula\{ + Functions\BaseFunction, + ArgumentList, +}; -class MatchAllType extends \Espo\Core\Formula\Functions\Base +class MatchAllType extends BaseFunction { - public function process(\StdClass $item) + public function process(ArgumentList $args) { - $args = $this->fetchArguments($item); + $args = $this->evaluate($args); - if (count($args) < 2) throw new Error("string\\matchAll: Too few arguments."); + if (count($args) < 2) { + $this->throwTooFewArguments(); + } $string = $args[0]; $regexp = $args[1]; diff --git a/application/Espo/Core/Formula/Functions/StringGroup/MatchType.php b/application/Espo/Core/Formula/Functions/StringGroup/MatchType.php index 6c0aa63b02..e8ffc13b08 100644 --- a/application/Espo/Core/Formula/Functions/StringGroup/MatchType.php +++ b/application/Espo/Core/Formula/Functions/StringGroup/MatchType.php @@ -29,15 +29,20 @@ namespace Espo\Core\Formula\Functions\StringGroup; -use Espo\Core\Exceptions\Error; +use Espo\Core\Formula\{ + Functions\BaseFunction, + ArgumentList, +}; -class MatchType extends \Espo\Core\Formula\Functions\Base +class MatchType extends BaseFunction { - public function process(\StdClass $item) + public function process(ArgumentList $args) { - $args = $this->fetchArguments($item); + $args = $this->evaluate($args); - if (count($args) < 2) throw new Error("string\\match: Too few arguments."); + if (count($args) < 2) { + $this->throwTooFewArguments(); + } $string = $args[0]; $regexp = $args[1]; diff --git a/application/Espo/Core/Formula/Functions/StringGroup/PadType.php b/application/Espo/Core/Formula/Functions/StringGroup/PadType.php index f66657ebc3..da84e6ed4e 100644 --- a/application/Espo/Core/Formula/Functions/StringGroup/PadType.php +++ b/application/Espo/Core/Formula/Functions/StringGroup/PadType.php @@ -29,23 +29,33 @@ namespace Espo\Core\Formula\Functions\StringGroup; -use Espo\Core\Exceptions\Error; +use Espo\Core\Formula\{ + Functions\BaseFunction, + ArgumentList, +}; -class PadType extends \Espo\Core\Formula\Functions\Base +class PadType extends BaseFunction { - public function process(\StdClass $item) + public function process(ArgumentList $args) { - $args = $this->fetchArguments($item); + $args = $this->evaluate($args); - if (count($args) < 2) throw new Error("string\\pad: should have at least 2 arguments."); + if (count($args) < 2) { + $this->throwTooFewArguments(); + } $input = $args[0]; $length = $args[1]; $string = $args[2] ?? ' '; $type = $args[3] ?? 'right'; - if (!is_string($input)) $input = strval($input); - if (!is_int($length)) throw new Error("string\\pad: second argument should be integer."); + if (!is_string($input)) { + $input = strval($input); + } + + if (!is_int($length)) { + $this->throwBadArgumentType(2); + } $map = [ 'right' => \STR_PAD_RIGHT, diff --git a/application/Espo/Core/Formula/Functions/StringGroup/PosType.php b/application/Espo/Core/Formula/Functions/StringGroup/PosType.php index 5437fda3b3..d90d391b7b 100644 --- a/application/Espo/Core/Formula/Functions/StringGroup/PosType.php +++ b/application/Espo/Core/Formula/Functions/StringGroup/PosType.php @@ -29,18 +29,23 @@ namespace Espo\Core\Formula\Functions\StringGroup; -use Espo\Core\Exceptions\Error; +use Espo\Core\Formula\{ + Functions\BaseFunction, + ArgumentList, +}; -class PosType extends \Espo\Core\Formula\Functions\Base +class PosType extends BaseFunction { - public function process(\StdClass $item) + public function process(ArgumentList $args) { - $args = $item->value ?? []; + $args = $this->evaluate($args); - if (count($args) < 2) throw new Error("Bad arguments passed to function string\\pos."); + if (count($args) < 2) { + $this->throwTooFewArguments(); + } - $string = $this->evaluate($args[0]); - $needle = $this->evaluate($args[1]); + $string = $args[0]; + $needle = $args[1]; if (!is_string($string)) { return false; diff --git a/application/Espo/Core/Formula/Functions/StringGroup/ReplaceType.php b/application/Espo/Core/Formula/Functions/StringGroup/ReplaceType.php index ff6fbb3622..0ee1930ece 100644 --- a/application/Espo/Core/Formula/Functions/StringGroup/ReplaceType.php +++ b/application/Espo/Core/Formula/Functions/StringGroup/ReplaceType.php @@ -29,36 +29,40 @@ namespace Espo\Core\Formula\Functions\StringGroup; -use Espo\Core\Exceptions\Error; +use Espo\Core\Formula\{ + Functions\BaseFunction, + ArgumentList, +}; -class ReplaceType extends \Espo\Core\Formula\Functions\Base +class ReplaceType extends BaseFunction { - public function process(\StdClass $item) + public function process(ArgumentList $args) { - $args = $this->fetchArguments($item); + $args = $this->evaluate($args); - if (count($args) < 3) throw new Error("string\\replace: Too few arguments."); + if (count($args) < 3) { + $this->throwTooFewArguments(); + }; $string = $args[0]; $search = $args[1]; $replace = $args[2]; if (!is_string($string)) { - $GLOBALS['log']->warning("string\\replace: 1st argument should be string."); + $this->logBadArgumentType(1, 'string'); return ''; } if (!is_string($search)) { - $GLOBALS['log']->warning("string\\replace: 2nd argument should be string."); + $this->logBadArgumentType(2, 'string'); return $string; } if (!is_string($replace)) { - $GLOBALS['log']->warning("string\\replace: 3rd argument should be string."); + $this->logBadArgumentType(3, 'string'); return $string; } return str_replace($search, $replace, $string); } } - diff --git a/application/Espo/Core/Formula/Functions/StringGroup/SubstringType.php b/application/Espo/Core/Formula/Functions/StringGroup/SubstringType.php index 1a2027c106..aa34aedb1c 100644 --- a/application/Espo/Core/Formula/Functions/StringGroup/SubstringType.php +++ b/application/Espo/Core/Formula/Functions/StringGroup/SubstringType.php @@ -29,21 +29,26 @@ namespace Espo\Core\Formula\Functions\StringGroup; -use Espo\Core\Exceptions\Error; +use Espo\Core\Formula\{ + Functions\BaseFunction, + ArgumentList, +}; -class SubstringType extends \Espo\Core\Formula\Functions\Base +class SubstringType extends BaseFunction { - public function process(\StdClass $item) + public function process(ArgumentList $args) { - if (count($item->value) < 2) { - throw new Error("string\\substring: too few arguments."); + $args = $this->evaluate($args); + + if (count($args) < 2) { + $this->throwTooFewArguments(); } - $string = $this->evaluate($item->value[0]); - $start = $this->evaluate($item->value[1]); + $string = $args[0]; + $start = $args[1]; - if (count($item->value) > 2) { - $length = $this->evaluate($item->value[2]); + if (count($args) > 2) { + $length = $args[2]; return mb_substr($string, $start, $length); } else { return mb_substr($string, $start); diff --git a/application/Espo/Core/Formula/Functions/StringGroup/TestType.php b/application/Espo/Core/Formula/Functions/StringGroup/TestType.php index d37a76899b..091020108d 100644 --- a/application/Espo/Core/Formula/Functions/StringGroup/TestType.php +++ b/application/Espo/Core/Formula/Functions/StringGroup/TestType.php @@ -29,18 +29,23 @@ namespace Espo\Core\Formula\Functions\StringGroup; -use Espo\Core\Exceptions\Error; +use Espo\Core\Formula\{ + Functions\BaseFunction, + ArgumentList, +}; -class TestType extends \Espo\Core\Formula\Functions\Base +class TestType extends BaseFunction { - public function process(\StdClass $item) + public function process(ArgumentList $args) { - if (count($item->value) < 2) { - throw new Error('string\\test: too few arguments.'); + $args = $this->evaluate($args); + + if (count($args) < 2) { + $this->throwTooFewArguments(); } - $string = $this->evaluate($item->value[0]); - $regexp = $this->evaluate($item->value[1]); + $string = $args[0]; + $regexp = $args[1]; if (!is_string($string)) { return false; diff --git a/application/Espo/Core/Formula/Functions/StringGroup/TrimType.php b/application/Espo/Core/Formula/Functions/StringGroup/TrimType.php index 3399d5face..928cd9c3d6 100644 --- a/application/Espo/Core/Formula/Functions/StringGroup/TrimType.php +++ b/application/Espo/Core/Formula/Functions/StringGroup/TrimType.php @@ -29,17 +29,22 @@ namespace Espo\Core\Formula\Functions\StringGroup; -use Espo\Core\Exceptions\Error; +use Espo\Core\Formula\{ + Functions\BaseFunction, + ArgumentList, +}; -class TrimType extends \Espo\Core\Formula\Functions\Base +class TrimType extends BaseFunction { - public function process(\StdClass $item) + public function process(ArgumentList $args) { - if (count($item->value) < 1) { - throw new Error(); + $args = $this->evaluate($args); + + if (count($args) < 1) { + $this->throwTooFewArguments(); } - $value = $this->evaluate($item->value[0]); + $value = $args[0]; if (!is_string($value)) { $value = strval($value); diff --git a/application/Espo/Core/Formula/Functions/StringGroup/UpperCaseType.php b/application/Espo/Core/Formula/Functions/StringGroup/UpperCaseType.php index e9fbfe9944..229c93c523 100644 --- a/application/Espo/Core/Formula/Functions/StringGroup/UpperCaseType.php +++ b/application/Espo/Core/Formula/Functions/StringGroup/UpperCaseType.php @@ -29,18 +29,22 @@ namespace Espo\Core\Formula\Functions\StringGroup; -use Espo\Core\Exceptions\Error; +use Espo\Core\Formula\{ + Functions\BaseFunction, + ArgumentList, +}; -class UpperCaseType extends \Espo\Core\Formula\Functions\Base +class UpperCaseType extends BaseFunction { - public function process(\StdClass $item) + public function process(ArgumentList $args) { + $args = $this->evaluate($args); - if (count($item->value) < 1) { - throw new Error(); + if (count($args) < 1) { + $this->throwTooFewArguments(); } - $value = $this->evaluate($item->value[0]); + $value = $args[0]; if (!is_string($value)) { $value = strval($value); diff --git a/tests/unit/Espo/Core/Formula/EvaluatorTest.php b/tests/unit/Espo/Core/Formula/EvaluatorTest.php index 7cdd8a65ef..b10c0f66e7 100644 --- a/tests/unit/Espo/Core/Formula/EvaluatorTest.php +++ b/tests/unit/Espo/Core/Formula/EvaluatorTest.php @@ -38,6 +38,15 @@ class EvaluatorTest extends \PHPUnit\Framework\TestCase $container = $this->container = $this->getMockBuilder('\\Espo\\Core\\Container')->disableOriginalConstructor()->getMock(); + $this->log = $this->getMockBuilder('Espo\\Core\\Utils\\Log')->disableOriginalConstructor()->getMock(); + + $container + ->expects($this->any()) + ->method('get') + ->will($this->returnValueMap([ + ['log', $this->log], + ])); + $injectableFactory = $injectableFactory = new \Espo\Core\InjectableFactory($container); $this->evaluator = new \Espo\Core\Formula\Evaluator($injectableFactory); diff --git a/tests/unit/Espo/Core/Formula/FormulaTest.php b/tests/unit/Espo/Core/Formula/FormulaTest.php index 2e03008388..6ab1af2dd3 100644 --- a/tests/unit/Espo/Core/Formula/FormulaTest.php +++ b/tests/unit/Espo/Core/Formula/FormulaTest.php @@ -63,6 +63,8 @@ class FormulaTest extends \PHPUnit\Framework\TestCase $this->user = $this->getMockBuilder('Espo\\Entities\\User')->disableOriginalConstructor()->getMock(); + $this->log = $this->getMockBuilder('Espo\\Core\\Utils\\Log')->disableOriginalConstructor()->getMock(); + $this->user->id = '1'; $this->user @@ -80,7 +82,8 @@ class FormulaTest extends \PHPUnit\Framework\TestCase ['dateTime', $this->dateTime], ['number', $this->number], ['config', $this->config], - ['user', $this->user] + ['user', $this->user], + ['log', $this->log], ])); }