From b421bbf23d7fc69ad68b2e21f4474eb4c783899e Mon Sep 17 00:00:00 2001 From: Russ Michell Date: Thu, 9 Jun 2016 21:45:55 +1200 Subject: [PATCH] W.I.P Deeper JSON structures new accepted. --- code/models/fieldtypes/JSONText.php | 34 +++++++++++++++++++++++++---- tests/JSONTextTest.php | 21 +++++++++++------- 2 files changed, 43 insertions(+), 12 deletions(-) diff --git a/code/models/fieldtypes/JSONText.php b/code/models/fieldtypes/JSONText.php index 726bf70..84e1788 100644 --- a/code/models/fieldtypes/JSONText.php +++ b/code/models/fieldtypes/JSONText.php @@ -43,7 +43,7 @@ class JSONText extends StringField private static $allowed_operators = [ 'postgres' => [ 'getByKey' => '->', // int/str type-check performed at runtime. - 'getByVal' => '<-' // int/str type-check performed at runtime. + 'getByVal' => '->>' // int/str type-check performed at runtime. ] ]; @@ -151,6 +151,7 @@ public function getValueAsIterable() new RecursiveArrayIterator(json_decode($json, true)), RecursiveIteratorIterator::SELF_FIRST ); + } /** @@ -258,6 +259,7 @@ public function nth($n) * @param string $operand * @return mixed null|array * @throws JSONTextException + * @todo How to increment an interator for each depth using $data->getDepth() and $i ?? */ public function extract($operator, $operand) { @@ -272,8 +274,9 @@ public function extract($operator, $operand) throw new JSONTextException($msg); } + $cleaned = $this->cleanFlattenedArray($data); $i = 0; - foreach ($data as $key => $val) { + foreach ($cleaned as $key => $val) { if ($marshalled = $this->marshallQuery($key, $val, $i, func_get_args())) { return $this->returnAsType($marshalled); } @@ -284,6 +287,29 @@ public function extract($operator, $operand) return $this->returnAsType([]); } + /** + * TEMPORARY - doesn't work to the extent expected anyway. + * + * @param $data + * @return array + */ + private function cleanFlattenedArray($data) + { + $flattened = iterator_to_array($data); + $cleaned = []; + foreach ($flattened as $key => $val) { + if (is_int($key)) { + continue; + } + + if (!in_array($val, $cleaned)) { + $cleaned[$key] = $val; + } + } + + return $cleaned; + } + /** * Alias of self::extract(). * @@ -326,8 +352,8 @@ private function marshallQuery($key, $val, $idx, $args) $operand ]); - if ($operator === $backendOperator) { - return $backendDBApiInst->$routine(); + if ($operator === $backendOperator && $result = $backendDBApiInst->$routine()) { + return $result; } } diff --git a/tests/JSONTextTest.php b/tests/JSONTextTest.php index 7107776..a750118 100644 --- a/tests/JSONTextTest.php +++ b/tests/JSONTextTest.php @@ -131,20 +131,25 @@ public function testNth_AsJson() public function testExtract_AsArray() { + // Hashed $field = JSONText::create('MyJSON'); $field->setValue($this->fixture['hashed']); $field->setReturnType('array'); - - // By key + $this->assertEquals(['british' => ['vauxhall', 'morris']], $field->extract('->', 'british')); - $this->assertEquals([0 => 'vauxhall'], $field->extract('->', 6)); + $this->assertEquals(['british' => ['vauxhall', 'morris']], $field->extract('->', 2)); + $this->assertEquals(['american' => ['buick', 'oldsmobile', 'ford']], $field->extract('->', 1)); $this->assertEquals([], $field->extract('->', '6')); // strict handling - // By value - // TODO: Use rewind() to get he tp-level key > val from the original iterator - $this->assertEquals(['british' => ['vauxhall', 'morris']], $field->extract('<-', 'morris')); -/* $this->assertEquals([0 => 'vauxhall'], $field->extract('<-', 6)); - $this->assertEquals([], $field->extract('->', '6')); // strict handling*/ + // Nested + $field = JSONText::create('MyJSON'); + $field->setValue($this->fixture['nested']); + $field->setReturnType('array'); + + $this->assertEquals(['planes' => ['russian' => ['antonov', 'mig'], 'french' => 'airbus']], $field->extract('->', 'planes')); + //$this->assertEquals(['planes' => ['russian' => ['antonov', 'mig'], 'french' => 'airbus']], $field->extract('->', 1)); + //$this->assertEquals(['american' => ['buick', 'oldsmobile', 'ford']], $field->extract('->', 1)); + //$this->assertEquals([], $field->extract('->', '6')); // strict handling*/ } }