diff --git a/README.md b/README.md index d3cba5b..96f9474 100644 --- a/README.md +++ b/README.md @@ -17,14 +17,36 @@ Support can be installed through Composer, just include `"michele-angioni/suppor Then add the Support Service Provider in the Laravel `app.php` config file, under the providers array - 'MicheleAngioni\Support\SupportServiceProvider' +```php +'MicheleAngioni\Support\SupportServiceProvider' +``` and the Helpers facade in the aliases array - 'Helpers' => 'MicheleAngioni\Support\Facades\Helpers' +```php +'Helpers' => 'MicheleAngioni\Support\Facades\Helpers' +``` + +#### Laravel 4 If you are looking for the Laravel 4 version, check the [1.0 branch](https://github.com/micheleangioni/support/tree/1.0) and its documentation. +#### Lumen + +At the moment, only partial and **unstable** support for Lumen is guaranteed. + +First of all load the Service Provider in your bootstrap file + +```php +$app->register('MicheleAngioni\Support\SupportServiceProvider'); +``` + +and set the needed config key + +```php +config(['ma_support.cache_time' => 10]); // Default number of minutes the repositories will be cached +``` + ## Modules summary Support comes bundled of the following features: Repositories, Cache, Presenters, Semaphores, an Helpers class and new custom validators. @@ -45,79 +67,91 @@ This way implementing the repository pattern becomes straightforward. As an example let's take a `Post` model. First of all we shall create a repository interface which will be injected in the constructor of the classes we need. Let's define the `PostRepositoryInterface` as - model = $model; - } + public function __construct(Post $model) + { + $this->model = $model; } +} +``` Now we need to bind the implementation to the interface, which can be done by adding - $this->app->bind( - 'PostRepositoryInterface', - 'EloquentPostRepository' - ); +```php +$this->app->bind( + 'PostRepositoryInterface', + 'EloquentPostRepository' +); +``` to an existing Laravel Service Provider. Or we can create a brand new one - app->bind( - 'PostRepositoryInterface', - 'EloquentPostRepository' - ); - } + public function register() + { + $this->app->bind( + 'PostRepositoryInterface', + 'EloquentPostRepository' + ); } +} +``` and add it to the `config/app.php` file in the providers array - 'RepositoryServiceProvider', +```php +'RepositoryServiceProvider', +``` Suppose that now we need the Post repo in our PostController. We simply inject our `PostRepositoryInterface` in the controller which gets resolved thanks to the Laravel IoC Container - postRepo = $postRepo; - } + function __construct(PostRepo $postRepo) + { + $this->postRepo = $postRepo; + } - public function show($idPost) - { - $post = $this->postRepo->find($idPost); + public function show($idPost) + { + $post = $this->postRepo->find($idPost); - // Use the retrieved post - } + // Use the retrieved post } +} +``` The `AbstractEloquentRepository` empowers automatically our repositories of the following public methods: @@ -158,22 +192,26 @@ Decrecated methods: The Repository module also supports xml repositories. Suppose we have a staff.xml file. We need to define a `StaffXMLRepositoryInterface` - app->bind( - 'StaffXMLRepositoryInterface', - 'SimpleXMLStaffRepository' - ); - } + public function register() + { + $this->app->bind( + 'StaffXMLRepositoryInterface', + 'SimpleXMLStaffRepository' + ); } +} +``` We can then inject the repo in the class we need or simply call it through the Laravel application instance / facade - $xmlStaffRepo = App::make('StaffXMLRepositoryInterface'); +```php +$xmlStaffRepo = App::make('StaffXMLRepositoryInterface'); +``` ### !!Warning!! @@ -213,36 +255,36 @@ The `AbstractEloquentRepository` and `AbstractSimpleXMLRepository` classes do NO The Cache module can be used to give Cache capabilities to our repositories, through the use of the [decorator pattern](http://en.wikipedia.org/wiki/Decorator_pattern). We can then continue our previous example of a Post model and its repo. We define a `CachePostRepoDecorator` as follows - app->bind( - 'PostRepositoryInterface', function($app) - { - $repo = $app->make('EloquentPostRepository'); + public function register() + { + $this->app->bind( + 'PostRepositoryInterface', function($app) + { + $repo = $app->make('EloquentPostRepository'); - return new CachePostRepoDecorator($repo, new LaravelCache($app['cache']), new KeyManager); - } - ); - } + return new CachePostRepoDecorator($repo, new LaravelCache($app['cache']), new KeyManager); + } + ); } +} +``` Now you can use the Post repository as before, but when calling the all(), find() or findOrFail() methods the result will be cached (default time: 10 minutes It can be modified in the configuration file). @@ -285,65 +329,71 @@ Now you can use the Post repository as before, but when calling the all(), find( Want to manually delete a cache result? In your Post model define a flush() method as follows - public function flush() - { - Cache::tags(get_called_class().'id'.$this->{$this->primaryKey})->flush(); - } +```php +public function flush() +{ + Cache::tags(get_called_class().'id'.$this->{$this->primaryKey})->flush(); +} +``` You can then call it when editing or deleting a Post model you that your clients don't get outdated results. The Cache module comes with xml handlers too. Let's take the staff.xml class we used before. All we need to provide cache is to define the caching xml repo as follows - app->bind( + 'StaffXMLRepositoryInterface', function($app) { - $this->app->bind( - 'StaffXMLRepositoryInterface', function($app) - { - $repo = $app->make('SimpleXMLStaffRepository'); + $repo = $app->make('SimpleXMLStaffRepository'); - return new CacheSimpleXMLStaffRepoDecorator($repo, new LaravelCache($app['cache']) - ); - }); - } + return new CacheSimpleXMLStaffRepoDecorator($repo, new LaravelCache($app['cache']) + ); + }); } +} +``` ## Presenters Usage @@ -356,65 +406,69 @@ First of all define the PostDecorator by extending `MicheleAngioni\Support\Prese The AbstractPresenter will allow to access al model's attributes through the use of PHP magic method __GET. It also implements ArrayAccess interface so that we can keep to access our attributes both as an object and as array. - object->text); - } - - public function capitalText() - { - return e(strtoupper($this->object->text)); - } + return e($this->object->text); + } + + public function capitalText() + { + return e(strtoupper($this->object->text)); } +} +``` Now we have to couple our presenter to the Post model with the help of the `MicheleAngioni\Support\Presenters\Presenter` class, for example directly in the PostController - postRepo = $postRepo; - $this->presenter = $presenter - } + function __construct(PostRepo $postRepo, Presenter $presenter) + { + $this->postRepo = $postRepo; + $this->presenter = $presenter + } - public function index() - { - $posts = $this->postRepo->all(); - - // Pass the post collection to the presenter - $posts = $this->presenter->collection($posts, new PostPresenter(); + public function index() + { + $posts = $this->postRepo->all(); + + // Pass the post collection to the presenter + $posts = $this->presenter->collection($posts, new PostPresenter(); - // Pass the post collection to the view - return View::make('forum')->with('posts', $posts) - } + // Pass the post collection to the view + return View::make('forum')->with('posts', $posts) + } - public function show($idPost) - { - $post = $this->postRepo->find($idPost); - - // Pass the post to the presenter - $post = $this->presenter->model($post, new PostPresenter(); - - // Pass the post to the view - return View::make('forum')->with('post', $post) - } + public function show($idPost) + { + $post = $this->postRepo->find($idPost); + + // Pass the post to the presenter + $post = $this->presenter->model($post, new PostPresenter(); + + // Pass the post to the view + return View::make('forum')->with('post', $post) } +} +``` In the above Controller we have decorated a single model in the show method and an entire collection in the index method, thus passed them to the view. @@ -426,22 +480,24 @@ Through the presenter we can also add brand new functionality to our models: in The semaphores module consists of a single class, the `SemaphoresManager`. Its constructor needs a Cache Manager and a Key Manager. The Support package provides both of them, so we can bind them to the SemaphoresManager in a service provider - app->bind( - 'MicheleAngioni\Support\Semaphores\SemaphoresManager', function($app) - { - return new SemaphoresManager(new LaravelCache($app['cache']), new KeyManager); - }); - } +use Illuminate\Support\ServiceProvider; +use MicheleAngioni\Support\Cache\KeyManager; +use MicheleAngioni\Support\Cache\LaravelCache; +use MicheleAngioni\Support\Semaphores\SemaphoresManager; + +class SemaphoresServiceProviders extends ServiceProvider +{ + $this->app->bind( + 'MicheleAngioni\Support\Semaphores\SemaphoresManager', function($app) + { + return new SemaphoresManager(new LaravelCache($app['cache']), new KeyManager); + }); } +} +``` We can them simply inject the SemaphoresManager in a constructor to be resolver by the IoC Container and it is ready to use through the following methods: @@ -455,7 +511,9 @@ We can them simply inject the SemaphoresManager in a constructor to be resolver The helpers class provides several useful methods which simplify php development. Support has also an Helpers facade which can be registered in the `app.php` file under the aliases array as - 'Helpers' => 'MicheleAngioni\Support\Facades\Helpers' +```php +'Helpers' => 'MicheleAngioni\Support\Facades\Helpers' +``` The available methods are: diff --git a/composer.json b/composer.json index 8bff5f0..75dc82a 100644 --- a/composer.json +++ b/composer.json @@ -12,6 +12,8 @@ ], "require": { "php": ">=5.4.0", + "illuminate/cache": "~5.0", + "illuminate/console": "~5.0", "illuminate/database": "~5.0", "illuminate/pagination": "~5.0", "illuminate/support": "~5.0",