Skip to content
This repository has been archived by the owner on Nov 17, 2020. It is now read-only.

Commit

Permalink
Rename the repository helper, make it a Trait and use PHP 7.1
Browse files Browse the repository at this point in the history
  • Loading branch information
Pierstoval committed Dec 5, 2017
1 parent 9706915 commit 5a43c19
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 66 deletions.
107 changes: 47 additions & 60 deletions BaseEntityRepository.php → EntityRepositoryHelperTrait.php
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -16,53 +16,39 @@
use Symfony\Component\PropertyAccess\PropertyAccess;

/**
* This class is a tool to be used with the Doctrine ORM.
* This trait is a tool to be used with the Doctrine ORM.
* It adds many useful methods to the default EntityRepository, and can be used in any ORM environment.
* For Symfony, if you want to change the default EntityRepository to this one, just change the configuration,
* in app/config.yml
* doctrine:
* orm:
* default_repository_class: Orbitale\Component\DoctrineTools\BaseEntityRepository
*
* Many methods accept a "$indexBy" parameter. This parameter is used to modify the returned collection index.
* If you specify the $indexBy parameter, the returned array will be indexed by the specified field.
* For instance, if you want to index by "id", you can have something similar to this:
* [ '1' => ['id': 1, 'slug': 'object'] , '12' => ['id': '12', 'slug' => 'another-object'] ]
* This is great to be sure that primary/unique indexes garantee unique objects in the returned array.
*
* @package Orbitale\Component\DoctrineTools
*/
class BaseEntityRepository extends EntityRepository
trait EntityRepositoryHelperTrait
{

/**
* Finds all objects and retrieve only "root" objects, without their associated relatives.
* This prevends potential "fetch=EAGER" to be thrown.
*
* @param string $indexBy The field to use as array key index.
*
* @return object[]
*/
public function findAllRoot($indexBy = null)
public function findAllRoot(string $indexBy = null): iterable
{
$datas = $this->createQueryBuilder('object')->getQuery()->getResult();

if ($datas && $indexBy) {
$datas = $this->sortCollection($datas, $indexBy);
}
$this->checkRepository();

return $datas;
return $this->createQueryBuilder('object')
->indexBy($indexBy)
->getQuery()
->getResult()
;
}

/**
* Finds all objects and fetches them as array.
*
* @param string $indexBy The field to use as array key index.
*
* @return array[]
*/
public function findAllArray($indexBy = null)
public function findAllArray(string $indexBy = null): array
{
$this->checkRepository();

$datas = $this->createQueryBuilder('object', $indexBy)->getQuery()->getArrayResult();

if ($datas && $indexBy) {
Expand All @@ -76,29 +62,30 @@ public function findAllArray($indexBy = null)
* Alias for findBy, but adding the $indexBy argument.
*
* {@inheritdoc}
*
* @param string $indexBy The field to use as array key index.
*/
public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null, $indexBy = null)
public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null, string $indexBy = null)
{
$datas = parent::findBy($criteria, $orderBy, $limit, $offset);
if ($datas && $indexBy) {
$datas = $this->sortCollection($datas, $indexBy);
$this->checkRepository();

$data = parent::findBy($criteria, $orderBy, $limit, $offset);

if ($data && $indexBy) {
$data = $this->sortCollection($data, $indexBy);
}

return $datas;
return $data;
}

/**
* Alias for findAll, but adding the $indexBy argument.
* If you do not want the associated elements, please {@see BaseEntityRepository::findAllRoot}
* If you do not want the associated elements to be fetched at the same time, please {@see EntityRepositoryHelperTrait::findAllRoot}
*
* {@inheritdoc}
*
* @param string $indexBy The field to use as array key index.
*/
public function findAll($indexBy = null)
public function findAll(string $indexBy = null)
{
$this->checkRepository();

$datas = $this->findBy(array());

if ($datas && $indexBy) {
Expand All @@ -112,51 +99,45 @@ public function findAll($indexBy = null)
* Gets current AUTO_INCREMENT value from table.
* Useful to see get the maximum ID of the table.
* NOTE: Not compatible with every platform.
*
* @internal
* @return integer
*/
public function getAutoIncrement()
public function getAutoIncrement(): int
{
$this->checkRepository();

$table = $this->getClassMetadata()->getTableName();

$connection = $this->getEntityManager()->getConnection();
$statement = $connection->prepare('SHOW TABLE STATUS LIKE "'.$table.'" ');
$statement->execute();
$datas = $statement->fetch();
$data = $statement->fetch();

$max = (int) $datas['Auto_increment'];

return $max;
return (int) $data['Auto_increment'];
}

/**
* Gets total number of elements in the table.
*
* @return integer
*/
public function getNumberOfElements()
public function getNumberOfElements(): ?int
{
$this->checkRepository();

return $this->_em->createQueryBuilder()
->select('count(a)')
->from($this->getEntityName(), 'a')
->getQuery()
->getSingleScalarResult();
->getSingleScalarResult()
;
}

/**
* Sorts a collection by a specific key, usually the primary key one,
* but you can specify any key.
* For "cleanest" uses, you'd better use a primary or unique key.
*
* @param object[] $collection The collection to sort by index
* @param string $indexBy The field to use as array key index. The special "true" or "_primary" values will use the single identifier field name from the metadatas.
* @throws MappingException
* @return array[]|object[]
*/
public function sortCollection($collection, $indexBy = null)
public function sortCollection(iterable $collection, string $indexBy = null): iterable
{
$this->checkRepository();

$finalCollection = array();
$currentObject = current($collection);
$accessor = class_exists('Symfony\Component\PropertyAccess\PropertyAccess') ? PropertyAccess::createPropertyAccessor() : null;
Expand Down Expand Up @@ -192,14 +173,13 @@ public function sortCollection($collection, $indexBy = null)

/**
* Gets the list of all single identifiers (id) from table
*
* @return array
*
* @throws MappingException
*/
public function getIds()
public function getIds(): iterable
{
$this->checkRepository();

$primaryKey = $this->getClassMetadata()->getSingleIdentifierFieldName();

$result = $this->_em
->createQueryBuilder()
->select('entity.'.$primaryKey)
Expand All @@ -216,4 +196,11 @@ public function getIds()

return $array;
}

private function checkRepository(): void
{
if (!$this instanceof EntityRepository) {
throw new \RuntimeException(sprintf('This trait can only be used by %s classes.', EntityRepository::class));
}
}
}
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Simply install the library with [Composer](https://getcomposer.org):

## Entity Repository

There are 3 ways of using `BaseEntityRepository`:
There are 3 ways of using `EntityRepositoryHelperTrait`:

1. In your own repositories, just extend the Orbitale's one:

Expand All @@ -33,10 +33,11 @@ There are 3 ways of using `BaseEntityRepository`:

namespace AppBundle\Repository;

use Orbitale\Component\DoctrineTools\BaseEntityRepository;
use Orbitale\Component\DoctrineTools\EntityRepositoryHelperTrait;

class PostRepository extends BaseEntityRepository
class PostRepository
{
use EntityRepositoryHelperTrait;

// Your custom logic here ...

Expand All @@ -50,7 +51,7 @@ class PostRepository extends BaseEntityRepository
# app/config.yml
doctrine:
orm:
default_repository_class: Orbitale\Component\DoctrineTools\BaseEntityRepository
default_repository_class: Orbitale\Component\DoctrineTools\EntityRepositoryHelperTrait

```

Expand All @@ -59,15 +60,15 @@ doctrine:
```php

$configuration = new Doctrine\ORM\Configuration();
$configuration->setDefaultRepositoryClassName('Orbitale\Component\DoctrineTools\BaseEntityRepository');
$configuration->setDefaultRepositoryClassName('Orbitale\Component\DoctrineTools\EntityRepositoryHelperTrait');

// Build the EntityManager with its configuration...

```

This way, you can use your EntityRepository exactly like before, it just adds new cool methods!

Just take a look at the [BaseEntityRepository](BaseEntityRepository.php) class to see what nice features it adds!
Just take a look at the [EntityRepositoryHelperTrait](EntityRepositoryHelperTrait.php) class to see what nice features it adds!

## Doctrine Fixtures

Expand Down

0 comments on commit 5a43c19

Please sign in to comment.