diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..b74dd9c2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.idea/ +composer.phar +vendor/ \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..f8719fb2 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,13 @@ +language: php + +php: + - 5.4 + - 5.5 + - 5.6 + - hhvm + +before_script: + - travis_retry composer self-update + - travis_retry composer install --prefer-source --no-interaction --dev + +script: phpunit \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 00000000..7ed3364a --- /dev/null +++ b/README.md @@ -0,0 +1,357 @@ +# Laravel 5 Repositories + +Laravel 5 Repositories is used to abstract the data layer, making our application more flexible to maintain. + +## Installation + +Add this line "prettus/l5-repository": "1.0.*" in your composer.json. + +```json +"require": { + "prettus/l5-repository": "1.0.*" +} +``` + +Issue composer update + +Add to app/config/app.php service provider array: + +```php + 'Prettus\Repository\RepositoryServiceProvider', +``` + +Publish Configuration + +```shell +php artisan vendor:publish --provider="Prettus\Repository\RepositoryServiceProvider" +``` + +## Methods + +### Repository + +- scopeReset() +- find($id, $columns = ['*']) +- findByField($field, $value, $columns = ['*']) +- all($columns = array('*')) +- paginate($limit = null, $columns = ['*']) +- create(array $attributes) +- update(array $attributes, $id) +- delete($id) +- getModel() +- with(array $relations); +- pushCriteria(Criteria $criteria) +- getCriteria() +- getByCriteria(Criteria $criteria) +- skipCriteria() + +### Criteria + +- apply($query) + +## Utilisation + +### Create a Repository + +```php +use Prettus\Repository\Eloquent\Repository; + +class PostRepository extends RepositoryBase { + + public function __construct(Post $model) + { + parent::__construct($model); + } + +} +``` + +### Using the Repository in a Controller + +```php + +class PostsController extends BaseController { + + /** + * @var PostRepository + */ + protected $repository; + + public function __construct(PostRepository $repository){ + $this->repository = $repository; + } + + + public function index() + { + $posts = $this->repository->all(); + ... + } + + + public function show($id) + { + $post = $this->repository->find($id); + ... + } + + public function store() + { + + $post = $this->repository->create( Input::all() ); + ... + } + + public function update($id) + { + $post = $this->repository->update( Input::all(), $id ); + ... + } + + public function destroy($id){ + $this->repository->delete($id) + ... + } +} +``` + +### Create a Criteria + +```php +class MyCriteria implements \Prettus\Repository\Contracts\Criteria { + + public function apply($query) + { + $query = $query->where('user_id','=', Auth::user()->id ); + return $query; + } +} +``` + +### Using the Criteria in a Controller + +```php + +class PostsController extends BaseController { + + /** + * @var PostRepository + */ + protected $repository; + + public function __construct(PostRepository $repository){ + $this->repository = $repository; + } + + + public function index() + { + $this->repository->pushCriteria(new MyCriteria()); + $posts = $this->repository->all(); + ... + } + +} +``` + +Getting results from criteria + +```php +$posts = $this->repository->getByCriteria(new MyCriteria()); +``` + +Setting Criteria default in Repository + +```php +use Prettus\Repository\Eloquent\Repository; + +class PostRepository extends RepositoryBase { + + public function __construct(Post $model) + { + parent::__construct($model); + } + + public function boot(){ + $this->pushCriteria(new MyCriteria()); + $this->pushCriteria(new AnotherCriteria()); + ... + } + +} +``` + +### Using the RequestCriteria + +RequestCriteria is a standard Criteria implementation. It enables filters perform in the repository from parameters sent in the request. + +You can perform a dynamic search , filtering the data and customize queries + +To use the Criteria in your repository , you can add a new criteria in the boot method of your repository , or directly use in your controller , in order to filter out only a few requests + +####Enabling in your Repository + +```php +use Prettus\Repository\Eloquent\Repository; +use Prettus\Repository\Criteria\RequestCriteria; + +class PostRepository extends RepositoryBase { + + /** + * @var array + */ + protected $fieldSearchable = [ + 'name', + 'email' + ]; + + public function __construct(Post $model) + { + parent::__construct($model); + } + + public function boot(){ + $this->pushCriteria(new RequestCriteria(app('request'))); + ... + } + +} +``` + +Remember, you need to define which fields from the model can are searchable. + +In your repository set **$fieldSearchable** with their fields searchable. + +```php +protected $fieldSearchable = [ + 'name', + 'email' +]; +``` + +You can set the type of condition will be used to perform the query , the default condition is "**=**" + +```php +protected $fieldSearchable = [ + 'name'=>'like', + 'email', // Default Condition "**=**" + 'your_field'=>'condition' +]; +``` + +####Enabling in your Controller + +```php + public function index() + { + $this->repository->pushCriteria(new RequestCriteria(app('request'))); + $posts = $this->repository->all(); + ... + } +``` + +#### Example the Crirteria + +Request all data without filter by request + +*http://prettus.local/users* + +```json +[ +{ +id: 1, +name: "Anderson Andrade", +email: "email@gmail.com", +created_at: "-0001-11-30 00:00:00", +updated_at: "-0001-11-30 00:00:00" +}, +{ +id: 2, +name: "Lorem Ipsum", +email: "lorem@ipsum.com", +created_at: "-0001-11-30 00:00:00", +updated_at: "-0001-11-30 00:00:00" +}, +{ +id: 3, +name: "Laravel", +email: "laravel@gmail.com", +created_at: "-0001-11-30 00:00:00", +updated_at: "-0001-11-30 00:00:00" +} +] +`` + +Conducting research in the repository + +*http://prettus.local/users?search=Anderson%20Andrade* + +or + +*http://prettus.local/users?search=Anderson&searchFields=name:like* + +or + +*http://prettus.local/users?search=email@gmail.com&searchFields=email:=* + +```json +[ +{ +id: 1, +name: "Anderson Andrade", +email: "email@gmail.com", +created_at: "-0001-11-30 00:00:00", +updated_at: "-0001-11-30 00:00:00" +} +] +``` + +Filtering fields + +*http://prettus.local/users?filter=id;name* + +```json +[ +{ +id: 1, +name: "Anderson Andrade" +}, +{ +id: 2, +name: "Lorem Ipsum" +}, +{ +id: 3, +name: "Laravel" +} +] +``` + +Sorting the results + +*http://prettus.local/users?filter=id;name&orderBy=id&sortedBy=desc* + +```json +[ +{ +id: 3, +name: "Laravel" +}, +{ +id: 2, +name: "Lorem Ipsum" +}, +{ +id: 1, +name: "Anderson Andrade" +} +] +``` + +####Overwrite params name + +You can change the name of the parameters in the configuration file **config/repository-criteria.php** + +# Author + +Anderson Andrade - \ No newline at end of file diff --git a/composer.json b/composer.json new file mode 100644 index 00000000..d7dcedab --- /dev/null +++ b/composer.json @@ -0,0 +1,28 @@ +{ + "name": "prettus/l5-repository", + "description": "Laravel 5 - Repositories to abstract the database layer", + "license": "MIT", + "keywords": ["laravel", "repository", "eloquent", "model"], + "authors": [ + { + "name": "Anderson Andrade", + "email": "contato@andersonandra.de" + } + ], + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0", + "phpspec/phpspec": "~2.1", + "mockery/mockery": "dev-master", + "illuminate/support": "5.0.*" + }, + "autoload": { + "psr-0": { + "Prettus\\Repository\\": "src/", + "Prettus\\Repository\\Test": "tests/" + } + }, + "minimum-stability": "stable" +} \ No newline at end of file diff --git a/composer.lock b/composer.lock new file mode 100644 index 00000000..f50fe150 --- /dev/null +++ b/composer.lock @@ -0,0 +1,1573 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "hash": "df68c69d7b3aa1e3ca0db3ecb006e83a", + "packages": [], + "packages-dev": [ + { + "name": "danielstjules/stringy", + "version": "1.9.0", + "source": { + "type": "git", + "url": "https://github.com/danielstjules/Stringy.git", + "reference": "3cf18e9e424a6dedc38b7eb7ef580edb0929461b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/danielstjules/Stringy/zipball/3cf18e9e424a6dedc38b7eb7ef580edb0929461b", + "reference": "3cf18e9e424a6dedc38b7eb7ef580edb0929461b", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Stringy\\": "src/" + }, + "files": [ + "src/Create.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel St. Jules", + "email": "danielst.jules@gmail.com", + "homepage": "http://www.danielstjules.com" + } + ], + "description": "A string manipulation library with multibyte support", + "homepage": "https://github.com/danielstjules/Stringy", + "keywords": [ + "UTF", + "helpers", + "manipulation", + "methods", + "multibyte", + "string", + "utf-8", + "utility", + "utils" + ], + "time": "2015-02-10 06:19:18" + }, + { + "name": "doctrine/inflector", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/inflector.git", + "reference": "0bcb2e79d8571787f18b7eb036ed3d004908e604" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/0bcb2e79d8571787f18b7eb036ed3d004908e604", + "reference": "0bcb2e79d8571787f18b7eb036ed3d004908e604", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "4.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Inflector\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Common String Manipulations with regard to casing and singular/plural rules.", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "inflection", + "pluralize", + "singularize", + "string" + ], + "time": "2014-12-20 21:24:13" + }, + { + "name": "doctrine/instantiator", + "version": "1.0.4", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "f976e5de371104877ebc89bd8fecb0019ed9c119" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/f976e5de371104877ebc89bd8fecb0019ed9c119", + "reference": "f976e5de371104877ebc89bd8fecb0019ed9c119", + "shasum": "" + }, + "require": { + "php": ">=5.3,<8.0-DEV" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "2.0.*@ALPHA" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Instantiator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2014-10-13 12:58:55" + }, + { + "name": "illuminate/contracts", + "version": "v5.0.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/contracts.git", + "reference": "78f1dba092d5fcb6d3a19537662abe31c4d128fd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/contracts/zipball/78f1dba092d5fcb6d3a19537662abe31c4d128fd", + "reference": "78f1dba092d5fcb6d3a19537662abe31c4d128fd", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Contracts\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "description": "The Illuminate Contracts package.", + "time": "2015-01-30 16:27:08" + }, + { + "name": "illuminate/support", + "version": "v5.0.4", + "source": { + "type": "git", + "url": "https://github.com/illuminate/support.git", + "reference": "405a2241fefa49cfc39b7fba8cc54f69fce2f101" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/support/zipball/405a2241fefa49cfc39b7fba8cc54f69fce2f101", + "reference": "405a2241fefa49cfc39b7fba8cc54f69fce2f101", + "shasum": "" + }, + "require": { + "danielstjules/stringy": "~1.8", + "doctrine/inflector": "~1.0", + "ext-mbstring": "*", + "illuminate/contracts": "5.0.*", + "php": ">=5.4.0" + }, + "suggest": { + "jeremeamia/superclosure": "Required to be able to serialize closures (~2.0)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Support\\": "" + }, + "files": [ + "helpers.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "description": "The Illuminate Support package.", + "time": "2015-02-11 11:08:03" + }, + { + "name": "mockery/mockery", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/padraic/mockery.git", + "reference": "f770ab0cf167cccf1a701f28411fbfc9971ff90e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/padraic/mockery/zipball/f770ab0cf167cccf1a701f28411fbfc9971ff90e", + "reference": "f770ab0cf167cccf1a701f28411fbfc9971ff90e", + "shasum": "" + }, + "require": { + "lib-pcre": ">=7.0", + "php": ">=5.3.2" + }, + "require-dev": { + "hamcrest/hamcrest-php": "~1.1", + "phpunit/phpunit": "~4.0", + "satooshi/php-coveralls": "~0.7@dev" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.9.x-dev" + } + }, + "autoload": { + "psr-0": { + "Mockery": "library/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Pádraic Brady", + "email": "padraic.brady@gmail.com", + "homepage": "http://blog.astrumfutura.com" + }, + { + "name": "Dave Marshall", + "email": "dave.marshall@atstsolutions.co.uk", + "homepage": "http://davedevelopment.co.uk" + } + ], + "description": "Mockery is a simple yet flexible PHP mock object framework for use in unit testing with PHPUnit, PHPSpec or any other testing framework. Its core goal is to offer a test double framework with a succinct API capable of clearly defining all possible object operations and interactions using a human readable Domain Specific Language (DSL). Designed as a drop in alternative to PHPUnit's phpunit-mock-objects library, Mockery is easy to integrate with PHPUnit and can operate alongside phpunit-mock-objects without the World ending.", + "homepage": "http://github.com/padraic/mockery", + "keywords": [ + "BDD", + "TDD", + "library", + "mock", + "mock objects", + "mockery", + "stub", + "test", + "test double", + "testing" + ], + "time": "2015-02-11 12:43:02" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8", + "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "suggest": { + "dflydev/markdown": "~1.0", + "erusev/parsedown": "~1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "phpDocumentor": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "mike.vanriel@naenius.com" + } + ], + "time": "2015-02-03 12:10:50" + }, + { + "name": "phpspec/php-diff", + "version": "v1.0.2", + "source": { + "type": "git", + "url": "https://github.com/phpspec/php-diff.git", + "reference": "30e103d19519fe678ae64a60d77884ef3d71b28a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/php-diff/zipball/30e103d19519fe678ae64a60d77884ef3d71b28a", + "reference": "30e103d19519fe678ae64a60d77884ef3d71b28a", + "shasum": "" + }, + "type": "library", + "autoload": { + "psr-0": { + "Diff": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Chris Boulton", + "homepage": "http://github.com/chrisboulton", + "role": "Original developer" + } + ], + "description": "A comprehensive library for generating differences between two hashable objects (strings or arrays).", + "time": "2013-11-01 13:02:21" + }, + { + "name": "phpspec/phpspec", + "version": "2.1.1", + "source": { + "type": "git", + "url": "https://github.com/phpspec/phpspec.git", + "reference": "66a1df93099282b1514e9e001fcf6e9393f7783d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/phpspec/zipball/66a1df93099282b1514e9e001fcf6e9393f7783d", + "reference": "66a1df93099282b1514e9e001fcf6e9393f7783d", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "~1.0,>=1.0.1", + "php": ">=5.3.3", + "phpspec/php-diff": "~1.0.0", + "phpspec/prophecy": "~1.1", + "sebastian/exporter": "~1.0", + "symfony/console": "~2.3", + "symfony/event-dispatcher": "~2.1", + "symfony/finder": "~2.1", + "symfony/process": "~2.1", + "symfony/yaml": "~2.1" + }, + "require-dev": { + "behat/behat": "~3.0,>=3.0.11", + "bossa/phpspec2-expect": "~1.0", + "symfony/filesystem": "~2.1" + }, + "suggest": { + "phpspec/nyan-formatters": "~1.0 – Adds Nyan formatters" + }, + "bin": [ + "bin/phpspec" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1.x-dev" + } + }, + "autoload": { + "psr-0": { + "PhpSpec": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "homepage": "http://marcelloduarte.net/" + } + ], + "description": "Specification-oriented BDD framework for PHP 5.3+", + "homepage": "http://phpspec.net/", + "keywords": [ + "BDD", + "SpecBDD", + "TDD", + "spec", + "specification", + "testing", + "tests" + ], + "time": "2015-01-09 13:21:45" + }, + { + "name": "phpspec/prophecy", + "version": "v1.3.1", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "9ca52329bcdd1500de24427542577ebf3fc2f1c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/9ca52329bcdd1500de24427542577ebf3fc2f1c9", + "reference": "9ca52329bcdd1500de24427542577ebf3fc2f1c9", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "~1.0,>=1.0.2", + "phpdocumentor/reflection-docblock": "~2.0" + }, + "require-dev": { + "phpspec/phpspec": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "psr-0": { + "Prophecy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "http://phpspec.org", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2014-11-17 16:23:49" + }, + { + "name": "phpunit/php-code-coverage", + "version": "2.0.15", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "34cc484af1ca149188d0d9e91412191e398e0b67" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/34cc484af1ca149188d0d9e91412191e398e0b67", + "reference": "34cc484af1ca149188d0d9e91412191e398e0b67", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "phpunit/php-file-iterator": "~1.3", + "phpunit/php-text-template": "~1.2", + "phpunit/php-token-stream": "~1.3", + "sebastian/environment": "~1.0", + "sebastian/version": "~1.0" + }, + "require-dev": { + "ext-xdebug": ">=2.1.4", + "phpunit/phpunit": "~4" + }, + "suggest": { + "ext-dom": "*", + "ext-xdebug": ">=2.2.1", + "ext-xmlwriter": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2015-01-24 10:06:35" + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.3.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/acd690379117b042d1c8af1fafd61bde001bf6bb", + "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "File/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2013-10-10 15:34:57" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", + "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "Text/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2014-01-30 17:20:04" + }, + { + "name": "phpunit/php-timer", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/19689d4354b295ee3d8c54b4f42c3efb69cbc17c", + "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "PHP/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2013-08-02 07:42:54" + }, + { + "name": "phpunit/php-token-stream", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "db32c18eba00b121c145575fcbcd4d4d24e6db74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/db32c18eba00b121c145575fcbcd4d4d24e6db74", + "reference": "db32c18eba00b121c145575fcbcd4d4d24e6db74", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "time": "2015-01-17 09:51:32" + }, + { + "name": "phpunit/phpunit", + "version": "4.5.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "5b578d3865a9128b9c209b011fda6539ec06e7a5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/5b578d3865a9128b9c209b011fda6539ec06e7a5", + "reference": "5b578d3865a9128b9c209b011fda6539ec06e7a5", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=5.3.3", + "phpspec/prophecy": "~1.3.1", + "phpunit/php-code-coverage": "~2.0", + "phpunit/php-file-iterator": "~1.3.2", + "phpunit/php-text-template": "~1.2", + "phpunit/php-timer": "~1.0.2", + "phpunit/phpunit-mock-objects": "~2.3", + "sebastian/comparator": "~1.1", + "sebastian/diff": "~1.1", + "sebastian/environment": "~1.2", + "sebastian/exporter": "~1.2", + "sebastian/global-state": "~1.0", + "sebastian/version": "~1.0", + "symfony/yaml": "~2.0" + }, + "suggest": { + "phpunit/php-invoker": "~1.1" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.5.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2015-02-05 15:51:19" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "c63d2367247365f688544f0d500af90a11a44c65" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/c63d2367247365f688544f0d500af90a11a44c65", + "reference": "c63d2367247365f688544f0d500af90a11a44c65", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "~1.0,>=1.0.1", + "php": ">=5.3.3", + "phpunit/php-text-template": "~1.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.3" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "time": "2014-10-03 05:12:11" + }, + { + "name": "sebastian/comparator", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "1dd8869519a225f7f2b9eb663e225298fade819e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1dd8869519a225f7f2b9eb663e225298fade819e", + "reference": "1dd8869519a225f7f2b9eb663e225298fade819e", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/diff": "~1.2", + "sebastian/exporter": "~1.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "http://www.github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2015-01-29 16:28:08" + }, + { + "name": "sebastian/diff", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "5843509fed39dee4b356a306401e9dd1a931fec7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/5843509fed39dee4b356a306401e9dd1a931fec7", + "reference": "5843509fed39dee4b356a306401e9dd1a931fec7", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "http://www.github.com/sebastianbergmann/diff", + "keywords": [ + "diff" + ], + "time": "2014-08-15 10:29:00" + }, + { + "name": "sebastian/environment", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "6e6c71d918088c251b181ba8b3088af4ac336dd7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6e6c71d918088c251b181ba8b3088af4ac336dd7", + "reference": "6e6c71d918088c251b181ba8b3088af4ac336dd7", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2014-10-25 08:00:45" + }, + { + "name": "sebastian/exporter", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "84839970d05254c73cde183a721c7af13aede943" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/84839970d05254c73cde183a721c7af13aede943", + "reference": "84839970d05254c73cde183a721c7af13aede943", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/recursion-context": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2015-01-27 07:23:06" + }, + { + "name": "sebastian/global-state", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/c7428acdb62ece0a45e6306f1ae85e1c05b09c01", + "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "time": "2014-10-06 09:23:50" + }, + { + "name": "sebastian/recursion-context", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "3989662bbb30a29d20d9faa04a846af79b276252" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/3989662bbb30a29d20d9faa04a846af79b276252", + "reference": "3989662bbb30a29d20d9faa04a846af79b276252", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2015-01-24 09:48:32" + }, + { + "name": "sebastian/version", + "version": "1.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "a77d9123f8e809db3fbdea15038c27a95da4058b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/a77d9123f8e809db3fbdea15038c27a95da4058b", + "reference": "a77d9123f8e809db3fbdea15038c27a95da4058b", + "shasum": "" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2014-12-15 14:25:24" + }, + { + "name": "symfony/console", + "version": "v2.6.4", + "target-dir": "Symfony/Component/Console", + "source": { + "type": "git", + "url": "https://github.com/symfony/Console.git", + "reference": "e44154bfe3e41e8267d7a3794cd9da9a51cfac34" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Console/zipball/e44154bfe3e41e8267d7a3794cd9da9a51cfac34", + "reference": "e44154bfe3e41e8267d7a3794cd9da9a51cfac34", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/event-dispatcher": "~2.1", + "symfony/process": "~2.1" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Console\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony Console Component", + "homepage": "http://symfony.com", + "time": "2015-01-25 04:39:26" + }, + { + "name": "symfony/event-dispatcher", + "version": "v2.6.4", + "target-dir": "Symfony/Component/EventDispatcher", + "source": { + "type": "git", + "url": "https://github.com/symfony/EventDispatcher.git", + "reference": "f75989f3ab2743a82fe0b03ded2598a2b1546813" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/f75989f3ab2743a82fe0b03ded2598a2b1546813", + "reference": "f75989f3ab2743a82fe0b03ded2598a2b1546813", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~2.0,>=2.0.5", + "symfony/dependency-injection": "~2.6", + "symfony/expression-language": "~2.6", + "symfony/stopwatch": "~2.3" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony EventDispatcher Component", + "homepage": "http://symfony.com", + "time": "2015-02-01 16:10:57" + }, + { + "name": "symfony/finder", + "version": "v2.6.4", + "target-dir": "Symfony/Component/Finder", + "source": { + "type": "git", + "url": "https://github.com/symfony/Finder.git", + "reference": "16513333bca64186c01609961a2bb1b95b5e1355" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Finder/zipball/16513333bca64186c01609961a2bb1b95b5e1355", + "reference": "16513333bca64186c01609961a2bb1b95b5e1355", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Finder\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony Finder Component", + "homepage": "http://symfony.com", + "time": "2015-01-03 08:01:59" + }, + { + "name": "symfony/process", + "version": "v2.6.4", + "target-dir": "Symfony/Component/Process", + "source": { + "type": "git", + "url": "https://github.com/symfony/Process.git", + "reference": "ecfc23e89d9967999fa5f60a1e9af7384396e9ae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Process/zipball/ecfc23e89d9967999fa5f60a1e9af7384396e9ae", + "reference": "ecfc23e89d9967999fa5f60a1e9af7384396e9ae", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Process\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony Process Component", + "homepage": "http://symfony.com", + "time": "2015-01-25 04:39:26" + }, + { + "name": "symfony/yaml", + "version": "v2.6.4", + "target-dir": "Symfony/Component/Yaml", + "source": { + "type": "git", + "url": "https://github.com/symfony/Yaml.git", + "reference": "60ed7751671113cf1ee7d7778e691642c2e9acd8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/60ed7751671113cf1ee7d7778e691642c2e9acd8", + "reference": "60ed7751671113cf1ee7d7778e691642c2e9acd8", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Yaml\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony Yaml Component", + "homepage": "http://symfony.com", + "time": "2015-01-25 04:39:26" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": { + "mockery/mockery": 20 + }, + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=5.4.0" + }, + "platform-dev": [] +} diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 00000000..98ae332e --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,18 @@ + + + + + ./tests/ + + + \ No newline at end of file diff --git a/src/Prettus/Repository/Contracts/Criteria.php b/src/Prettus/Repository/Contracts/Criteria.php new file mode 100644 index 00000000..573310d8 --- /dev/null +++ b/src/Prettus/Repository/Contracts/Criteria.php @@ -0,0 +1,18 @@ +request = $request; + } + + /** + * Apply criteria in query repository + * + * @param $query + * @param Repository $repository + * @return mixed + */ + public function apply($query, Repository $repository) + { + $fieldsSearchable = $repository->getFieldsSearchable(); + $search = $this->request->get( config('repository-criteria.params.search','search') , null); + $searchFields = $this->request->get( config('repository-criteria.params.searchFields','searchFields') , null); + $filter = $this->request->get( config('repository-criteria.params.filter','filter') , null); + $orderBy = $this->request->get( config('repository-criteria.params.orderBy','orderBy') , null); + $sortedBy = $this->request->get( config('repository-criteria.params.sortedBy','sortedBy') , 'asc'); + $sortedBy = !empty($sortedBy) ? $sortedBy : 'asc'; + + if( $search && is_array($fieldsSearchable) && count($fieldsSearchable) ) { + + $searchFields = is_array($searchFields) || is_null($searchFields) ? $searchFields : explode(';',$searchFields); + $fields = $this->parserFieldsSearch($fieldsSearchable, $searchFields); + $isFirstField = true; + $searchData = array(); + $queryForceAndWhere = false; + + foreach($fields as $field=>$condition) + { + if(is_numeric($field)){ + $field = $condition; + $condition = "="; + } + + $condition = trim(strtolower($condition)); + + if( isset($searchData[$field]) ) + { + $value = $condition == "like" ? "%{$searchData[$field]}%" : $searchData[$field]; + } + else + { + $value = $condition == "like" ? "%{$search}%" : $search; + } + + if( $isFirstField || $queryForceAndWhere ) + { + $query = $query->where($field,$condition,$value); + $isFirstField = false; + } + else + { + $query = $query->orWhere($field,$condition,$value); + } + } + } + + if( isset($orderBy) && !empty($orderBy) ) + { + $query = $query->orderBy($orderBy, $sortedBy); + } + + if( isset($filter) && !empty($filter) ) + { + if( is_string($filter) ){ + $filter = explode(';', $filter); + } + $query = $query->select($filter); + } + + return $query; + } + + protected function parserFieldsSearch(array $fields = array(), array $searchFields = null){ + + if( !is_null($searchFields) && count($searchFields) ){ + + $acceptedConditions = config('repository-criteria.acceptedConditions', array('=','like') ); + $originalFields = $fields; + $fields = []; + + foreach($searchFields as $index => $field){ + + $field_parts = explode(':', $field); + $_index = array_search($field_parts[0], $originalFields); + + if( count($field_parts) == 2 ) + { + if( in_array($field_parts[1],$acceptedConditions) ) + { + unset($originalFields[$_index]); + $field = $field_parts[0]; + $condition = $field_parts[1]; + $originalFields[$field] = $condition; + $searchFields[$index] = $field; + } + } + + } + + foreach($originalFields as $field=>$condition) + { + if(is_numeric($field)){ + $field = $condition; + $condition = "="; + } + + if( in_array($field, $searchFields) ) + { + $fields[$field] = $condition; + } + } + + if( count($fields) == 0 ){ + throw new \Exception( trans('prettus-repository::criteria.fields_not_accepted', array('field'=>implode(',', $searchFields))) ); + } + } + + return $fields; + } +} \ No newline at end of file diff --git a/src/Prettus/Repository/Eloquent/Repository.php b/src/Prettus/Repository/Eloquent/Repository.php new file mode 100644 index 00000000..4d970ebe --- /dev/null +++ b/src/Prettus/Repository/Eloquent/Repository.php @@ -0,0 +1,247 @@ +model = $model; + $this->criteria = new Collection(); + $this->scopeReset(); + } + + /** + * Reset internal Query + * + * @return $this + */ + public function scopeReset() + { + $this->query = $this->model; + $this->skipCriteria(false); + return $this; + } + + /** + * Find data by id + * + * @param $id + * @param array $columns + * @return Model|Collection + */ + public function find($id, $columns = array('*')) + { + $this->applyCriteria(); + return $this->query->find($id, $columns); + } + + /** + * Find data by field and value + * + * @param $field + * @param $value + * @param array $columns + * @return Model|Collection + */ + public function findByField($field, $value, $columns = array('*')) + { + $this->applyCriteria(); + return $this->query->where($field,'=',$value)->first(); + } + + /** + * Retrieve all data of repository + * + * @param array $columns + * @return Collection + */ + public function all($columns = array('*')) + { + $this->applyCriteria(); + + if( $this->query instanceof \Illuminate\Database\Eloquent\Builder ){ + return $this->query->get($columns); + } + + return $this->query->all($columns); + } + + /** + * Retrieve all data of repository, paginated + * @param null $limit + * @param array $columns + * @return LengthAwarePaginator + */ + public function paginate($limit = null, $columns = array('*')) + { + $this->applyCriteria(); + return $this->query->paginate($limit, $columns); + } + + /** + * Save a new entity in repository + * + * @param array $attributes + * @return Model + */ + public function create(array $attributes) + { + return $this->query->create($attributes); + } + + /** + * Update a entity in repository by id + * + * @param array $attributes + * @param $id + * @return Model + */ + public function update(array $attributes, $id) + { + $model = $this->find($id); + $model->fill($attributes); + return $model->save(); + } + + /** + * Delete a entity in repository by id + * + * @param $id + * @return int + */ + public function delete($id) + { + $model = $this->find($id); + return $model->delete(); + } + + /** + * Load relations + * + * @param array $relations + * @return $this + */ + public function with(array $relations) + { + $this->query = $this->query->with($relations); + return $this; + } + + /** + * Get repository model + * + * @return Model + */ + public function getModel() + { + return $this->model; + } + + /** + * Push Criteria for filter the query + * + * @param Criteria $criteria + * @return mixed + */ + public function pushCriteria(Criteria $criteria) + { + $this->criteria->push($criteria); + return $this; + } + + /** + * Get Collection of Criteria + * + * @return Collection + */ + public function getCriteria(){ + return $this->criteria; + } + + /** + * Find data by Criteria + * + * @param Criteria $criteria + * @return mixed + */ + public function getByCriteria(Criteria $criteria) + { + $this->query = $criteria->apply($this->query, $this); + return $this->query->get(); + } + + /** + * Skip Criteria + * + * @return $this + */ + public function skipCriteria($status = true){ + $this->skipCriteria = $status; + return $this; + } + + /** + * Apply criteria in current Query + * + * @return $this + */ + protected function applyCriteria(){ + + if( $this->skipCriteria === true ) + return $this; + + $criteria = $this->getCriteria(); + + foreach($criteria as $c){ + if( $c instanceof Criteria ){ + $this->query = $c->apply($this->query, $this); + } + } + + return $this; + } + + /** + * Get Searchable Fields + * + * @return array + */ + public function getFieldsSearchable(){ + return $this->fieldSearchable; + } +} \ No newline at end of file diff --git a/src/Prettus/Repository/Exceptions/RepositoryException.php b/src/Prettus/Repository/Exceptions/RepositoryException.php new file mode 100644 index 00000000..e07f0ac7 --- /dev/null +++ b/src/Prettus/Repository/Exceptions/RepositoryException.php @@ -0,0 +1,7 @@ +loadTranslationsFrom(__DIR__.'/../../lang', 'prettus-repository'); + $this->publishes([ + __DIR__.'/../../config/repository-criteria.php' => config_path('repository-criteria.php') + ]); + } +} \ No newline at end of file diff --git a/src/config/repository-criteria.php b/src/config/repository-criteria.php new file mode 100644 index 00000000..fa3b7aea --- /dev/null +++ b/src/config/repository-criteria.php @@ -0,0 +1,72 @@ +['=','like'] + | + | $query->where('foo','=','bar') + | $query->where('foo','like','bar') + | + */ + 'acceptedConditions'=>[ + '=','like' + ], + + /* + |-------------------------------------------------------------------------- + | Request Params + |-------------------------------------------------------------------------- + | + | Request parameters that will be used to filter the query in the repository + | + | Params : + | + | - search : Searched value + | Ex: http://localhost/?search=lorem + | + | - searchFields : Fields in which research should be carried out + | Ex: + | http://localhost/?search=lorem&searchFields=name;email + | http://localhost/?search=lorem&searchFields=name:like;email + | http://localhost/?search=lorem&searchFields=name:like + | + | - filter : Fields that must be returned to the response object + | Ex: + | http://localhost/?search=lorem&filter=id,name + | + | - orderBy : Order By + | Ex: + | http://localhost/?search=lorem&orderBy=id + | + | - sortedBy : Sort + | Ex: + | http://localhost/?search=lorem&orderBy=id&sortedBy=asc + | http://localhost/?search=lorem&orderBy=id&sortedBy=desc + | + */ + 'params'=>[ + 'search' =>'search', + 'searchFields' =>'searchFields', + 'filter' =>'filter', + 'orderBy' =>'orderBy', + 'sortedBy' =>'sortedBy' + ] +]; \ No newline at end of file diff --git a/src/lang/en/criteria.php b/src/lang/en/criteria.php new file mode 100644 index 00000000..cf7a7238 --- /dev/null +++ b/src/lang/en/criteria.php @@ -0,0 +1,4 @@ +'Columns :field are not accepted in the research' +); \ No newline at end of file diff --git a/src/lang/pt-br/criteria.php b/src/lang/pt-br/criteria.php new file mode 100644 index 00000000..5470ac0f --- /dev/null +++ b/src/lang/pt-br/criteria.php @@ -0,0 +1,4 @@ +'As colunas :field não são aceitas nessa consulta.' +); \ No newline at end of file diff --git a/tests/Prettus/Repository/Test/Contracts/CriteriaTest.php b/tests/Prettus/Repository/Test/Contracts/CriteriaTest.php new file mode 100644 index 00000000..31ca7297 --- /dev/null +++ b/tests/Prettus/Repository/Test/Contracts/CriteriaTest.php @@ -0,0 +1,43 @@ +shouldReceive('where') + ->once() + ->with('name','=','bar') + ->andReturnSelf(); + + $criteria = new CriteriaDumb($query); + + $this->assertEquals($query, $criteria->apply($query, $repository)); + } +} + +class CriteriaDumb implements Criteria { + + /** + * Apply criteria in query repository + * + * @param $query + * @param Repository $repository + * @return mixed + */ + public function apply($query, Repository $repository) + { + $query = $query->where('name','=','bar'); + return $query; + } +} \ No newline at end of file diff --git a/tests/Prettus/Repository/Test/Eloquent/RepositoryTest.php b/tests/Prettus/Repository/Test/Eloquent/RepositoryTest.php new file mode 100644 index 00000000..b6e15bdc --- /dev/null +++ b/tests/Prettus/Repository/Test/Eloquent/RepositoryTest.php @@ -0,0 +1,172 @@ +mock = m::mock('Illuminate\Database\Eloquent\Model'); + } + + public function createRepository($model){ + return new RepositoryEloquentDumb($model); + } + + public function testGetModelReturnModel(){ + $this->repository = $this->createRepository($this->mock); + $this->assertEquals($this->mock, $this->repository->getModel()); + } + + public function testFindById(){ + + $this->mock->shouldReceive('find') + ->with(1, array('*')) + ->once() + ->andReturn('foo'); + + $this->repository = $this->createRepository($this->mock); + $this->assertEquals('foo', $this->repository->find(1)); + } + + public function testFindByField(){ + + $this->mock->shouldReceive('where') + ->with('name','=','foo') + ->once() + ->andReturnSelf() + ->getMock() + ->shouldReceive('first') + ->once() + ->andReturn('foo'); + + $this->repository = $this->createRepository($this->mock); + $this->assertEquals('foo', $this->repository->findByField('name','foo')); + + } + + public function testGetAllWithoutCriteria(){ + + $this->mock->shouldReceive('all') + ->with(array('*')) + ->once() + ->andReturn('foo'); + + $this->repository = $this->createRepository($this->mock); + $this->assertEquals('foo', $this->repository->all()); + } + + public function testGetPaginator(){ + + $this->mock->shouldReceive('paginate') + ->with(10, array('*')) + ->once() + ->andReturn('foo'); + + $this->repository = $this->createRepository($this->mock); + $this->assertEquals('foo', $this->repository->paginate(10)); + } + + public function testCreate(){ + + $attributes = array('name'=>'Anderson'); + $this->mock->shouldReceive('create') + ->once() + ->with($attributes) + ->andReturn('foo'); + + $this->repository = $this->createRepository($this->mock); + $this->assertEquals('foo', $this->repository->create($attributes)); + + } + + public function testUpdate(){ + + $attributes = array('name'=>'Anderson'); + $this->mock + ->shouldReceive('find') + ->once() + ->with(1, array('*')) + ->andReturnSelf() + ->getMock() + ->shouldReceive('fill') + ->once() + ->with($attributes) + ->andReturnSelf() + ->getMock() + ->shouldReceive('save') + ->andReturn('foo'); + + $this->repository = $this->createRepository($this->mock); + $this->assertEquals('foo', $this->repository->update($attributes, 1)); + + } + + public function testDelete(){ + + $this->mock + ->shouldReceive('find') + ->once() + ->with(1, array('*')) + ->andReturnSelf() + ->getMock() + ->shouldReceive('delete') + ->once() + ->andReturn(1); + + $this->repository = $this->createRepository($this->mock); + $this->assertEquals(1, $this->repository->delete(1)); + + } + + public function testeSetRelationshipWith(){ + + $this->mock + ->shouldReceive('with') + ->once() + ->with(array('foo')) + ->andReturnSelf(); + + $this->repository = $this->createRepository($this->mock); + $this->assertEquals($this->repository, $this->repository->with(array('foo'))); + + } + +} + +class RepositoryEloquentDumb extends \Prettus\Repository\Eloquent\Repository { + +} + +class CriteriaDumb implements \Prettus\Repository\Contracts\Criteria { + + + /** + * Apply criteria in query repository + * + * @param $query + * @param Repository $repository + * @return mixed + */ + public function apply($query, Repository $repository) + { + $query->where('1',1,1); + return $query; + } +} \ No newline at end of file