PHPackages                             foothing/laravel-repository - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. foothing/laravel-repository

ActiveLibrary[Database &amp; ORM](/categories/database)

foothing/laravel-repository
===========================

This package provides an implementation of the repository pattern for Laravel 5.

0.9.0(9y ago)42.3k[1 issues](https://github.com/foothing/laravel-repository/issues)6MITPHPPHP &gt;=5.4.0

Since Oct 23Pushed 5y ago3 watchersCompare

[ Source](https://github.com/foothing/laravel-repository)[ Packagist](https://packagist.org/packages/foothing/laravel-repository)[ RSS](/packages/foothing-laravel-repository/feed)WikiDiscussions master Synced today

READMEChangelogDependencies (6)Versions (15)Used By (6)

Laravel repository
==================

[](#laravel-repository)

This package provides an implementation of the repository pattern for Laravel 5.

Composer installation
---------------------

[](#composer-installation)

```
composer require foothing/laravel-repository

```

Basic usage
-----------

[](#basic-usage)

This package ships with a repository interface definition and an `Eloquent` implementation. The `EloquentRepository` is ready to use.

```
// Make a repository instance manually
$repository = new EloquentRepository(new Post());
```

You are now ready to go:

```
// Find first occurrence with matching field 'email'
$repository->findOneBy('email', 'test@example.com');

// Find first occurrence where id > 1
$repository->findOneBy('id', '1', '>');

// Find where title starts with 'foo'
$repository->findAllBy('title', 'foo%', 'like');

// Find all occurrences where id > 1
$repository->findAllBy('id', '1', '>');

// Returns all posts
$repository->all();

// Returns all post with Laravel pagination format
$repository->paginate();

// Return record count
$repository->filter('name', 'Homer')->count();

// Create, update and delete instances.
$model = new Post(Input::all());
$freshMoel = $repository->create($model);
$updatedModel = $repository->update($model);
$repository->delete($model);
```

If you want to extend the base implementation with your custom methods all you need to do is extend the base class and define a constructor with the `Eloquent`model as the first argument.

```
class PostsRepository extends EloquentRepository {
	function __construct(Post $post) {
		// Call superclass constructor.
		parent::construct($post);
	}

	function customFancyMethod() {

	}
}
```

Don't forget to call the superclass constructor in order to enable all the features that are delivered out of the box. You can also add additional dependencies while overriding the base constructor.

```
class PostsRepository extends AbstractEloquentRepository {
	function __construct(Post $post, AnotherDependency $dependency) {
		parent::construct($post);
		// Do whatever you like with your $dependency
	}
}
```

and you are all set. Examples:

```
// Use with a dependency injector

class PostsController {
	protected $posts;

	function __construct(PostsRepository $posts) {
		$this->posts = $posts;
	}

	function getIndex($id = null) {
		// Return one post by primary key
		return $this->posts->find($id);
	}
}
```

### Eager load relations

[](#eager-load-relations)

You can eager load relations using the `with` method:

```
$posts = $repository->with(['author', 'comments'])->all();

Output:
[
	{
		"id": 1,
		"title": "Post title",
		"author": {
			"id": 1,
			"email": "test@example.com"
		},
		"comments": [
			{"id": 1, "text": "a comment"},
			{"id": 2, "text": "another comment"},
		],
	}
]
```

You can chain the `with` method to all available methods:

```
$posts = $repository->with(['author', 'comments'])->findOneBy('name', 'foo');
$posts = $repository->with(['author', 'comments'])->all();
// And so on.
```

You'll often want to eager load some relations by default. Let's assume you have an User model with a many-to-many relation with its Role models, and you want to fetch both the user info and the roles.

The `Foothing\Resources\Resource` interface has three methods which define the default Model behaviour:

- which relations to eager load by default for a *findOne* operation
- which relations to eager load by default for a *findMany* operation
- which fields to skip upon save

```
class User extends Model implements Foothing\Resources\Resource {
	/**
	 * Array of relations we want to eager-load when
	 * a single entity is being fetched.
	 *
	 * @return array
	 */
	function unitRelations() {
		return ['roles', 'posts'];
	}

	/**
	 * Array of relations we want to eager-load when
	 * a list of entities is being fetched.
	 *
	 * @return array
	 */
	function listRelations() {
		return ['roles'];
	}

	/**
	 * When the resource is sent in a json-encoded
	 * format it may happen to have relations fields
	 * populated. Since they would be set as stdClass
	 * objects we need to unset them before save.
	 *
	 * This method should return an array with all relations
	 * we want to be unset when processing the updates.
	 *
	 * @return array
	 */
	function skipOnSave() {
		return ['roles', 'posts'];
	}
}
```

In this way, each time you will use your UserRepository the following would be the default behaviour:

```
$users->find($id); 		// will eager load *roles* and *posts*
$users->findOneBy($id); // will eager load *roles* and *posts*
$users->create();		// will eager load *roles* and *posts*
$users->update();		// will eager load *roles* and *posts*
$users->all(); 			// will eager load *roles*
$users->paginate(); 	// will eager load *roles*
```

This default behaviour will be ignored if you use the `with` method explicitly.

The `skipOnSave` method comes handy when dealing with JSON object, since when you read a resource, then process it on the client side, then send it back to the server, it will contain the relation properties. This properties will be converted to stdClass PHP object breaking the Eloquent save method.

Criteria
--------

[](#criteria)

You can apply filters and order constraints using the `CriteriaInterface`, which also ships with an `Eloquent` implementation.

Usage:

```
$criteria = new \Foothing\Repository\Eloquent\EloquentCriteria();
$criteria->filter('name', 'Homer');
$criteria->filter('lastName', 'Simpson');

// Chain methods
$criteria->order('name')->sort('asc');
$repository->criteria($criteria)->paginate();
```

The repository provides shortcut methods you can use in your chains. The following example produces the same effect as the previous one.

```
$repository
	->filter('name', 'Homer')
	->filter('lastName', 'Simpson')
	->order('name')
	->sort('asc')
	->paginate();
```

Available filters:

```
// Defaults to '='
$criteria->filter('name', 'Homer');

$criteria->filter('name', 'Home%', 'like');
$criteria->filter('id', 1, '>');
$criteria->filter('id', 1', '>=');
$criteria->filter('id', 1, 'hasMany('Bar');
	}
}
```

In this case you'll be allowed to query `children` values:

```
$criteria->filter('children.name', 'Bar');
```

> Keep in mind that the methods subject to criteria restrictions are all those fetching more than one record.

Attach and detach many-to-many
------------------------------

[](#attach-and-detach-many-to-many)

Given the following `Model`:

```
class Homer extends Model {

	public function roles() {
		return $this->hasMany('Role');
	}

}
```

you can use the `attach()` and `detach()` methods to attach and detach to / from relation.

```
$homer = Homer::find(1);
$foodCritic = Role::find(1);
$repository->attach($homer, 'roles', $foodCritic);
$repository->detach($homer, 'roles', $foodCritic);
```

Scopes
------

[](#scopes)

You can plug-in your Model scopes using the `scope()` method.

```
// Model
class Person extends Model {

	public function scopeMale($query) {
		return $query->where('sex', 'male');
	}
}

// Usage in Repository
$malePeople = $repository->scope('male')->all();
$malePeople = $repository->scope('male')->filter('name', 'Bart')->all();
$malePeople = $repository->scope('male')->paginate();
$malePeople = $repository->scope('male')->findAllBy('name', 'John');
```

Scopes only apply on read methods.

Global Scopes
-------------

[](#global-scopes)

You can define a global scope for each repository implementation, which might come handy to restrict records access globally.

Just set

```
protected $globalScope = 'whatever';
```

in your repository. The global scope must match an Eloquent scope. Note that if you use explicit scopes, i.e. `$repository->scope('male')`, your global scope will be ignored.

Repository API
--------------

[](#repository-api)

```
