Simplistic layer to store documents into their own repositories

1.2.0 2018-06-01 11:29 UTC


This project provides a layer that sits in between your project and a collection of fake repositories so that each document is stored into its own repository regardless of whether it was persisted as a relation of another object. This layer is designed to be used on testing environments or on low data-level-access applications. Using this project in production is discouraged.

License Build Status SensioLabsInsight


When using fake repositories is common to use functions like serialize or json_encode in order to make data easily persistable. A side effects of using these methods is that related documents are stored along with the parent document. As a result, querying this document from its own repository produces no results, and modifying its data means loading any potential document related with the one that must be modified. This is usually not a problem for small projects, but with large projects where data is complex, unforseen consequences can ensue.


Install with:

$ composer require --dev carlosv2/dumbsmart-repositories


Imagine you have the following entities:

class User
    private $id;
    private $posts;
    public function __construct($id) { $this->id = $id; }
    public function getId() { return $this->id; }
    public function setPosts(array $posts) { $this->posts = $posts; }

class Post
    private $id;
    public function __construct($id) { $this->id = $id; }
    public function getId() { return $this->id; }

In order to use them, you first need to configure this layer:

// Configure the metadata
$metadataManager = new MetadataManager();

$userMetadata = new Metadata(new AccessorObjectIdentifier('getId'));
$userMetadata->setRelation(new OneToManyRelation('posts'));
$metadataManager->addMetadata(User::class, $userMetadata);

$postMetadata = new Metadata(new AccessorObjectIdentifier('getId'));
$metadataManager->addMetadata(Post::class, $postMetadata);

// Configure the repositories
$repositoryManager = new RepositoryManager();
$repositoryManager->addRepository(User::class, new InMemoryRepository(new AccessorObjectIdentifier('getId')));
$repositoryManager->addRepository(Post::class, new InMemoryRepository(new AccessorObjectIdentifier('getId')));

// Create the persister object
$transactionFactory = new TransactionFactory($metadataManager, $repositoryManager);
$persister = new Persister($repositoryManager, $transactionFactory);

Once you have configured the layer, you can start using it like this:

$post1 = new Post(1);
$post2 = new Post(2);

$user = new User(1);
$user->setPosts([$post1, $post2]);


// This returns an object with same properties as $post2. However it does
// not return same object because it has been serialized and unserialized
$persister->findById(Post::class, 2);

If you were using everzet/persisted-objects previously, you don't even need to modify your code, only the way you build your repositories:

// $persister is an instance of carlosV2\DumbsmartRepositories\Persister
$persister = ... ;

// FrontRepository implements Everzet\PersistedObjects\Repository
$frontRepository = new FrontRepository($persister, YourVeryOwnClass::class);
$repository = new YourVeryOwnClassRepository($frontRepository);