diff --git a/CHANGELOG.md b/CHANGELOG.md index 10b9bbc..203002a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,14 @@ # Changelog All Notable changes to `jobs-common` will be documented in this file +## 2.1.0 - 2016-12-01 + +### Added +- New methods to Collection object: `addCollection`, `filter`, `orderBy`, and `truncate`. + +### Fixed +- `getSource` method was returning the source with the suffix `Provider` since the v2 upgrade. I created a method to remove `Provider` from the end of the string if present. + ## 2.0.2 - 2016-11-01 ### Fixed diff --git a/src/Collection.php b/src/Collection.php index e8a3f9c..a7abb98 100644 --- a/src/Collection.php +++ b/src/Collection.php @@ -45,6 +45,31 @@ public function add($item, $key = null) return $this; } + /** + * Append a collection to this collection. + * + * @param Collection $collection + * + * @return $this + */ + public function addCollection(Collection $collection) + { + // If there are jobs, add them to the collection + if ($collection->count()) { + foreach ($collection->all() as $job) { + $this->add($job); + } + } + // If there are errors, add them to the collection + if ($collection->getErrors()) { + foreach ($collection->getErrors() as $error) { + $this->addError($error); + } + } + + return $this; + } + /** * Add error to collection * @@ -101,6 +126,37 @@ public function delete($key) return $this; } + /** + * Filter items by a field having a specific value. + * + * @param string $field + * @param string $value + * @param string $operator + * + * @return $this + */ + public function filter($field, $value, $operator = '=') + { + $this->items = array_filter( + $this->items, + function ($item) use ($field, $value, $operator) { + if (!isset($item->{$field})) { + throw new \Exception("Property not defined."); + } + if ($operator == '>') { + return $item->{$field} > $value; + } elseif ($operator == '<') { + return $item->{$field} < $value; + } elseif ($operator == '=') { + return $item->{$field} == $value; + } + return false; + } + ); + + return $this; + } + /** * Get item from collection at specific key * @@ -128,4 +184,52 @@ public function getErrors() { return $this->errors; } + + /** + * Order items by a field value. + * + * @param string $orderBy + * @param string $order + * + * @return $this + */ + public function orderBy($orderBy, $order = 'desc') + { + usort( + $this->items, + function ($item1, $item2) use ($orderBy, $order) { + if (!isset($item1->{$orderBy}) || !isset($item2->{$orderBy})) { + throw new \Exception("Property not defined."); + } + // If the two items are equal, return 0 + if ($item1->{$orderBy} == $item2->{$orderBy}) { + return 0; + } + // If ascending, test whether Item 1 is less than Item 2 + if ($order === 'asc') { + return $item1->{$orderBy} < $item2->{$orderBy} ? -1 : 1; + } + // Else assuming descending. + return $item1->{$orderBy} > $item2->{$orderBy} ? -1 : 1; + } + ); + + return $this; + } + + /** + * Truncate the items to a maximum number of results. + * + * @param null $max + * + * @return $this + */ + public function truncate($max = null) + { + if ($max) { + $this->items = array_slice($this->items, 0, $max); + } + + return $this; + } } diff --git a/src/Providers/AbstractProvider.php b/src/Providers/AbstractProvider.php index 0a86a3a..2a1d2ac 100644 --- a/src/Providers/AbstractProvider.php +++ b/src/Providers/AbstractProvider.php @@ -120,9 +120,16 @@ public function getJobs() */ public function getSource() { - $ref = new \ReflectionClass(get_class($this)); + $classSuffix = "Provider"; - return $ref->getShortName(); + $className = (new \ReflectionClass(get_class($this)))->getShortName(); + + // Strip off the suffix from the provider + if ($this->stringEndsWith($className, $classSuffix)) { + $className = substr($className, 0, strlen($classSuffix)); + } + + return $className; } /** @@ -353,4 +360,22 @@ private function parseAsXml($string) return []; } + + /** + * Determine whether a string ends with another string + * + * @param $string + * @param $test + * + * @return bool + */ + private function stringEndsWith($string, $test) + { + $stringLen = strlen($string); + $testLen = strlen($test); + if ($testLen > $stringLen) { + return false; + } + return substr_compare($string, $test, $stringLen - $testLen, $testLen) === 0; + } } diff --git a/tests/src/CollectionTest.php b/tests/src/CollectionTest.php index 2b1cb1a..de13891 100644 --- a/tests/src/CollectionTest.php +++ b/tests/src/CollectionTest.php @@ -93,4 +93,152 @@ public function testItFailsToDeleteItemWithoutValidKey() $this->assertEquals($message, end($errors)); } + + public function testItCanAddCollectionWhenCollectionHasItemsAndErrors() + { + $error = uniqid(); + + // Add an item to the test collection + $this->collection->add($this->getItem()); + + // Create a new collection with 2 items and 1 error + $collection = (new Collection()) + ->add($this->getItem()) + ->add($this->getItem()) + ->addError($error); + + $this->collection->addCollection($collection); + + $this->assertEquals(3, $this->collection->count()); + $this->assertEquals($error, $this->collection->getErrors()[0]); + } + + public function testItCanAddCollectionWhenCollectionHasNoItems() + { + $error = uniqid(); + + // Add an item to the test collection + $this->collection->add($this->getItem()); + + // Create a new collection with 1 error + $collection = (new Collection()) + ->addError($error); + + $this->collection->addCollection($collection); + + $this->assertEquals(1, $this->collection->count()); + $this->assertEquals($error, $this->collection->getErrors()[0]); + } + + public function testItCanFilterItemsWhenFieldExists() + { + // Add some items to the test collection + $item = $this->getItem(); + $this->collection->add($item) + ->add($this->getItem()); + + // Filter + $this->collection->filter('id', $item->id); + + // Test the results + $this->assertEquals(1, $this->collection->count()); + $this->assertEquals($item, $this->collection->get(0)); + } + + /** + * @expectedException \Exception + * @expectedExceptionMessage Property not defined. + */ + public function testItCannotFilterItemsWhenFieldNotExists() + { + // Add some items to the test collection + $item = $this->getItem(); + $this->collection->add($item) + ->add($this->getItem()); + + // Filter + $this->collection->filter(uniqid(), $item->id); + } + + public function testItCanOrderItemsWhenFieldExists() + { + // Add some items to the test collection + $this->collection + ->add($this->getItem()) + ->add($this->getItem()) + ->add($this->getItem()); + + // Filter + $this->collection->orderBy('id'); + + // Test the results + $this->assertEquals(3, $this->collection->count()); + $prevItem = null; + foreach($this->collection->all() as $item) { + if ($prevItem) { + $this->assertLessThan($prevItem, $item); + } + $prevItem = $item; + } + } + + public function testItCanOrderItemsAscWhenFieldExists() + { + // Add some items to the test collection + $this->collection + ->add($this->getItem()) + ->add($this->getItem()) + ->add($this->getItem()); + + // Filter + $this->collection->orderBy('id', 'asc'); + + // Test the results + $this->assertEquals(3, $this->collection->count()); + $prevItem = null; + foreach($this->collection->all() as $item) { + if ($prevItem) { + $this->assertGreaterThan($prevItem, $item); + } + $prevItem = $item; + } + } + + /** + * @expectedException \Exception + * @expectedExceptionMessage Property not defined. + */ + public function testItCannotOrderItemsWhenFieldNotExists() + { + // Add some items to the test collection + $this->collection + ->add($this->getItem()) + ->add($this->getItem()) + ->add($this->getItem()); + + // Filter + $this->collection->orderBy(uniqid()); + } + + public function testItCanTruncateCollection() + { + // Add some items to the test collection + $this->collection + ->add($this->getItem()) + ->add($this->getItem()) + ->add($this->getItem()); + + // Filter + $this->collection->truncate(1); + + // Test the results + $this->assertEquals(1, $this->collection->count()); + } + + private function getItem() + { + return (object) [ + 'id' => uniqid(), + ]; + } } diff --git a/tests/src/ProviderTest.php b/tests/src/ProviderTest.php index 92d2254..698e7d2 100644 --- a/tests/src/ProviderTest.php +++ b/tests/src/ProviderTest.php @@ -61,7 +61,7 @@ public function testItCannotGetJobsWhenInvalidQueryProvided() public function testItCanGetSource() { - $this->assertEquals('ConcreteProvider', $this->client->getSource()); + $this->assertEquals('Concrete', $this->client->getSource()); } public function testItCanParseDefaultAttributes()