Skip to content

Commit

Permalink
exception throwing find variants
Browse files Browse the repository at this point in the history
  • Loading branch information
juliangut committed Oct 30, 2017
1 parent 4bf6069 commit 5c73271
Show file tree
Hide file tree
Showing 8 changed files with 279 additions and 18 deletions.
26 changes: 21 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,25 @@ class customRepository extends EntityRepository implements Repository

* ORM (Relational databases) with [doctrine-orm-repositories](https://github.com/juliangut/doctrine-orm-repositories)
* MongoDB with [doctrine-mongodb-odm-repositories](https://github.com/juliangut/doctrine-mongodb-odm-repositories)
* CouchDB with [doctrine-couchdb-odm-repositories](https://github.com/juliangut/doctrine-couchdb-odm-repositories)
* CouchDB with [doctrine-couchdb-odm-repositories](https://github.com/juliangut/doctrine-couchdb-odm-repositories) _(not maintained)_

## New methods

These are the new methods that `juliangut/doctrine-base-repositories` brings to the table thanks to `RepositoryTrait`

### Find or fail

Same functionality as findBy, findOneBy and their "magic" combinations but throwing an exception if nothing is found

```php
$repository = $manager->getRepository(ObjectClass::class);

$object = $repository->findByOrFail(['slug' => 'my_slug']);
$object = $repository->findBySlugOrFail('my_slug');
$object = $repository->findOneByOrFail(['slug' => 'my_slug']);
$object = $repository->findOneBySlugOrFail('my_slug');
```

### Creating

#### getNew
Expand All @@ -94,7 +107,7 @@ Returns an object based on criteria or a new empty object if could not be found
```php
$repository = $manager->getRepository(ObjectClass::class);

$existingOrNewObject = $repository->findOneByorGetNew(['slug' => 'my_slug']);
$existingOrNewObject = $repository->findOneByOrGetNew(['slug' => 'my_slug']);
```

### Adding
Expand Down Expand Up @@ -157,9 +170,10 @@ $repository = $manager->getRepository(ObjectClass::class);

$totalObjects = $repository->countAll();
$activeObjects = $repository->countBy(['active' => true]);
$activeObjects = $repository->countByActive(true);
```

_countBy needs implementation on custom repository_
_countBy method needs implementation on custom repository_

## Events managing

Expand Down Expand Up @@ -238,7 +252,7 @@ _requires the implementation of getFilterCollection method on custom repository_

## Paginating

Returns the same results that `findBy` would return but within a `\Zend\Paginator\Paginator` object with pagination information. Provided by `PaginatorTrait`
Returns the same results that `findBy` would return but within a `\Zend\Paginator\Paginator` object with pagination information, an exception throwing version is also available. Provided by `PaginatorTrait`

```php
$repository = $manager->getRepository(ObjectClass::class);
Expand All @@ -251,9 +265,11 @@ $paginator->getTotalItemCount(); // 80
$paginator->getCurrentItemCount(); // 10
$paginator->getCurrentPageNumber(); // 1
...

$paginator = $repository->findPaginatedByOrFail(['active' => true], ['date' => 'ASC'], 10);
```

_needs implementation on custom repository_
_findPaginatedBy method needs implementation on custom repository_

## Contributing

Expand Down
33 changes: 33 additions & 0 deletions src/PaginatorTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,37 @@ protected function getPaginator(AdapterInterface $adapter, int $itemsPerPage): P

return $paginator;
}

/**
* Return paginated elements filtered by criteria or throw an exception if none found.
*
* @param array $criteria
* @param array|null $orderBy
* @param int $itemsPerPage
*
* @throws \DomainException
*
* @return Paginator
*/
public function findPaginatedByOrFail(array $criteria, array $orderBy = null, int $itemsPerPage = 10): Paginator
{
$paginator = $this->findPaginatedBy($criteria, $orderBy, $itemsPerPage);

if ($paginator->count() === 0) {
throw new \DomainException('FindPaginatedBy did not return any results');
}

return $paginator;
}

/**
* Return paginated elements filtered by criteria.
*
* @param array $criteria
* @param array|null $orderBy
* @param int $itemsPerPage
*
* @return Paginator
*/
abstract public function findPaginatedBy($criteria, array $orderBy = null, int $itemsPerPage = 10): Paginator;
}
40 changes: 36 additions & 4 deletions src/Repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,15 +125,47 @@ public function restoreFilters();
public function restoreFilter(string $filter);

/**
* Return paginated elements filtered by criteria.
* Find elements or throw an exception if none found.
*
* @param array $criteria
* @param array|null $orderBy
* @param int|null $limit
* @param int|null $offset
*
* @return object[]
*/
public function findByOrFail(array $criteria, array $orderBy = null, int $limit = null, int $offset = null): array;

/**
* Find elements or throw an exception if none found.
*
* @param array $criteria
* @param array $orderBy
* @param int $itemsPerPage
*
* @return object
*/
public function findOneByOrFail(array $criteria);

/**
* Return paginated elements filtered by criteria.
*
* @param array $criteria
* @param array|null $orderBy
* @param int $itemsPerPage
*
* @return Paginator
*/
public function findPaginatedBy($criteria, array $orderBy = null, int $itemsPerPage = 10): Paginator;

/**
* Return paginated elements filtered by criteria or throw an exception if none found.
*
* @param array $criteria
* @param array|null $orderBy
* @param int $itemsPerPage
*
* @return Paginator
*/
public function findPaginatedBy($criteria, array $orderBy = [], int $itemsPerPage = 10): Paginator;
public function findPaginatedByOrFail(array $criteria, array $orderBy = null, int $itemsPerPage = 10): Paginator;

/**
* Find one object by a set of criteria or create a new one.
Expand Down
59 changes: 58 additions & 1 deletion src/RepositoryTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,17 @@ trait RepositoryTrait
'countBy',
];

/**
* Methods that support exception throwing on fail.
*
* @var array
*/
protected static $falibleMethods = [
'findBy',
'findOneBy',
'findPaginatedBy',
];

/**
* Auto flush changes.
*
Expand Down Expand Up @@ -81,6 +92,49 @@ public function flush()
$this->getManager()->flush();
}

/**
* Find elements or throw an exception if none found.
*
* @param array $criteria
* @param array|null $orderBy
* @param int|null $limit
* @param int|null $offset
*
* @throws \DomainException
*
* @return object[]
*/
public function findByOrFail(array $criteria, array $orderBy = null, int $limit = null, int $offset = null): array
{
$objects = $this->findBy($criteria, $orderBy, $limit, $offset);

if (count($objects) === 0) {
throw new \DomainException('FindBy did not return any results');
}

return $objects;
}

/**
* Find elements or throw an exception if none found.
*
* @param array $criteria
*
* @throws \DomainException
*
* @return object
*/
public function findOneByOrFail(array $criteria)
{
$object = $this->findOneBy($criteria);

if ($object === null) {
throw new \DomainException('FindOneBy did not return any results');
}

return $object;
}

/**
* Find one object by a set of criteria or create a new one.
*
Expand Down Expand Up @@ -290,7 +344,10 @@ public function __call($method, $arguments)

$baseMethod = $this->getSupportedMethod($method);

if ($baseMethod === 'findOneBy' && preg_match('/OrGetNew$/', $method)) {
if (in_array($baseMethod, static::$falibleMethods) && preg_match('/OrFail$/', $method)) {
$field = substr($method, strlen($baseMethod), -6);
$method = $baseMethod . 'OrFail';
} elseif ($baseMethod === 'findOneBy' && preg_match('/OrGetNew$/', $method)) {
$field = substr($method, strlen($baseMethod), -8);
$method = 'findOneByOrGetNew';
} else {
Expand Down
23 changes: 22 additions & 1 deletion tests/Repository/PaginatorTraitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

namespace Jgut\Doctrine\Repository\Tests;

use Jgut\Doctrine\Repository\Tests\Stubs\EntityStub;
use Jgut\Doctrine\Repository\Tests\Stubs\PaginatorTraitStub;
use Zend\Paginator\Paginator;

Expand All @@ -21,10 +22,30 @@
*/
class PaginatorTraitTest extends \PHPUnit_Framework_TestCase
{
public function testFindPaginatedByOrFail()
{
$entity = new EntityStub();

$trait = new PaginatorTraitStub([$entity]);

static::assertInstanceOf(Paginator::class, $trait->findPaginatedByOrFail([], [], 10));
}

/**
* @expectedException \DomainException
* @expectedExceptionMessage FindPaginatedBy did not return any results
*/
public function testFailingFindPaginatedByOrFail()
{
$trait = new PaginatorTraitStub();

static::assertInstanceOf(Paginator::class, $trait->findPaginatedByOrFail([], [], 10));
}

public function testPaginator()
{
$trait = new PaginatorTraitStub();

static::assertInstanceOf(Paginator::class, $trait->getPaginated([], 10));
static::assertInstanceOf(Paginator::class, $trait->findPaginatedBy([], [], 10));
}
}
78 changes: 78 additions & 0 deletions tests/Repository/RepositoryTraitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,66 @@ public function testFlush()
$repository->flush();
}

public function testFindByOrFail()
{
$manager = $this->getMockBuilder(EntityManager::class)
->disableOriginalConstructor()
->getMock();
/* @var EntityManager $manager */

$entity = new EntityStub();

$repository = new RepositoryStub($manager, [$entity]);

static::assertEquals([$entity], $repository->findByOrFail(['param' => 'value']));
}

/**
* @expectedException \DomainException
* @expectedExceptionMessage FindBy did not return any results
*/
public function testFailingFindByOrFail()
{
$manager = $this->getMockBuilder(EntityManager::class)
->disableOriginalConstructor()
->getMock();
/* @var EntityManager $manager */

$repository = new RepositoryStub($manager);

var_dump($repository->findByOrFail(['param' => 'value']));
}

public function testFindOneByOrFail()
{
$manager = $this->getMockBuilder(EntityManager::class)
->disableOriginalConstructor()
->getMock();
/* @var EntityManager $manager */

$entity = new EntityStub();

$repository = new RepositoryStub($manager, [$entity]);

static::assertEquals($entity, $repository->findOneByOrFail(['param' => 'value']));
}

/**
* @expectedException \DomainException
* @expectedExceptionMessage FindOneBy did not return any results
*/
public function testFailingOneFindByOrFail()
{
$manager = $this->getMockBuilder(EntityManager::class)
->disableOriginalConstructor()
->getMock();
/* @var EntityManager $manager */

$repository = new RepositoryStub($manager);

var_dump($repository->findOneByOrFail(['param' => 'value']));
}

public function testGetNewByFindOne()
{
$manager = $this->getMockBuilder(EntityManager::class)
Expand Down Expand Up @@ -299,6 +359,24 @@ public function testCountAll()
static::assertEquals(2, $repository->countAll());
}

/**
* @expectedException \BadMethodCallException
* @expectedExceptionMessageRegExp /^Invalid call to .+::findOneByOrFail\. Field "parameter" does not exist/
*/
public function testCallOrFailVariants()
{
$entity = new EntityStub();

$manager = $this->getMockBuilder(EntityManager::class)
->disableOriginalConstructor()
->getMock();
/* @var EntityManager $manager */

$repository = new RepositoryStub($manager, [$entity]);

$repository->findOneByParameterOrFail(1);
}

/**
* @expectedException \BadMethodCallException
* @expectedExceptionMessageRegExp /^You need to call .+::removeByParameter with a parameter$/
Expand Down
Loading

0 comments on commit 5c73271

Please sign in to comment.