From 0e5ff9f64a665fbf50ea8dc6f1b0023bb0ad1776 Mon Sep 17 00:00:00 2001 From: Yuri Kuznetsov Date: Fri, 11 Feb 2022 13:44:56 +0200 Subject: [PATCH] object functions --- .../Functions/JsonGroup/EncodeType.php | 49 +++++++ .../Functions/ObjectGroup/CloneDeepType.php | 55 ++++++++ .../Functions/ObjectGroup/CreateType.php | 41 ++++++ .../Formula/Functions/ObjectGroup/GetType.php | 58 ++++++++ .../Formula/Functions/ObjectGroup/HasType.php | 58 ++++++++ .../Formula/Functions/ObjectGroup/SetType.php | 65 +++++++++ .../Espo/Resources/metadata/app/formula.json | 30 ++++ .../unit/Espo/Core/Formula/EvaluatorTest.php | 133 ++++++++++++++++++ 8 files changed, 489 insertions(+) create mode 100644 application/Espo/Core/Formula/Functions/JsonGroup/EncodeType.php create mode 100644 application/Espo/Core/Formula/Functions/ObjectGroup/CloneDeepType.php create mode 100644 application/Espo/Core/Formula/Functions/ObjectGroup/CreateType.php create mode 100644 application/Espo/Core/Formula/Functions/ObjectGroup/GetType.php create mode 100644 application/Espo/Core/Formula/Functions/ObjectGroup/HasType.php create mode 100644 application/Espo/Core/Formula/Functions/ObjectGroup/SetType.php diff --git a/application/Espo/Core/Formula/Functions/JsonGroup/EncodeType.php b/application/Espo/Core/Formula/Functions/JsonGroup/EncodeType.php new file mode 100644 index 0000000000..60c9afa976 --- /dev/null +++ b/application/Espo/Core/Formula/Functions/JsonGroup/EncodeType.php @@ -0,0 +1,49 @@ +throwTooFewArguments(); + } + + $value = $this->evaluate($args[0]); + + return Json::encode($value); + } +} diff --git a/application/Espo/Core/Formula/Functions/ObjectGroup/CloneDeepType.php b/application/Espo/Core/Formula/Functions/ObjectGroup/CloneDeepType.php new file mode 100644 index 0000000000..cf30e14ddf --- /dev/null +++ b/application/Espo/Core/Formula/Functions/ObjectGroup/CloneDeepType.php @@ -0,0 +1,55 @@ +throwTooFewArguments(1); + } + + $obj = $this->evaluate($args[0]); + + if (!$obj instanceof stdClass) { + $this->throwBadArgumentType(1, 'object'); + } + + return ObjectUtil::clone($obj); + } +} diff --git a/application/Espo/Core/Formula/Functions/ObjectGroup/CreateType.php b/application/Espo/Core/Formula/Functions/ObjectGroup/CreateType.php new file mode 100644 index 0000000000..05f3138f4f --- /dev/null +++ b/application/Espo/Core/Formula/Functions/ObjectGroup/CreateType.php @@ -0,0 +1,41 @@ +throwTooFewArguments(2); + } + + $obj = $this->evaluate($args[0]); + $key = $this->evaluate($args[1]); + + if (!$obj instanceof stdClass) { + $this->throwBadArgumentType(1, 'object'); + } + + if ($key === null) { + $this->throwBadArgumentType(2); + } + + return $obj->$key ?? null; + } +} diff --git a/application/Espo/Core/Formula/Functions/ObjectGroup/HasType.php b/application/Espo/Core/Formula/Functions/ObjectGroup/HasType.php new file mode 100644 index 0000000000..4f10a8279c --- /dev/null +++ b/application/Espo/Core/Formula/Functions/ObjectGroup/HasType.php @@ -0,0 +1,58 @@ +throwTooFewArguments(2); + } + + $obj = $this->evaluate($args[0]); + $key = $this->evaluate($args[1]); + + if (!$obj instanceof stdClass) { + $this->throwBadArgumentType(1, 'object'); + } + + if ($key === null) { + $this->throwBadArgumentType(2); + } + + return property_exists($obj, $key); + } +} diff --git a/application/Espo/Core/Formula/Functions/ObjectGroup/SetType.php b/application/Espo/Core/Formula/Functions/ObjectGroup/SetType.php new file mode 100644 index 0000000000..3522ac5cc2 --- /dev/null +++ b/application/Espo/Core/Formula/Functions/ObjectGroup/SetType.php @@ -0,0 +1,65 @@ +throwTooFewArguments(3); + } + + $obj = $this->evaluate($args[0]); + $key = $this->evaluate($args[1]); + $value = $this->evaluate($args[2]); + + if (!$obj instanceof stdClass) { + $this->throwBadArgumentType(1, 'object'); + } + + if ($key === null) { + $this->throwBadArgumentType(2); + } + + $clonedObj = ObjectUtil::clone($obj); + + $clonedObj->$key = $value; + + return $clonedObj; + } +} diff --git a/application/Espo/Resources/metadata/app/formula.json b/application/Espo/Resources/metadata/app/formula.json index db9ad0a8ff..9ecd700f94 100644 --- a/application/Espo/Resources/metadata/app/formula.json +++ b/application/Espo/Resources/metadata/app/formula.json @@ -339,6 +339,31 @@ "insertText": "util\\generateId()", "returnType": "string" }, + { + "name": "object\\create", + "insertText": "object\\create()", + "returnType": "object" + }, + { + "name": "object\\get", + "insertText": "object\\get(OBJECT, KEY)", + "returnType": "mixed" + }, + { + "name": "object\\has", + "insertText": "object\\has(OBJECT, KEY)", + "returnType": "bool" + }, + { + "name": "object\\set", + "insertText": "object\\set(OBJECT, KEY, VALUE)", + "returnType": "object" + }, + { + "name": "object\\cloneDeep", + "insertText": "object\\cloneDeep(OBJECT)", + "returnType": "object" + }, { "name": "password\\generate", "insertText": "password\\generate()", @@ -388,6 +413,11 @@ "insertText": "json\\retrieve(JSON, PATH)", "returnType": "mixed" }, + { + "name": "json\\encode", + "insertText": "json\\encode(VALUE)", + "returnType": "string" + }, { "name": "ext\\email\\send", "insertText": "ext\\email\\send(EMAIL_ID)", diff --git a/tests/unit/Espo/Core/Formula/EvaluatorTest.php b/tests/unit/Espo/Core/Formula/EvaluatorTest.php index 3132d79fa1..e14a095b8f 100644 --- a/tests/unit/Espo/Core/Formula/EvaluatorTest.php +++ b/tests/unit/Espo/Core/Formula/EvaluatorTest.php @@ -764,4 +764,137 @@ class EvaluatorTest extends \PHPUnit\Framework\TestCase $this->evaluator->process($expression, null) ); } + + public function testObjectCreate(): void + { + $expression = "object\\create()"; + + $this->assertEquals( + (object) [], + $this->evaluator->process($expression, null) + ); + } + + public function testObjectSet(): void + { + $expression = " + \$o1 = object\\create(); + \$o2 = object\\set(\$o1, 'key', 'value'); + "; + + $vars = (object) []; + + $this->evaluator->process($expression, null, $vars); + + $this->assertNotEquals( + $vars->o1, + $vars->o2 + ); + + $this->assertEquals( + 'value', + $vars->o2->key + ); + } + + public function testObjectGet1(): void + { + $expression = " + \$o = object\\create(); + \$o = object\\set(\$o, 'key', 'value'); + \$v = object\\get(\$o, 'key'); + "; + + $vars = (object) []; + + $this->evaluator->process($expression, null, $vars); + + $this->assertEquals( + 'value', + $vars->o->key + ); + } + + public function testObjectGet2(): void + { + $expression = " + \$o = object\\create(); + \$v = object\\get(\$o, 'key'); + "; + + $vars = (object) []; + + $this->evaluator->process($expression, null, $vars); + + $this->assertEquals( + null, + $vars->v + ); + } + + public function testObjectHas1(): void + { + $expression = " + object\\has( + object\\set(object\\create(), 'key', 'value'), + 'key' + ) + "; + + $this->assertEquals( + true, + $this->evaluator->process($expression, null) + ); + } + + public function testObjectHas2(): void + { + $expression = " + object\\has( + object\\create(), + 'key' + ) + "; + + $this->assertEquals( + false, + $this->evaluator->process($expression, null) + ); + } + + public function testObjectClone(): void + { + $expression = " + \$o1 = object\\create(); + \$o2 = object\\cloneDeep(\$o1); + "; + + $vars = (object) []; + + $this->evaluator->process($expression, null, $vars); + + $this->assertEquals( + $vars->o1, + $vars->o2 + ); + + $this->assertNotSame( + $vars->o1, + $vars->o2 + ); + } + + public function testJsonEncode(): void + { + $expression = " + json\\encode( + object\\set(object\\create(), 'key', 'value') + ) + "; + + $this->assertEquals( + "{\"key\":\"value\"}", + $this->evaluator->process($expression, null) + ); + } }