diff --git a/README.md b/README.md index 101f5c5..19fb8d9 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -# SAE (Services API Engine) +# Contracts ![CircleCI (all branches)](https://img.shields.io/circleci/project/github/fmizzell/contracts.svg) [![Maintainability](https://api.codeclimate.com/v1/badges/3790fc0eeeb9dac4f0cb/maintainability)](https://codeclimate.com/github/fmizzell/contracts/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/3790fc0eeeb9dac4f0cb/test_coverage)](https://codeclimate.com/github/fmizzell/contracts/test_coverage) [![GPLv3 license](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0.en.html) -A set of interfaces. \ No newline at end of file +A set of interfaces. diff --git a/src/Conditioner.php b/src/Conditioner.php new file mode 100644 index 0000000..97084cc --- /dev/null +++ b/src/Conditioner.php @@ -0,0 +1,9 @@ + [], + 'descend' => [], + ]; + + private $conditions = []; + + public function retrieveAll(): array + { + $results = parent::retrieveAll(); + $results = $this->applyFilters($results); + $this->resetFilters(); + return $results; + } + + public function store(string $data, string $id = NULL): string + { + $this->validate($data); + return parent::store($data, $id); + } + + public function conditionByIsEqualTo(string $property, string $value) + { + $this->conditions[$property][] = $value; + } + + public function limitTo(int $number_of_items) + { + $this->limit = $number_of_items; + } + + public function offsetBy(int $offset) + { + $this->offset = $offset; + } + + public function sortByAscending(string $property) + { + $this->sorts['ascend'][] = $property; + } + + public function sortByDescending(string $property) + { + $this->sorts['descend'][] = $property; + } + + private function applyFilters(array $results) { + + if (!empty($this->conditions)) { + $results2 = []; + + foreach ($this->conditions as $property => $values) { + foreach ($values as $value) { + foreach ($results as $key => $result) { + $obj = json_decode($result); + if ($obj->{$property} == $value) { + $results2[$key] = $result; + } + } + } + } + + $results = $results2; + } + + + foreach ($this->sorts as $type => $properties) { + foreach ($properties as $property) { + usort($results, function ($a, $b) use ($property) { + return $this->compare($a, $b, $property); + }); + + if ($type == 'descend') { + $results = array_reverse($results); + } + } + } + + if ($this->limit > 0 || $this->offset > 0) { + $results = array_slice($results, $this->offset, $this->limit); + } + + return $results; + } + + private function resetFilters() { + $this->offset = 0; + $this->limit = 0; + + $this->sorts = [ + 'ascend' => [], + 'descend' => [], + ]; + + $this->conditions = []; + } + + private function validate(string $data) { + $decoded = json_decode($data); + if (is_null($decoded)) { + throw new \Exception("Only JSON strings can be stored"); + } + if (!is_object($decoded)) { + throw new \Exception("Only strings with JSON objects can be stored"); + } + } + + private function compare($a, $b, $property) { + $a = json_decode($a); + $b = json_decode($b); + return strnatcmp($a->{$property}, $b->{$property}); + } +} \ No newline at end of file diff --git a/src/Mock/Storage/Memory.php b/src/Mock/Storage/Memory.php index 17ec839..3af56f9 100644 --- a/src/Mock/Storage/Memory.php +++ b/src/Mock/Storage/Memory.php @@ -2,7 +2,11 @@ namespace Contracts\Mock\Storage; -class Memory implements \Contracts\Storage, \Contracts\BulkRetriever { +use Contracts\Storage; +use Contracts\BulkRetriever; + +class Memory implements Storage, BulkRetriever { + private $storage = []; public function retrieve(string $id): ?string @@ -20,7 +24,7 @@ public function retrieveAll(): array public function store(string $data, string $id = NULL): string { - if (!$id) { + if (!isset($id)) { throw new \Exception("An id is required to store the data."); } if (!isset($this->storage[$id])) { @@ -39,4 +43,5 @@ public function remove(string $id) } return FALSE; } + } \ No newline at end of file diff --git a/src/Offsetter.php b/src/Offsetter.php new file mode 100644 index 0000000..fcc44c0 --- /dev/null +++ b/src/Offsetter.php @@ -0,0 +1,8 @@ +assertNull($store->retrieve("1")); } + public function testStorageJsonObjectMemory() { + $objects = []; + $objects[] = << $object) { + $store->store($object, "{$index}"); + } + + $this->assertEquals(4, count($store->retrieveAll())); + + $store->offsetBy(1); + $store->limitTo(1); + + foreach ($store->retrieveAll() as $string) { + $this->assertEquals($objects[1], $string); + } + + $store->offsetBy(3); + + foreach ($store->retrieveAll() as $string) { + $this->assertEquals($objects[3], $string); + } + + $store->limitTo(1); + + foreach ($store->retrieveAll() as $string) { + $this->assertEquals($objects[0], $string); + } + + $store->sortByAscending("first"); + + $order = [0, 2, 3, 1]; + $order_index = 0; + foreach ($store->retrieveAll() as $string) { + $this->assertEquals($objects[$order[$order_index]], $string); + $order_index++; + } + + $store->sortByDescending("first"); + + $order = [1, 3, 2, 0]; + $order_index = 0; + foreach ($store->retrieveAll() as $string) { + $this->assertEquals($objects[$order[$order_index]], $string); + $order_index++; + } + + $store->conditionByIsEqualTo("first", "Gerardo"); + + $order = [0, 2]; + $order_index = 0; + foreach ($store->retrieveAll() as $string) { + $this->assertEquals($objects[$order[$order_index]], $string); + $order_index++; + } + } + } \ No newline at end of file