├── .gitignore ├── .travis.yml ├── src ├── Exceptions │ └── TransformerException.php ├── Config │ └── transformers.php ├── Contracts │ └── Transformable.php ├── stubs │ └── transformer.stub ├── TransformableTrait.php ├── Commands │ └── MakeTransformerCommand.php ├── Providers │ └── TransformerServiceProvider.php └── Transformer.php ├── phpunit.xml ├── tests ├── Models │ ├── Tag.php │ ├── Post.php │ └── User.php ├── TransformableTest.php ├── TestCase.php └── TransformerTest.php ├── composer.json ├── LICENSE.md ├── README.md └── composer.lock /.gitignore: -------------------------------------------------------------------------------- 1 | vendor/ 2 | .idea/ -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | install: composer install 2 | language: php 3 | 4 | php: 5 | - 5.6 6 | - 7.0 -------------------------------------------------------------------------------- /src/Exceptions/TransformerException.php: -------------------------------------------------------------------------------- 1 | [ 9 | 10 | ] 11 | ]; 12 | -------------------------------------------------------------------------------- /src/Contracts/Transformable.php: -------------------------------------------------------------------------------- 1 | $item->id 18 | ]; 19 | } 20 | } -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 15 | ./tests 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/TransformableTrait.php: -------------------------------------------------------------------------------- 1 | transformer) { 17 | $transformer = App::make($this->transformer); 18 | } 19 | 20 | elseif (Transformer::canMake($modelName)) { 21 | $transformer = Transformer::make($modelName); 22 | } 23 | 24 | // If not a transformer instance. 25 | if (! $transformer instanceof Transformer) { 26 | throw new TransformerException('Model transformer not an instance of transformer class'); 27 | } 28 | 29 | return $transformer; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/Models/Tag.php: -------------------------------------------------------------------------------- 1 | $tag->name 21 | ]; 22 | } 23 | } 24 | 25 | class Tag extends Model implements Transformable 26 | { 27 | use TransformableTrait; 28 | 29 | /** 30 | * @var 31 | */ 32 | protected $transformer = TagTransformer::class; 33 | 34 | /** 35 | * @return \Illuminate\Database\Eloquent\Relations\BelongsTo 36 | */ 37 | public function post() 38 | { 39 | return $this->belongsToMany(Post::class); 40 | } 41 | } -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "logaretm/transformers", 3 | "description": "Simple laravel eloquent models transformers.", 4 | "license": "MIT", 5 | "keywords": ["laravel", "transformers"], 6 | "authors": [ 7 | { 8 | "name": "Abdelrahman Awad", 9 | "email": "logaretm1@gmail.com" 10 | } 11 | ], 12 | "require": { 13 | "illuminate/support": "^5.2", 14 | "illuminate/console": "^5.2" 15 | }, 16 | "autoload": { 17 | "psr-4": { 18 | "Logaretm\\Transformers\\": "src/" 19 | } 20 | }, 21 | "autoload-dev": { 22 | "classmap": ["tests/TestCase.php"], 23 | "psr-4": { 24 | "Logaretm\\Transformers\\Tests\\": "tests/" 25 | } 26 | }, 27 | "require-dev": { 28 | "phpunit/phpunit": "^5.2", 29 | "illuminate/database": "^5.2", 30 | "fzaninotto/faker": "^1.5", 31 | "illuminate/pagination": "^5.2", 32 | "mockery/mockery": "^0.9.4" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Commands/MakeTransformerCommand.php: -------------------------------------------------------------------------------- 1 | 4 | 5 | > Permission is hereby granted, free of charge, to any person obtaining a copy 6 | > of this software and associated documentation files (the "Software"), to deal 7 | > in the Software without restriction, including without limitation the rights 8 | > to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | > copies of the Software, and to permit persons to whom the Software is 10 | > furnished to do so, subject to the following conditions: 11 | > 12 | > The above copyright notice and this permission notice shall be included in 13 | > all copies or substantial portions of the Software. 14 | > 15 | > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | > THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /tests/Models/Post.php: -------------------------------------------------------------------------------- 1 | $post->title, 21 | 'body' => $post->body, 22 | 'created' => $post->created_at->timestamp 23 | ]; 24 | } 25 | } 26 | 27 | class Post extends Model implements Transformable 28 | { 29 | use TransformableTrait; 30 | 31 | /** 32 | * @var 33 | */ 34 | protected $transformer = PostTransformer::class; 35 | 36 | /** 37 | * @return \Illuminate\Database\Eloquent\Relations\BelongsTo 38 | */ 39 | public function author() 40 | { 41 | return $this->belongsTo(User::class, 'user_id'); 42 | } 43 | 44 | /** 45 | * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany 46 | */ 47 | public function tags() 48 | { 49 | return $this->belongsToMany(Tag::class); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Providers/TransformerServiceProvider.php: -------------------------------------------------------------------------------- 1 | publishes([ 20 | __DIR__ . '/../config/transformers.php' => config_path('transformers.php') 21 | ], 'config'); 22 | 23 | $this->commands([ 24 | MakeTransformerCommand::class 25 | ]); 26 | } 27 | 28 | /** 29 | * Register the application services. 30 | * 31 | * @return void 32 | */ 33 | public function register() 34 | { 35 | if (Transformer::isConfigPublished()) { 36 | $this->registerTransformers(); 37 | } 38 | } 39 | 40 | /** 41 | * 42 | */ 43 | protected function registerTransformers() 44 | { 45 | foreach (Config::get('transformers.transformers') as $class => $transformerClass) { 46 | $this->app->singleton($transformerClass, function () use ($transformerClass) { 47 | return new $transformerClass(); 48 | }); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /tests/Models/User.php: -------------------------------------------------------------------------------- 1 | $user->name, 21 | 'email' => $user->email, 22 | 'memberSince' => $user->created_at->timestamp 23 | ]; 24 | } 25 | 26 | // Custom/Alternate transformation. 27 | public function adminTransformation($user) 28 | { 29 | return [ 30 | 'name' => $user->name, 31 | 'email' => $user->email, 32 | 'memberSince' => $user->created_at->timestamp, 33 | 'isAdmin' => $user->id === 1 34 | ]; 35 | } 36 | } 37 | 38 | class User extends Model implements Transformable 39 | { 40 | use TransformableTrait; 41 | 42 | /** 43 | * @var 44 | */ 45 | protected $transformer = UserTransformer::class; 46 | 47 | /** 48 | * @return \Illuminate\Database\Eloquent\Relations\HasMany 49 | */ 50 | public function posts() 51 | { 52 | return $this->hasMany(Post::class); 53 | } 54 | 55 | /** 56 | * Removes the property from the user object, for testing purposes. 57 | */ 58 | public function unsetTransformerProperty() 59 | { 60 | unset($this->transformer); 61 | } 62 | 63 | /** 64 | * [getIsOfAgeAttribute description] 65 | * @return [type] [description] 66 | */ 67 | public function getIsOfAgeAttribute() 68 | { 69 | return true; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /tests/TransformableTest.php: -------------------------------------------------------------------------------- 1 | makeUsers(1); 20 | 21 | App::shouldReceive('make') 22 | ->once() 23 | ->with(UserTransformer::class) 24 | ->andReturn(new UserTransformer); 25 | 26 | $transformer = $user->getTransformer(); 27 | 28 | $this->assertInstanceOf(UserTransformer::class, $transformer); 29 | } 30 | 31 | /** @test */ 32 | function it_throws_an_exception_if_a_model_uses_the_trait_but_does_not_define_the_transformer() 33 | { 34 | $model = new BadModel; 35 | 36 | // Mock config call. 37 | Config::shouldReceive('has') 38 | ->once() 39 | ->with('transformers.transformers') 40 | ->andReturn(false); 41 | 42 | // $this->setExpectedException(TransformerException::class); 43 | $this->expectException(TransformerException::class); 44 | 45 | // fails, throws a TransformerException. 46 | $model->getTransformer(); 47 | } 48 | 49 | /** @test */ 50 | function it_throws_an_exception_if_a_model_uses_the_trait_but_defines_an_invalid_transformer_class() 51 | { 52 | $model = new AnotherBadModel; 53 | 54 | App::shouldReceive('make') 55 | ->once() 56 | ->with(User::class) 57 | ->andReturn(new User()); 58 | 59 | // $this->setExpectedException(TransformerException::class); 60 | $this->expectException(TransformerException::class); 61 | 62 | $model->getTransformer(); 63 | } 64 | 65 | /** @test */ 66 | function it_instantiates_the_transformer_if_a_model_uses_the_trait_and_was_defined_in_the_config() 67 | { 68 | $user = $this->makeUsers(1, true); 69 | $user->unsetTransformerProperty(); 70 | 71 | Config::shouldReceive('has') 72 | ->twice() 73 | ->with('transformers.transformers') 74 | ->andReturn(true); 75 | 76 | Config::shouldReceive('get') 77 | ->twice() 78 | ->with('transformers.transformers') 79 | ->andReturn([User::class => UserTransformer::class]); 80 | 81 | App::shouldReceive('make') 82 | ->once() 83 | ->with(UserTransformer::class) 84 | ->andReturn(new UserTransformer); 85 | 86 | $this->assertInstanceOf(UserTransformer::class, $user->getTransformer()); 87 | } 88 | } 89 | 90 | 91 | class BadModel extends Model implements Transformable 92 | { 93 | use TransformableTrait; 94 | } 95 | 96 | class AnotherBadModel extends Model implements Transformable 97 | { 98 | use TransformableTrait; 99 | 100 | protected $transformer = User::class; 101 | } -------------------------------------------------------------------------------- /tests/TestCase.php: -------------------------------------------------------------------------------- 1 | setUpDatabase(); 14 | $this->migrateTables(); 15 | } 16 | 17 | /** 18 | * Sets up a sqlite in memory database. 19 | */ 20 | protected function setUpDatabase() 21 | { 22 | $database = new DB; 23 | 24 | $database->addConnection(['driver' => 'sqlite', 'database' => ':memory:']); 25 | $database->bootEloquent(); 26 | $database->setAsGlobal(); 27 | } 28 | 29 | /** 30 | * Migrates the tables required for testing. 31 | */ 32 | protected function migrateTables() 33 | { 34 | DB::schema()->create('users', function (Blueprint $table) { 35 | $table->increments('id'); 36 | $table->string('name'); 37 | $table->string('email'); 38 | $table->timestamps(); 39 | }); 40 | 41 | DB::schema()->create('posts', function (Blueprint $table) { 42 | $table->increments('id'); 43 | $table->string('title'); 44 | $table->text('body'); 45 | $table->unsignedInteger('user_id')->index(); 46 | $table->timestamps(); 47 | }); 48 | 49 | DB::schema()->create('tags', function (Blueprint $table) { 50 | $table->increments('id'); 51 | $table->string('name'); 52 | $table->timestamps(); 53 | }); 54 | 55 | DB::schema()->create('post_tag', function (Blueprint $table) { 56 | $table->unsignedInteger('tag_id')->index(); 57 | $table->unsignedInteger('post_id')->index(); 58 | }); 59 | 60 | DB::schema()->create('categories', function (Blueprint $table) { 61 | $table->increments('id'); 62 | $table->string('title'); 63 | $table->text('description')->nullable(); 64 | $table->timestamps(); 65 | }); 66 | } 67 | 68 | /** 69 | * @param int $count 70 | * @param bool $save 71 | * @return array|User 72 | */ 73 | protected function makeUsers($count = 1, $save = false) 74 | { 75 | $faker = Faker\Factory::create(); 76 | $users = []; 77 | 78 | for ($i = 0; $i < $count; $i++) { 79 | $user = new User; 80 | $user->name = $faker->name; 81 | $user->email = $faker->email; 82 | 83 | if ($save) { 84 | $user->save(); 85 | } 86 | 87 | $users[] = $user; 88 | } 89 | 90 | return $count === 1 ? $users[0] : $users; 91 | } 92 | 93 | /** 94 | * @param int $count 95 | * @return array 96 | */ 97 | protected function makeTags($count = 10) 98 | { 99 | $faker = Faker\Factory::create(); 100 | 101 | $tagIds = []; 102 | foreach (range(1, $count, 1) as $value) { 103 | $tag = new Tag(); 104 | $tag->name = $faker->word; 105 | $tag->save(); 106 | 107 | $tagIds[] = $tag->id; 108 | } 109 | 110 | return $tagIds; 111 | } 112 | 113 | /** 114 | * @param int $count 115 | * @param bool $save 116 | * @return array 117 | */ 118 | protected function makePosts($count = 1, $save = false) 119 | { 120 | $faker = Faker\Factory::create(); 121 | $posts = []; 122 | 123 | for ($i = 0; $i < $count; $i++) { 124 | $post = new Post(); 125 | $post->title = $faker->title; 126 | $post->body = $faker->sentence; 127 | 128 | if ($save) { 129 | $post->save(); 130 | } 131 | 132 | $posts[] = $post; 133 | } 134 | 135 | return $count === 1 ? $posts[0] : $posts; 136 | } 137 | 138 | /** 139 | * @return User 140 | */ 141 | protected function makeUserWithPosts() 142 | { 143 | $user = $this->makeUsers(1, true); 144 | $posts = $user->posts()->saveMany($this->makePosts(3, false)); 145 | 146 | foreach ($posts as $post) { 147 | $post->tags()->attach($this->makeTags(4)); 148 | } 149 | 150 | return $user; 151 | } 152 | } -------------------------------------------------------------------------------- /tests/TransformerTest.php: -------------------------------------------------------------------------------- 1 | makeUsers(1, true); 18 | $transformer = new UserTransformer(); 19 | 20 | $this->assertEquals([ 21 | 'name' => $user->name, 22 | 'email' => $user->email, 23 | 'memberSince' => $user->created_at->timestamp 24 | ], $transformer->transform($user)); 25 | } 26 | 27 | /** @test */ 28 | function it_transforms_an_array_of_models() 29 | { 30 | $users = $this->makeUsers(3, true); 31 | $user = $users[0]; 32 | $transformer = new UserTransformer(); 33 | 34 | $this->assertEquals([ 35 | 'name' => $user->name, 36 | 'email' => $user->email, 37 | 'memberSince' => $user->created_at->timestamp 38 | ], $transformer->transform($users)[0]); 39 | } 40 | 41 | /** @test */ 42 | function it_transformers_a_collection_of_the_model() 43 | { 44 | $this->makeUsers(10, true); 45 | $transformer = new UserTransformer(); 46 | $users = User::get(); 47 | 48 | // make sure its the same count as the created users. 49 | $this->assertCount(10, $transformer->transform($users)); 50 | } 51 | 52 | /** @test */ 53 | function it_transforms_a_paginator_of_the_model() 54 | { 55 | $this->makeUsers(15, true); 56 | $transformer = new UserTransformer(); 57 | $users = User::paginate(5); 58 | 59 | $this->assertCount(5, $transformer->transform($users)); 60 | } 61 | 62 | /** @test */ 63 | function it_transforms_related_models() 64 | { 65 | $this->makeUserWithPosts(); 66 | $user = User::first(); 67 | $transformer = new UserTransformer(); 68 | 69 | App::shouldReceive('make') 70 | ->once() 71 | ->with(PostTransformer::class) 72 | ->andReturn(new PostTransformer); 73 | 74 | $transformedData = $transformer->with('posts')->transform($user); 75 | 76 | $this->assertCount(3, $transformedData['posts']); 77 | } 78 | 79 | /** @test */ 80 | function it_transforms_nested_relations() 81 | { 82 | $this->makeUserWithPosts(); 83 | 84 | $user = User::first(); 85 | $transformer = new UserTransformer(); 86 | 87 | App::shouldReceive('make') 88 | ->once() 89 | ->with(PostTransformer::class) 90 | ->andReturn(new PostTransformer()); 91 | 92 | App::shouldReceive('make') 93 | ->once() 94 | ->with(TagTransformer::class) 95 | ->andReturn(new TagTransformer()); 96 | 97 | $transformedData = $transformer->with('posts.tags')->transform($user); 98 | 99 | $this->assertCount(3, $transformedData['posts']); 100 | $this->assertCount(4, $transformedData['posts'][0]['tags']); 101 | } 102 | 103 | /** @test */ 104 | function it_uses_multiple_transformations() 105 | { 106 | $user = $this->makeUsers(1, true); 107 | $transformer = new UserTransformer(); 108 | 109 | $this->assertArrayNotHasKey('isAdmin', $transformer->transform($user)); 110 | $transformer->setTransformation('admin'); 111 | 112 | $this->assertArrayHasKey('isAdmin', $transformer->transform($user)); 113 | } 114 | 115 | /** @test */ 116 | function it_allows_a_closure_as_an_alternate_transformation_method() 117 | { 118 | $user = $this->makeUsers(1, true); 119 | $transformer = new UserTransformer(); 120 | 121 | $transformer->setTransformation(function ($user) { 122 | return [ 123 | 'name' => $user->name, 124 | 'isAdmin' => true, 125 | ]; 126 | }); 127 | 128 | $this->assertEquals(['name' => $user->name, 'isAdmin' => true], $transformer->transform($user)); 129 | } 130 | 131 | /** @test */ 132 | function it_throws_an_exception_if_a_requested_transformation_does_not_exist() 133 | { 134 | $this->makeUsers(1, true); 135 | $transformer = new UserTransformer(); 136 | 137 | $this->expectException(TransformerException::class); 138 | $transformer->setTransformation('public'); 139 | } 140 | 141 | /** @test */ 142 | function it_returns_empty_array_if_the_related_has_empty_collection() 143 | { 144 | $this->makeUserWithPosts(); 145 | $post = Post::first(); 146 | $post->user_id = 0; 147 | $post->save(); 148 | $transformer = new PostTransformer(); 149 | $transformed = $transformer->with('author')->transform($post); 150 | $this->assertEquals($transformed['author'], null); 151 | 152 | $user = User::first(); 153 | $user->posts()->delete(); 154 | $transformer = new UserTransformer(); 155 | 156 | $transformed = $transformer->with('posts.tags')->transform($user); 157 | 158 | $this->assertEquals($transformed['posts'], []); 159 | } 160 | 161 | /** @test */ 162 | function it_also_includes_getters_in_the_transformation() 163 | { 164 | $this->makeUserWithPosts(); 165 | $user = User::first(); 166 | $transformer = new UserTransformer(); 167 | $transformed = $transformer->with('isOfAge')->transform($user); 168 | 169 | $this->assertTrue($transformed['isOfAge']); 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /src/Transformer.php: -------------------------------------------------------------------------------- 1 | normalize($object)) instanceof Collection) { 41 | return $this->transformCollection($collection); 42 | } 43 | 44 | // If there are relations setup, transform it along with the object. 45 | if ($this->relatedCount) { 46 | return $this->transformWithRelated($object); 47 | } 48 | 49 | // If another transformation method was requested, use that instead. 50 | if (is_callable($this->transformationMethod)) { 51 | return $this->getAlternateTransformation($object); 52 | } 53 | 54 | return $this->getTransformation($object); 55 | } 56 | 57 | /** 58 | * Normalizes the object to a collection if it is some sort of a container to multiple items. 59 | * 60 | * @param $object 61 | * @return Collection 62 | */ 63 | protected function normalize($object) 64 | { 65 | // If its a paginator instance, create a collection with its items. 66 | if ($object instanceof Paginator) { 67 | return collect($object->items()); 68 | } elseif (is_array($object)) { 69 | // If its an array, package it in a collection. 70 | return collect($object); 71 | } 72 | 73 | return $object; 74 | } 75 | 76 | /** 77 | * Calls the selected alternate transformation method. 78 | * 79 | * @param $item 80 | * @return mixed 81 | */ 82 | public function getAlternateTransformation($item) 83 | { 84 | return call_user_func($this->transformationMethod, $item); 85 | } 86 | 87 | /** 88 | * @param $item 89 | * @return mixed 90 | */ 91 | abstract public function getTransformation($item); 92 | 93 | /** 94 | * Transforms the item with its related models. 95 | * 96 | * @param $item 97 | * @return array 98 | */ 99 | public function transformWithRelated($item) 100 | { 101 | $transformedItem = $this->getTransformation($item); 102 | 103 | return $this->transformRelated($transformedItem, $item); 104 | } 105 | 106 | /** 107 | * Adds a relation to the transformer. 108 | * 109 | * @param $relation 110 | * @return $this 111 | */ 112 | public function with($relation) 113 | { 114 | $this->reset(); 115 | 116 | if (func_num_args() > 1) { 117 | return $this->with(func_get_args()); 118 | } 119 | 120 | if (is_array($relation)) { 121 | $this->related = array_merge($this->related, $relation); 122 | } else { 123 | $this->related[] = $relation; 124 | } 125 | 126 | $this->relatedCount = count($this->related); 127 | 128 | return $this; 129 | } 130 | 131 | /** 132 | * Sets the current transformation. 133 | * 134 | * @param $transformation 135 | * @return $this 136 | * @throws TransformerException 137 | */ 138 | public function setTransformation($transformation) 139 | { 140 | if (is_callable($transformation)) { 141 | $this->transformationMethod = $transformation; 142 | 143 | return $this; 144 | } 145 | 146 | // replace just to avoid wrongly passing the name containing "Transformation". 147 | $methodName = str_replace('Transformation', '', $transformation) . "Transformation"; 148 | 149 | if (! method_exists($this, $methodName)) { 150 | throw new TransformerException("No such transformation as $methodName defined."); 151 | } 152 | 153 | $this->transformationMethod = [$this, $methodName]; 154 | 155 | return $this; 156 | } 157 | 158 | /** 159 | * Transforms a collection. 160 | * 161 | * @param \Illuminate\Support\Collection $collection 162 | * @return array 163 | */ 164 | public function transformCollection(Collection $collection) 165 | { 166 | // Use collection's built in map method. 167 | 168 | return $collection->map([$this, 'transform'])->all(); 169 | } 170 | 171 | /** 172 | * Transforms the related item, and adds it to the transformation array. 173 | * 174 | * @param $itemTransformation 175 | * @param $item 176 | * @return array 177 | */ 178 | protected function transformRelated($itemTransformation, $item) 179 | { 180 | foreach ($this->related as $relation) { 181 | // get direct relation name. 182 | $relationName = explode('.', $relation, 2)[0]; 183 | $itemTransformation[$relationName] = $this->getRelatedTransformation($item, $relation); 184 | } 185 | 186 | return $itemTransformation; 187 | } 188 | 189 | /** 190 | * Resolves the transformation for the related model. 191 | * 192 | * @param $item 193 | * @param $relation 194 | * @return mixed 195 | */ 196 | protected function getRelatedTransformation($item, $relation) 197 | { 198 | // get nested relations separated by the dot notation. 199 | // we only get one relation at a time because recursion handles the remaining relations. 200 | $nestedRelations = explode('.', $relation, 2); 201 | $relation = $nestedRelations[0]; 202 | 203 | $result = $item->{$relation}; 204 | $related = $result; 205 | 206 | $transformer = null; 207 | 208 | if (! is_object($related)) { 209 | return $related; 210 | } 211 | 212 | // if its a collection switch the object to the first item. 213 | if ($related instanceof Collection) { 214 | if ($related->count()) { 215 | $result = $result[0]; 216 | } else { 217 | return []; 218 | } 219 | } 220 | 221 | $transformer = $this->resolveTransformer($result); 222 | 223 | // If no transformer was resolved. 224 | if (! $transformer) { 225 | return $related->toArray(); 226 | } 227 | 228 | // if it has nested relations (equal to or more than 2 levels) 229 | if (count($nestedRelations) == 2) { 230 | // configure the remaining nested relations to the transformer. 231 | $transformer->with($nestedRelations[1]); 232 | } 233 | 234 | return $transformer->transform($related); 235 | } 236 | 237 | /** 238 | * @param $model 239 | * @return Transformer|null 240 | */ 241 | protected function resolveTransformer($model) 242 | { 243 | // if its a transformable model resolve its transformer. 244 | $className = get_class($model); 245 | 246 | // if its registered by the service provider. 247 | if (static::canMake($className)) { 248 | return static::make($className); 249 | } 250 | 251 | if ($model instanceof Transformable) { 252 | return $model->getTransformer(); 253 | } 254 | 255 | return null; 256 | } 257 | 258 | /** 259 | * Resets the transformer relations and the selected transformation method. 260 | * 261 | * @return $this 262 | */ 263 | public function reset() 264 | { 265 | return $this->resetRelations() 266 | ->resetTransformation(); 267 | } 268 | 269 | /** 270 | * Resets the relations. 271 | * 272 | * @return $this 273 | */ 274 | public function resetRelations() 275 | { 276 | $this->related = []; 277 | $this->relatedCount = 0; 278 | 279 | return $this; 280 | } 281 | 282 | /** 283 | * Resets the transformation method to the default one. 284 | * 285 | * @return $this 286 | */ 287 | public function resetTransformation() 288 | { 289 | $this->transformationMethod = null; 290 | 291 | return $this; 292 | } 293 | 294 | /** 295 | * Makes (resolves) a transformer for the given model class name. 296 | * 297 | * @param $modelName 298 | * @return App 299 | */ 300 | public static function make($modelName) 301 | { 302 | if (! static::isConfigPublished()) { 303 | return null; 304 | } 305 | 306 | $transformerName = Config::get('transformers.transformers')[$modelName]; 307 | 308 | return App::make($transformerName); 309 | } 310 | 311 | /** 312 | * Checks if the a transformer for specific model can be generated. 313 | * 314 | * @param $modelName 315 | * @return bool 316 | */ 317 | public static function canMake($modelName) 318 | { 319 | if (! static::isConfigPublished()) { 320 | return false; 321 | } 322 | 323 | return array_has(Config::get('transformers.transformers'), $modelName); 324 | } 325 | 326 | /** 327 | * Checks if the app has the transformers package configuration. 328 | * 329 | * @return mixed 330 | */ 331 | public static function isConfigPublished() 332 | { 333 | return Config::has('transformers.transformers'); 334 | } 335 | } 336 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Transformers 2 | [![Codacy Badge](https://api.codacy.com/project/badge/Grade/ddca1557a00545d48c62f1c5c616c984)](https://www.codacy.com/app/logaretm1/transformers?utm_source=github.com&utm_medium=referral&utm_content=logaretm/transformers&utm_campaign=Badge_Grade) 3 | [![Build Status](https://travis-ci.org/logaretm/transformers.svg?branch=master)](https://travis-ci.org/logaretm/transformers) 4 | 5 | This a package that provides transformer (reducer/serializer) classes and traits for the Laravel eloquent models. 6 | 7 | ## Install 8 | 9 | Via Composer 10 | 11 | ``` bash 12 | composer require logaretm/transformers 13 | ``` 14 | 15 | ##### Transformer: 16 | A class responsible for transforming or reducing an object from one form to another then consumed. 17 | 18 | ##### Why would you use them? 19 | 20 | Transformers are useful in API responses, where you want the ajax results to be in a specific form, by hiding attributes, exposing additional ones, or convert attribute types. 21 | 22 | Also by delegating the responsibility of transforming models to a separate class make it easier to handle and maintain down the line. 23 | 24 | ##### Inspiration 25 | 26 | Having seen[Jeffery Way's Laracasts video](https://laracasts.com/series/incremental-api-development/episodes/4) and reading the book [Building APIs You Won't Hate](https://apisyouwonthate.com/), I wanted to create a simple package specific to laravel apps and because I needed this functionality in almost every project. 27 | 28 | ## Usage 29 | 30 | First you need to a transformer for your model. the transformer should extend the Transformer abstract class. 31 | And provide an implementation for the ```getTransformation()``` method. 32 | 33 | ``` php 34 | class UserTransformer extends Transformer 35 | { 36 | /** 37 | * @param $user 38 | * @return mixed 39 | */ 40 | public function getTransformation($user) 41 | { 42 | return [ 43 | 'name' => $user->name, 44 | 'email' => $user->email, 45 | 'memberSince' => $user->created_at->timestamp 46 | ]; 47 | } 48 | } 49 | ``` 50 | 51 | Now you can use the transformer in multiple ways, inject it in your controller method and laravel IoC should instantiate it. 52 | 53 | ```php 54 | class UsersController extends Controller 55 | { 56 | public function index(UserTransformer $transformer) 57 | { 58 | $users = User::get(); 59 | 60 | return response()->json([ 61 | 'users' => [ 62 | 'data' => $transformer->transform($users) 63 | ] 64 | ]); 65 | } 66 | } 67 | ``` 68 | 69 | You can also instantiate it manually if you don't think DI is your thing. 70 | ```php 71 | $transformer = new UserTransformer; 72 | ``` 73 | 74 | #### Dynamic Transformation 75 | 76 | You can also use the `TransformableTrait` on your model and define a `$transformer` property to be able to use the `getTransformer()` method. 77 | 78 | ```php 79 | class User extends Model implements Transform 80 | { 81 | use TransformableTrait; 82 | 83 | /** 84 | * Defines the appropiate transformer for this model. 85 | * 86 | * @var 87 | */ 88 | protected $transformer = UserTransformer::class; 89 | } 90 | ``` 91 | 92 | then you can get the transformer instance using: 93 | 94 | ```php 95 | $user = User::first(); 96 | $transformer = $user->getTransformer(); // returns instance of UserTransformer. 97 | ``` 98 | 99 | which can be helpful if you want to dynamically transform models. but note that it will throw a `TransformerException` if the returned instance isn't an instance of `Transformer`. 100 | 101 | #### Service Provider 102 | 103 | You may find retrieving the transformer over and over isn't intuitive, you can use the `TransformerServiceProvider` and a config file to define an array mapping each model or any class to a transformer class. 104 | 105 | * Add this line to `config/app.php` in the service providers array. 106 | 107 | `Logaretm\Transformers\Providers\TransformerServiceProvider::class` 108 | 109 | * Run this artisan command: 110 | 111 | `php artisan vendor:publish --provider="Logaretm\Transformers\Providers\TransformerServiceProvider" --tags="config"` 112 | 113 | * Head over to config/transformers.php and populate the array with your model/transformer pairs. 114 | 115 | ```php 116 | 'transformers' => [ 117 | User::class => UserTransformerClass 118 | ] 119 | ``` 120 | 121 | * Now you don't need to provide the `$transformer` property anymore on your model, nor implement the interface. 122 | 123 | Note that the transformer resolution for the related model will prioritize the registered transformers. 124 | 125 | Furthermore you can now use the static methods `Transformer::make` and `Transformer::canMake` to instantiate transformers for the models, using the trait is still helpful, but not required anymore. 126 | 127 | ```php 128 | if(Transformer::canMake(User::class); // returns true if the transformer is registered. 129 | $transformer = Transformer::make(User::class); // creates a transformer for the model. 130 | ``` 131 | #### Relations 132 | 133 | It is also possible to transform a model along with their related models using the fluent method ```with()```. 134 | 135 | The related model transformer is resolved when: 136 | 137 | * If the service provider is registered, then it will be resolved from the config array. 138 | 139 | * If the model implements the `Transformable` contract which is automated by the `TransformableTrait`. it also needs to define the `$transformer` property. 140 | 141 | otherwise the model will be transformed using a simple `toArray()` call. 142 | 143 | ```php 144 | $transformer = new UserTransformer(); 145 | $users = User::with('posts')->get(); 146 | $data = $transformer->with('posts')->transform($users); 147 | ``` 148 | 149 | you can also transform nested relations with the same syntax. 150 | 151 | ```php 152 | $transformer = new UserTransformer(); 153 | $users = User::with('posts.tags')->get(); 154 | $data = $transformer->with('posts.tags')->transform($users); 155 | ``` 156 | 157 | you can reset the transformer relations using `$transformer->resetRelations()` which will remove the related models from the transformation. also note that any call to `with` will reset the transformer automatically. 158 | 159 | aside from collections you can transform a paginator, or a single object. 160 | 161 | ```php 162 | $users = User::get(); 163 | $transformer->transform($users); // returns an array of arrays. 164 | 165 | $paginator = User::paginate(15); 166 | $transformer->transform($paginator); // returns an array(15). 167 | 168 | $user = User::first(); 169 | $transformedUser = $transformer->transform($user); // returns a single array. 170 | ``` 171 | 172 | #### Alternate Transformations 173 | 174 | You don't have to use only one transformation per transformer, for example you may need specific transformations for specific scenarios for the same model. 175 | 176 | using the method `setTransformation` you can override the transformation method to use another one you have defined on the transformer. 177 | 178 | ```php 179 | class UserTransformer extends Transformer 180 | { 181 | /** 182 | * @param $user 183 | * @return mixed 184 | */ 185 | public function getTransformation($user) 186 | { 187 | return [ 188 | 'name' => $user->name, 189 | 'email' => $user->email, 190 | 'memberSince' => $user->created_at->timestamp 191 | ]; 192 | } 193 | 194 | // Custom/Alternate transformation. 195 | public function adminTransformation($user) 196 | { 197 | return [ 198 | 'name' => $user->name, 199 | 'email' => $user->email, 200 | 'memberSince' => $user->created_at->timestamp, 201 | 'isAdmin' => $user->isAdmin() 202 | ]; 203 | } 204 | } 205 | ``` 206 | 207 | To use the alternate transformation: 208 | 209 | ```php 210 | $transformer->setTransformation('admin'); 211 | ``` 212 | 213 | or you can pass a closure as an alternate transformation method. 214 | ```php 215 | $transformer->setTransformation(function ($user) { 216 | return [ 217 | 'name' => $user->name, 218 | 'email' => $user->email, 219 | 'memberSince' => $user->created_at->timestamp, 220 | 'isAdmin' => $user->isAdmin() 221 | ]; 222 | }); 223 | ``` 224 | 225 | Note that the naming convention for the transformation method is `{transformation_name}Transformation`. 226 | 227 | any subsequent calls to `transform` method will use that transformation instead. 228 | 229 | Note that it will throw a TransformerException if the requested transformation does not exist. 230 | 231 | to reset the transformation method use the `resetTransformation` method. 232 | 233 | ```php 234 | $transformer->resetTransformation(); //resets the transformation method. 235 | ``` 236 | 237 | or if you want to reset both relations and transformation method: 238 | 239 | ```php 240 | $transformer->reset(); //resets the transformation method and the relations. 241 | ``` 242 | 243 | #### Generating Transformers 244 | You can easily generate a transformer class using this artisan command: 245 | ```bash 246 | php artisan make:transformer {transformer name} 247 | ``` 248 | 249 | which will create a basic transformer class in `app/Transformers` directory, don't forget to put your transformations there. 250 | 251 | ## Testing 252 | 253 | Use php unit for testing. 254 | ``` bash 255 | phpunit 256 | ``` 257 | 258 | ## TODO 259 | 260 | * Improve the API and method names. 261 | * ~~Maybe a console command to generate a transformer for a model.~~ 262 | * ~~Use closures to override transformation.~~ 263 | * Write more todos. 264 | 265 | ## Contributing 266 | 267 | All contributes will be fully credited. 268 | 269 | ## Issues 270 | 271 | If you discover any issues, email me at logaretm1@gmail.com or use the issue tracker. 272 | 273 | ## Credits 274 | 275 | - [Abdelrahman Awad](https://github.com/logaretm) 276 | 277 | ## License 278 | 279 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information. 280 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", 5 | "This file is @generated automatically" 6 | ], 7 | "hash": "8d15dab00b446cd57cddb4766b526668", 8 | "content-hash": "15b6121bf29fe22f71d49d3c8c52a531", 9 | "packages": [ 10 | { 11 | "name": "doctrine/inflector", 12 | "version": "v1.1.0", 13 | "source": { 14 | "type": "git", 15 | "url": "https://github.com/doctrine/inflector.git", 16 | "reference": "90b2128806bfde671b6952ab8bea493942c1fdae" 17 | }, 18 | "dist": { 19 | "type": "zip", 20 | "url": "https://api.github.com/repos/doctrine/inflector/zipball/90b2128806bfde671b6952ab8bea493942c1fdae", 21 | "reference": "90b2128806bfde671b6952ab8bea493942c1fdae", 22 | "shasum": "" 23 | }, 24 | "require": { 25 | "php": ">=5.3.2" 26 | }, 27 | "require-dev": { 28 | "phpunit/phpunit": "4.*" 29 | }, 30 | "type": "library", 31 | "extra": { 32 | "branch-alias": { 33 | "dev-master": "1.1.x-dev" 34 | } 35 | }, 36 | "autoload": { 37 | "psr-0": { 38 | "Doctrine\\Common\\Inflector\\": "lib/" 39 | } 40 | }, 41 | "notification-url": "https://packagist.org/downloads/", 42 | "license": [ 43 | "MIT" 44 | ], 45 | "authors": [ 46 | { 47 | "name": "Roman Borschel", 48 | "email": "roman@code-factory.org" 49 | }, 50 | { 51 | "name": "Benjamin Eberlei", 52 | "email": "kontakt@beberlei.de" 53 | }, 54 | { 55 | "name": "Guilherme Blanco", 56 | "email": "guilhermeblanco@gmail.com" 57 | }, 58 | { 59 | "name": "Jonathan Wage", 60 | "email": "jonwage@gmail.com" 61 | }, 62 | { 63 | "name": "Johannes Schmitt", 64 | "email": "schmittjoh@gmail.com" 65 | } 66 | ], 67 | "description": "Common String Manipulations with regard to casing and singular/plural rules.", 68 | "homepage": "http://www.doctrine-project.org", 69 | "keywords": [ 70 | "inflection", 71 | "pluralize", 72 | "singularize", 73 | "string" 74 | ], 75 | "time": "2015-11-06 14:35:42" 76 | }, 77 | { 78 | "name": "illuminate/console", 79 | "version": "v5.2.32", 80 | "source": { 81 | "type": "git", 82 | "url": "https://github.com/illuminate/console.git", 83 | "reference": "6fe633078a4ae1915f391d87e5c95092fbadf2b0" 84 | }, 85 | "dist": { 86 | "type": "zip", 87 | "url": "https://api.github.com/repos/illuminate/console/zipball/6fe633078a4ae1915f391d87e5c95092fbadf2b0", 88 | "reference": "6fe633078a4ae1915f391d87e5c95092fbadf2b0", 89 | "shasum": "" 90 | }, 91 | "require": { 92 | "illuminate/contracts": "5.2.*", 93 | "illuminate/support": "5.2.*", 94 | "nesbot/carbon": "~1.20", 95 | "php": ">=5.5.9", 96 | "symfony/console": "2.8.*|3.0.*" 97 | }, 98 | "suggest": { 99 | "guzzlehttp/guzzle": "Required to use the ping methods on schedules (~5.3|~6.0).", 100 | "mtdowling/cron-expression": "Required to use scheduling component (~1.0).", 101 | "symfony/process": "Required to use scheduling component (2.8.*|3.0.*)." 102 | }, 103 | "type": "library", 104 | "extra": { 105 | "branch-alias": { 106 | "dev-master": "5.2-dev" 107 | } 108 | }, 109 | "autoload": { 110 | "psr-4": { 111 | "Illuminate\\Console\\": "" 112 | } 113 | }, 114 | "notification-url": "https://packagist.org/downloads/", 115 | "license": [ 116 | "MIT" 117 | ], 118 | "authors": [ 119 | { 120 | "name": "Taylor Otwell", 121 | "email": "taylorotwell@gmail.com" 122 | } 123 | ], 124 | "description": "The Illuminate Console package.", 125 | "homepage": "http://laravel.com", 126 | "time": "2016-05-16 13:24:33" 127 | }, 128 | { 129 | "name": "illuminate/contracts", 130 | "version": "v5.2.32", 131 | "source": { 132 | "type": "git", 133 | "url": "https://github.com/illuminate/contracts.git", 134 | "reference": "411b851962c211078ade7664a6976e77a78cd2a5" 135 | }, 136 | "dist": { 137 | "type": "zip", 138 | "url": "https://api.github.com/repos/illuminate/contracts/zipball/411b851962c211078ade7664a6976e77a78cd2a5", 139 | "reference": "411b851962c211078ade7664a6976e77a78cd2a5", 140 | "shasum": "" 141 | }, 142 | "require": { 143 | "php": ">=5.5.9" 144 | }, 145 | "type": "library", 146 | "extra": { 147 | "branch-alias": { 148 | "dev-master": "5.2-dev" 149 | } 150 | }, 151 | "autoload": { 152 | "psr-4": { 153 | "Illuminate\\Contracts\\": "" 154 | } 155 | }, 156 | "notification-url": "https://packagist.org/downloads/", 157 | "license": [ 158 | "MIT" 159 | ], 160 | "authors": [ 161 | { 162 | "name": "Taylor Otwell", 163 | "email": "taylorotwell@gmail.com" 164 | } 165 | ], 166 | "description": "The Illuminate Contracts package.", 167 | "homepage": "http://laravel.com", 168 | "time": "2016-03-07 20:37:17" 169 | }, 170 | { 171 | "name": "illuminate/support", 172 | "version": "v5.2.32", 173 | "source": { 174 | "type": "git", 175 | "url": "https://github.com/illuminate/support.git", 176 | "reference": "61329ea409362fdae167fdca1125f46c997ce689" 177 | }, 178 | "dist": { 179 | "type": "zip", 180 | "url": "https://api.github.com/repos/illuminate/support/zipball/61329ea409362fdae167fdca1125f46c997ce689", 181 | "reference": "61329ea409362fdae167fdca1125f46c997ce689", 182 | "shasum": "" 183 | }, 184 | "require": { 185 | "doctrine/inflector": "~1.0", 186 | "ext-mbstring": "*", 187 | "illuminate/contracts": "5.2.*", 188 | "paragonie/random_compat": "~1.4", 189 | "php": ">=5.5.9" 190 | }, 191 | "suggest": { 192 | "illuminate/filesystem": "Required to use the composer class (5.2.*).", 193 | "jeremeamia/superclosure": "Required to be able to serialize closures (~2.2).", 194 | "symfony/polyfill-php56": "Required to use the hash_equals function on PHP 5.5 (~1.0).", 195 | "symfony/process": "Required to use the composer class (2.8.*|3.0.*).", 196 | "symfony/var-dumper": "Improves the dd function (2.8.*|3.0.*)." 197 | }, 198 | "type": "library", 199 | "extra": { 200 | "branch-alias": { 201 | "dev-master": "5.2-dev" 202 | } 203 | }, 204 | "autoload": { 205 | "psr-4": { 206 | "Illuminate\\Support\\": "" 207 | }, 208 | "files": [ 209 | "helpers.php" 210 | ] 211 | }, 212 | "notification-url": "https://packagist.org/downloads/", 213 | "license": [ 214 | "MIT" 215 | ], 216 | "authors": [ 217 | { 218 | "name": "Taylor Otwell", 219 | "email": "taylorotwell@gmail.com" 220 | } 221 | ], 222 | "description": "The Illuminate Support package.", 223 | "homepage": "http://laravel.com", 224 | "time": "2016-05-14 16:24:10" 225 | }, 226 | { 227 | "name": "nesbot/carbon", 228 | "version": "1.21.0", 229 | "source": { 230 | "type": "git", 231 | "url": "https://github.com/briannesbitt/Carbon.git", 232 | "reference": "7b08ec6f75791e130012f206e3f7b0e76e18e3d7" 233 | }, 234 | "dist": { 235 | "type": "zip", 236 | "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/7b08ec6f75791e130012f206e3f7b0e76e18e3d7", 237 | "reference": "7b08ec6f75791e130012f206e3f7b0e76e18e3d7", 238 | "shasum": "" 239 | }, 240 | "require": { 241 | "php": ">=5.3.0", 242 | "symfony/translation": "~2.6|~3.0" 243 | }, 244 | "require-dev": { 245 | "phpunit/phpunit": "~4.0|~5.0" 246 | }, 247 | "type": "library", 248 | "autoload": { 249 | "psr-4": { 250 | "Carbon\\": "src/Carbon/" 251 | } 252 | }, 253 | "notification-url": "https://packagist.org/downloads/", 254 | "license": [ 255 | "MIT" 256 | ], 257 | "authors": [ 258 | { 259 | "name": "Brian Nesbitt", 260 | "email": "brian@nesbot.com", 261 | "homepage": "http://nesbot.com" 262 | } 263 | ], 264 | "description": "A simple API extension for DateTime.", 265 | "homepage": "http://carbon.nesbot.com", 266 | "keywords": [ 267 | "date", 268 | "datetime", 269 | "time" 270 | ], 271 | "time": "2015-11-04 20:07:17" 272 | }, 273 | { 274 | "name": "paragonie/random_compat", 275 | "version": "v1.4.1", 276 | "source": { 277 | "type": "git", 278 | "url": "https://github.com/paragonie/random_compat.git", 279 | "reference": "c7e26a21ba357863de030f0b9e701c7d04593774" 280 | }, 281 | "dist": { 282 | "type": "zip", 283 | "url": "https://api.github.com/repos/paragonie/random_compat/zipball/c7e26a21ba357863de030f0b9e701c7d04593774", 284 | "reference": "c7e26a21ba357863de030f0b9e701c7d04593774", 285 | "shasum": "" 286 | }, 287 | "require": { 288 | "php": ">=5.2.0" 289 | }, 290 | "require-dev": { 291 | "phpunit/phpunit": "4.*|5.*" 292 | }, 293 | "suggest": { 294 | "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." 295 | }, 296 | "type": "library", 297 | "autoload": { 298 | "files": [ 299 | "lib/random.php" 300 | ] 301 | }, 302 | "notification-url": "https://packagist.org/downloads/", 303 | "license": [ 304 | "MIT" 305 | ], 306 | "authors": [ 307 | { 308 | "name": "Paragon Initiative Enterprises", 309 | "email": "security@paragonie.com", 310 | "homepage": "https://paragonie.com" 311 | } 312 | ], 313 | "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", 314 | "keywords": [ 315 | "csprng", 316 | "pseudorandom", 317 | "random" 318 | ], 319 | "time": "2016-03-18 20:34:03" 320 | }, 321 | { 322 | "name": "symfony/console", 323 | "version": "v3.0.7", 324 | "source": { 325 | "type": "git", 326 | "url": "https://github.com/symfony/console.git", 327 | "reference": "382fc9ed852edabd6133e34f8549d7a7d99db115" 328 | }, 329 | "dist": { 330 | "type": "zip", 331 | "url": "https://api.github.com/repos/symfony/console/zipball/382fc9ed852edabd6133e34f8549d7a7d99db115", 332 | "reference": "382fc9ed852edabd6133e34f8549d7a7d99db115", 333 | "shasum": "" 334 | }, 335 | "require": { 336 | "php": ">=5.5.9", 337 | "symfony/polyfill-mbstring": "~1.0" 338 | }, 339 | "require-dev": { 340 | "psr/log": "~1.0", 341 | "symfony/event-dispatcher": "~2.8|~3.0", 342 | "symfony/process": "~2.8|~3.0" 343 | }, 344 | "suggest": { 345 | "psr/log": "For using the console logger", 346 | "symfony/event-dispatcher": "", 347 | "symfony/process": "" 348 | }, 349 | "type": "library", 350 | "extra": { 351 | "branch-alias": { 352 | "dev-master": "3.0-dev" 353 | } 354 | }, 355 | "autoload": { 356 | "psr-4": { 357 | "Symfony\\Component\\Console\\": "" 358 | }, 359 | "exclude-from-classmap": [ 360 | "/Tests/" 361 | ] 362 | }, 363 | "notification-url": "https://packagist.org/downloads/", 364 | "license": [ 365 | "MIT" 366 | ], 367 | "authors": [ 368 | { 369 | "name": "Fabien Potencier", 370 | "email": "fabien@symfony.com" 371 | }, 372 | { 373 | "name": "Symfony Community", 374 | "homepage": "https://symfony.com/contributors" 375 | } 376 | ], 377 | "description": "Symfony Console Component", 378 | "homepage": "https://symfony.com", 379 | "time": "2016-06-06 15:08:35" 380 | }, 381 | { 382 | "name": "symfony/polyfill-mbstring", 383 | "version": "v1.2.0", 384 | "source": { 385 | "type": "git", 386 | "url": "https://github.com/symfony/polyfill-mbstring.git", 387 | "reference": "dff51f72b0706335131b00a7f49606168c582594" 388 | }, 389 | "dist": { 390 | "type": "zip", 391 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/dff51f72b0706335131b00a7f49606168c582594", 392 | "reference": "dff51f72b0706335131b00a7f49606168c582594", 393 | "shasum": "" 394 | }, 395 | "require": { 396 | "php": ">=5.3.3" 397 | }, 398 | "suggest": { 399 | "ext-mbstring": "For best performance" 400 | }, 401 | "type": "library", 402 | "extra": { 403 | "branch-alias": { 404 | "dev-master": "1.2-dev" 405 | } 406 | }, 407 | "autoload": { 408 | "psr-4": { 409 | "Symfony\\Polyfill\\Mbstring\\": "" 410 | }, 411 | "files": [ 412 | "bootstrap.php" 413 | ] 414 | }, 415 | "notification-url": "https://packagist.org/downloads/", 416 | "license": [ 417 | "MIT" 418 | ], 419 | "authors": [ 420 | { 421 | "name": "Nicolas Grekas", 422 | "email": "p@tchwork.com" 423 | }, 424 | { 425 | "name": "Symfony Community", 426 | "homepage": "https://symfony.com/contributors" 427 | } 428 | ], 429 | "description": "Symfony polyfill for the Mbstring extension", 430 | "homepage": "https://symfony.com", 431 | "keywords": [ 432 | "compatibility", 433 | "mbstring", 434 | "polyfill", 435 | "portable", 436 | "shim" 437 | ], 438 | "time": "2016-05-18 14:26:46" 439 | }, 440 | { 441 | "name": "symfony/translation", 442 | "version": "v3.1.0", 443 | "source": { 444 | "type": "git", 445 | "url": "https://github.com/symfony/translation.git", 446 | "reference": "0e67031c9ef0ad681932d2b24f4fd0ec8a6679ff" 447 | }, 448 | "dist": { 449 | "type": "zip", 450 | "url": "https://api.github.com/repos/symfony/translation/zipball/0e67031c9ef0ad681932d2b24f4fd0ec8a6679ff", 451 | "reference": "0e67031c9ef0ad681932d2b24f4fd0ec8a6679ff", 452 | "shasum": "" 453 | }, 454 | "require": { 455 | "php": ">=5.5.9", 456 | "symfony/polyfill-mbstring": "~1.0" 457 | }, 458 | "conflict": { 459 | "symfony/config": "<2.8" 460 | }, 461 | "require-dev": { 462 | "psr/log": "~1.0", 463 | "symfony/config": "~2.8|~3.0", 464 | "symfony/intl": "~2.8|~3.0", 465 | "symfony/yaml": "~2.8|~3.0" 466 | }, 467 | "suggest": { 468 | "psr/log": "To use logging capability in translator", 469 | "symfony/config": "", 470 | "symfony/yaml": "" 471 | }, 472 | "type": "library", 473 | "extra": { 474 | "branch-alias": { 475 | "dev-master": "3.1-dev" 476 | } 477 | }, 478 | "autoload": { 479 | "psr-4": { 480 | "Symfony\\Component\\Translation\\": "" 481 | }, 482 | "exclude-from-classmap": [ 483 | "/Tests/" 484 | ] 485 | }, 486 | "notification-url": "https://packagist.org/downloads/", 487 | "license": [ 488 | "MIT" 489 | ], 490 | "authors": [ 491 | { 492 | "name": "Fabien Potencier", 493 | "email": "fabien@symfony.com" 494 | }, 495 | { 496 | "name": "Symfony Community", 497 | "homepage": "https://symfony.com/contributors" 498 | } 499 | ], 500 | "description": "Symfony Translation Component", 501 | "homepage": "https://symfony.com", 502 | "time": "2016-05-12 18:19:29" 503 | } 504 | ], 505 | "packages-dev": [ 506 | { 507 | "name": "doctrine/instantiator", 508 | "version": "1.0.5", 509 | "source": { 510 | "type": "git", 511 | "url": "https://github.com/doctrine/instantiator.git", 512 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" 513 | }, 514 | "dist": { 515 | "type": "zip", 516 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", 517 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", 518 | "shasum": "" 519 | }, 520 | "require": { 521 | "php": ">=5.3,<8.0-DEV" 522 | }, 523 | "require-dev": { 524 | "athletic/athletic": "~0.1.8", 525 | "ext-pdo": "*", 526 | "ext-phar": "*", 527 | "phpunit/phpunit": "~4.0", 528 | "squizlabs/php_codesniffer": "~2.0" 529 | }, 530 | "type": "library", 531 | "extra": { 532 | "branch-alias": { 533 | "dev-master": "1.0.x-dev" 534 | } 535 | }, 536 | "autoload": { 537 | "psr-4": { 538 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" 539 | } 540 | }, 541 | "notification-url": "https://packagist.org/downloads/", 542 | "license": [ 543 | "MIT" 544 | ], 545 | "authors": [ 546 | { 547 | "name": "Marco Pivetta", 548 | "email": "ocramius@gmail.com", 549 | "homepage": "http://ocramius.github.com/" 550 | } 551 | ], 552 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", 553 | "homepage": "https://github.com/doctrine/instantiator", 554 | "keywords": [ 555 | "constructor", 556 | "instantiate" 557 | ], 558 | "time": "2015-06-14 21:17:01" 559 | }, 560 | { 561 | "name": "fzaninotto/faker", 562 | "version": "v1.6.0", 563 | "source": { 564 | "type": "git", 565 | "url": "https://github.com/fzaninotto/Faker.git", 566 | "reference": "44f9a286a04b80c76a4e5fb7aad8bb539b920123" 567 | }, 568 | "dist": { 569 | "type": "zip", 570 | "url": "https://api.github.com/repos/fzaninotto/Faker/zipball/44f9a286a04b80c76a4e5fb7aad8bb539b920123", 571 | "reference": "44f9a286a04b80c76a4e5fb7aad8bb539b920123", 572 | "shasum": "" 573 | }, 574 | "require": { 575 | "php": "^5.3.3|^7.0" 576 | }, 577 | "require-dev": { 578 | "ext-intl": "*", 579 | "phpunit/phpunit": "~4.0", 580 | "squizlabs/php_codesniffer": "~1.5" 581 | }, 582 | "type": "library", 583 | "extra": { 584 | "branch-alias": [] 585 | }, 586 | "autoload": { 587 | "psr-4": { 588 | "Faker\\": "src/Faker/" 589 | } 590 | }, 591 | "notification-url": "https://packagist.org/downloads/", 592 | "license": [ 593 | "MIT" 594 | ], 595 | "authors": [ 596 | { 597 | "name": "François Zaninotto" 598 | } 599 | ], 600 | "description": "Faker is a PHP library that generates fake data for you.", 601 | "keywords": [ 602 | "data", 603 | "faker", 604 | "fixtures" 605 | ], 606 | "time": "2016-04-29 12:21:54" 607 | }, 608 | { 609 | "name": "hamcrest/hamcrest-php", 610 | "version": "v1.2.2", 611 | "source": { 612 | "type": "git", 613 | "url": "https://github.com/hamcrest/hamcrest-php.git", 614 | "reference": "b37020aa976fa52d3de9aa904aa2522dc518f79c" 615 | }, 616 | "dist": { 617 | "type": "zip", 618 | "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/b37020aa976fa52d3de9aa904aa2522dc518f79c", 619 | "reference": "b37020aa976fa52d3de9aa904aa2522dc518f79c", 620 | "shasum": "" 621 | }, 622 | "require": { 623 | "php": ">=5.3.2" 624 | }, 625 | "replace": { 626 | "cordoval/hamcrest-php": "*", 627 | "davedevelopment/hamcrest-php": "*", 628 | "kodova/hamcrest-php": "*" 629 | }, 630 | "require-dev": { 631 | "phpunit/php-file-iterator": "1.3.3", 632 | "satooshi/php-coveralls": "dev-master" 633 | }, 634 | "type": "library", 635 | "autoload": { 636 | "classmap": [ 637 | "hamcrest" 638 | ], 639 | "files": [ 640 | "hamcrest/Hamcrest.php" 641 | ] 642 | }, 643 | "notification-url": "https://packagist.org/downloads/", 644 | "license": [ 645 | "BSD" 646 | ], 647 | "description": "This is the PHP port of Hamcrest Matchers", 648 | "keywords": [ 649 | "test" 650 | ], 651 | "time": "2015-05-11 14:41:42" 652 | }, 653 | { 654 | "name": "illuminate/container", 655 | "version": "v5.2.32", 656 | "source": { 657 | "type": "git", 658 | "url": "https://github.com/illuminate/container.git", 659 | "reference": "1e156f8017490f5583ab161030bf839c77c95e54" 660 | }, 661 | "dist": { 662 | "type": "zip", 663 | "url": "https://api.github.com/repos/illuminate/container/zipball/1e156f8017490f5583ab161030bf839c77c95e54", 664 | "reference": "1e156f8017490f5583ab161030bf839c77c95e54", 665 | "shasum": "" 666 | }, 667 | "require": { 668 | "illuminate/contracts": "5.2.*", 669 | "php": ">=5.5.9" 670 | }, 671 | "type": "library", 672 | "extra": { 673 | "branch-alias": { 674 | "dev-master": "5.2-dev" 675 | } 676 | }, 677 | "autoload": { 678 | "psr-4": { 679 | "Illuminate\\Container\\": "" 680 | } 681 | }, 682 | "notification-url": "https://packagist.org/downloads/", 683 | "license": [ 684 | "MIT" 685 | ], 686 | "authors": [ 687 | { 688 | "name": "Taylor Otwell", 689 | "email": "taylorotwell@gmail.com" 690 | } 691 | ], 692 | "description": "The Illuminate Container package.", 693 | "homepage": "http://laravel.com", 694 | "time": "2016-03-16 17:19:17" 695 | }, 696 | { 697 | "name": "illuminate/database", 698 | "version": "v5.2.32", 699 | "source": { 700 | "type": "git", 701 | "url": "https://github.com/illuminate/database.git", 702 | "reference": "5fbd370c687b5f428357982883eadf9fa33cf9a1" 703 | }, 704 | "dist": { 705 | "type": "zip", 706 | "url": "https://api.github.com/repos/illuminate/database/zipball/5fbd370c687b5f428357982883eadf9fa33cf9a1", 707 | "reference": "5fbd370c687b5f428357982883eadf9fa33cf9a1", 708 | "shasum": "" 709 | }, 710 | "require": { 711 | "illuminate/container": "5.2.*", 712 | "illuminate/contracts": "5.2.*", 713 | "illuminate/support": "5.2.*", 714 | "nesbot/carbon": "~1.20", 715 | "php": ">=5.5.9" 716 | }, 717 | "suggest": { 718 | "doctrine/dbal": "Required to rename columns and drop SQLite columns (~2.4).", 719 | "fzaninotto/faker": "Required to use the eloquent factory builder (~1.4).", 720 | "illuminate/console": "Required to use the database commands (5.2.*).", 721 | "illuminate/events": "Required to use the observers with Eloquent (5.2.*).", 722 | "illuminate/filesystem": "Required to use the migrations (5.2.*).", 723 | "illuminate/pagination": "Required to paginate the result set (5.2.*)." 724 | }, 725 | "type": "library", 726 | "extra": { 727 | "branch-alias": { 728 | "dev-master": "5.2-dev" 729 | } 730 | }, 731 | "autoload": { 732 | "psr-4": { 733 | "Illuminate\\Database\\": "" 734 | } 735 | }, 736 | "notification-url": "https://packagist.org/downloads/", 737 | "license": [ 738 | "MIT" 739 | ], 740 | "authors": [ 741 | { 742 | "name": "Taylor Otwell", 743 | "email": "taylorotwell@gmail.com" 744 | } 745 | ], 746 | "description": "The Illuminate Database package.", 747 | "homepage": "http://laravel.com", 748 | "keywords": [ 749 | "database", 750 | "laravel", 751 | "orm", 752 | "sql" 753 | ], 754 | "time": "2016-05-15 17:43:26" 755 | }, 756 | { 757 | "name": "illuminate/pagination", 758 | "version": "v5.2.32", 759 | "source": { 760 | "type": "git", 761 | "url": "https://github.com/illuminate/pagination.git", 762 | "reference": "4f98bbdc05a0ab11e29f33f9962062f0c1320ca5" 763 | }, 764 | "dist": { 765 | "type": "zip", 766 | "url": "https://api.github.com/repos/illuminate/pagination/zipball/4f98bbdc05a0ab11e29f33f9962062f0c1320ca5", 767 | "reference": "4f98bbdc05a0ab11e29f33f9962062f0c1320ca5", 768 | "shasum": "" 769 | }, 770 | "require": { 771 | "illuminate/contracts": "5.2.*", 772 | "illuminate/support": "5.2.*", 773 | "php": ">=5.5.9" 774 | }, 775 | "type": "library", 776 | "extra": { 777 | "branch-alias": { 778 | "dev-master": "5.2-dev" 779 | } 780 | }, 781 | "autoload": { 782 | "psr-4": { 783 | "Illuminate\\Pagination\\": "" 784 | } 785 | }, 786 | "notification-url": "https://packagist.org/downloads/", 787 | "license": [ 788 | "MIT" 789 | ], 790 | "authors": [ 791 | { 792 | "name": "Taylor Otwell", 793 | "email": "taylorotwell@gmail.com" 794 | } 795 | ], 796 | "description": "The Illuminate Pagination package.", 797 | "homepage": "http://laravel.com", 798 | "time": "2016-03-15 19:15:44" 799 | }, 800 | { 801 | "name": "mockery/mockery", 802 | "version": "0.9.4", 803 | "source": { 804 | "type": "git", 805 | "url": "https://github.com/padraic/mockery.git", 806 | "reference": "70bba85e4aabc9449626651f48b9018ede04f86b" 807 | }, 808 | "dist": { 809 | "type": "zip", 810 | "url": "https://api.github.com/repos/padraic/mockery/zipball/70bba85e4aabc9449626651f48b9018ede04f86b", 811 | "reference": "70bba85e4aabc9449626651f48b9018ede04f86b", 812 | "shasum": "" 813 | }, 814 | "require": { 815 | "hamcrest/hamcrest-php": "~1.1", 816 | "lib-pcre": ">=7.0", 817 | "php": ">=5.3.2" 818 | }, 819 | "require-dev": { 820 | "phpunit/phpunit": "~4.0" 821 | }, 822 | "type": "library", 823 | "extra": { 824 | "branch-alias": { 825 | "dev-master": "0.9.x-dev" 826 | } 827 | }, 828 | "autoload": { 829 | "psr-0": { 830 | "Mockery": "library/" 831 | } 832 | }, 833 | "notification-url": "https://packagist.org/downloads/", 834 | "license": [ 835 | "BSD-3-Clause" 836 | ], 837 | "authors": [ 838 | { 839 | "name": "Pádraic Brady", 840 | "email": "padraic.brady@gmail.com", 841 | "homepage": "http://blog.astrumfutura.com" 842 | }, 843 | { 844 | "name": "Dave Marshall", 845 | "email": "dave.marshall@atstsolutions.co.uk", 846 | "homepage": "http://davedevelopment.co.uk" 847 | } 848 | ], 849 | "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.", 850 | "homepage": "http://github.com/padraic/mockery", 851 | "keywords": [ 852 | "BDD", 853 | "TDD", 854 | "library", 855 | "mock", 856 | "mock objects", 857 | "mockery", 858 | "stub", 859 | "test", 860 | "test double", 861 | "testing" 862 | ], 863 | "time": "2015-04-02 19:54:00" 864 | }, 865 | { 866 | "name": "myclabs/deep-copy", 867 | "version": "1.5.0", 868 | "source": { 869 | "type": "git", 870 | "url": "https://github.com/myclabs/DeepCopy.git", 871 | "reference": "e3abefcd7f106677fd352cd7c187d6c969aa9ddc" 872 | }, 873 | "dist": { 874 | "type": "zip", 875 | "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/e3abefcd7f106677fd352cd7c187d6c969aa9ddc", 876 | "reference": "e3abefcd7f106677fd352cd7c187d6c969aa9ddc", 877 | "shasum": "" 878 | }, 879 | "require": { 880 | "php": ">=5.4.0" 881 | }, 882 | "require-dev": { 883 | "doctrine/collections": "1.*", 884 | "phpunit/phpunit": "~4.1" 885 | }, 886 | "type": "library", 887 | "autoload": { 888 | "psr-4": { 889 | "DeepCopy\\": "src/DeepCopy/" 890 | } 891 | }, 892 | "notification-url": "https://packagist.org/downloads/", 893 | "license": [ 894 | "MIT" 895 | ], 896 | "description": "Create deep copies (clones) of your objects", 897 | "homepage": "https://github.com/myclabs/DeepCopy", 898 | "keywords": [ 899 | "clone", 900 | "copy", 901 | "duplicate", 902 | "object", 903 | "object graph" 904 | ], 905 | "time": "2015-11-07 22:20:37" 906 | }, 907 | { 908 | "name": "phpdocumentor/reflection-docblock", 909 | "version": "2.0.4", 910 | "source": { 911 | "type": "git", 912 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", 913 | "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8" 914 | }, 915 | "dist": { 916 | "type": "zip", 917 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8", 918 | "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8", 919 | "shasum": "" 920 | }, 921 | "require": { 922 | "php": ">=5.3.3" 923 | }, 924 | "require-dev": { 925 | "phpunit/phpunit": "~4.0" 926 | }, 927 | "suggest": { 928 | "dflydev/markdown": "~1.0", 929 | "erusev/parsedown": "~1.0" 930 | }, 931 | "type": "library", 932 | "extra": { 933 | "branch-alias": { 934 | "dev-master": "2.0.x-dev" 935 | } 936 | }, 937 | "autoload": { 938 | "psr-0": { 939 | "phpDocumentor": [ 940 | "src/" 941 | ] 942 | } 943 | }, 944 | "notification-url": "https://packagist.org/downloads/", 945 | "license": [ 946 | "MIT" 947 | ], 948 | "authors": [ 949 | { 950 | "name": "Mike van Riel", 951 | "email": "mike.vanriel@naenius.com" 952 | } 953 | ], 954 | "time": "2015-02-03 12:10:50" 955 | }, 956 | { 957 | "name": "phpspec/prophecy", 958 | "version": "v1.6.1", 959 | "source": { 960 | "type": "git", 961 | "url": "https://github.com/phpspec/prophecy.git", 962 | "reference": "58a8137754bc24b25740d4281399a4a3596058e0" 963 | }, 964 | "dist": { 965 | "type": "zip", 966 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/58a8137754bc24b25740d4281399a4a3596058e0", 967 | "reference": "58a8137754bc24b25740d4281399a4a3596058e0", 968 | "shasum": "" 969 | }, 970 | "require": { 971 | "doctrine/instantiator": "^1.0.2", 972 | "php": "^5.3|^7.0", 973 | "phpdocumentor/reflection-docblock": "^2.0|^3.0.2", 974 | "sebastian/comparator": "^1.1", 975 | "sebastian/recursion-context": "^1.0" 976 | }, 977 | "require-dev": { 978 | "phpspec/phpspec": "^2.0" 979 | }, 980 | "type": "library", 981 | "extra": { 982 | "branch-alias": { 983 | "dev-master": "1.6.x-dev" 984 | } 985 | }, 986 | "autoload": { 987 | "psr-0": { 988 | "Prophecy\\": "src/" 989 | } 990 | }, 991 | "notification-url": "https://packagist.org/downloads/", 992 | "license": [ 993 | "MIT" 994 | ], 995 | "authors": [ 996 | { 997 | "name": "Konstantin Kudryashov", 998 | "email": "ever.zet@gmail.com", 999 | "homepage": "http://everzet.com" 1000 | }, 1001 | { 1002 | "name": "Marcello Duarte", 1003 | "email": "marcello.duarte@gmail.com" 1004 | } 1005 | ], 1006 | "description": "Highly opinionated mocking framework for PHP 5.3+", 1007 | "homepage": "https://github.com/phpspec/prophecy", 1008 | "keywords": [ 1009 | "Double", 1010 | "Dummy", 1011 | "fake", 1012 | "mock", 1013 | "spy", 1014 | "stub" 1015 | ], 1016 | "time": "2016-06-07 08:13:47" 1017 | }, 1018 | { 1019 | "name": "phpunit/php-code-coverage", 1020 | "version": "4.0.0", 1021 | "source": { 1022 | "type": "git", 1023 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git", 1024 | "reference": "900370c81280cc0d942ffbc5912d80464eaee7e9" 1025 | }, 1026 | "dist": { 1027 | "type": "zip", 1028 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/900370c81280cc0d942ffbc5912d80464eaee7e9", 1029 | "reference": "900370c81280cc0d942ffbc5912d80464eaee7e9", 1030 | "shasum": "" 1031 | }, 1032 | "require": { 1033 | "php": "^5.6 || ^7.0", 1034 | "phpunit/php-file-iterator": "~1.3", 1035 | "phpunit/php-text-template": "~1.2", 1036 | "phpunit/php-token-stream": "^1.4.2", 1037 | "sebastian/code-unit-reverse-lookup": "~1.0", 1038 | "sebastian/environment": "^1.3.2", 1039 | "sebastian/version": "~1.0|~2.0" 1040 | }, 1041 | "require-dev": { 1042 | "ext-xdebug": ">=2.1.4", 1043 | "phpunit/phpunit": "^5.4" 1044 | }, 1045 | "suggest": { 1046 | "ext-dom": "*", 1047 | "ext-xdebug": ">=2.4.0", 1048 | "ext-xmlwriter": "*" 1049 | }, 1050 | "type": "library", 1051 | "extra": { 1052 | "branch-alias": { 1053 | "dev-master": "4.0.x-dev" 1054 | } 1055 | }, 1056 | "autoload": { 1057 | "classmap": [ 1058 | "src/" 1059 | ] 1060 | }, 1061 | "notification-url": "https://packagist.org/downloads/", 1062 | "license": [ 1063 | "BSD-3-Clause" 1064 | ], 1065 | "authors": [ 1066 | { 1067 | "name": "Sebastian Bergmann", 1068 | "email": "sb@sebastian-bergmann.de", 1069 | "role": "lead" 1070 | } 1071 | ], 1072 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", 1073 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage", 1074 | "keywords": [ 1075 | "coverage", 1076 | "testing", 1077 | "xunit" 1078 | ], 1079 | "time": "2016-06-03 05:03:56" 1080 | }, 1081 | { 1082 | "name": "phpunit/php-file-iterator", 1083 | "version": "1.4.1", 1084 | "source": { 1085 | "type": "git", 1086 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git", 1087 | "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0" 1088 | }, 1089 | "dist": { 1090 | "type": "zip", 1091 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0", 1092 | "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0", 1093 | "shasum": "" 1094 | }, 1095 | "require": { 1096 | "php": ">=5.3.3" 1097 | }, 1098 | "type": "library", 1099 | "extra": { 1100 | "branch-alias": { 1101 | "dev-master": "1.4.x-dev" 1102 | } 1103 | }, 1104 | "autoload": { 1105 | "classmap": [ 1106 | "src/" 1107 | ] 1108 | }, 1109 | "notification-url": "https://packagist.org/downloads/", 1110 | "license": [ 1111 | "BSD-3-Clause" 1112 | ], 1113 | "authors": [ 1114 | { 1115 | "name": "Sebastian Bergmann", 1116 | "email": "sb@sebastian-bergmann.de", 1117 | "role": "lead" 1118 | } 1119 | ], 1120 | "description": "FilterIterator implementation that filters files based on a list of suffixes.", 1121 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", 1122 | "keywords": [ 1123 | "filesystem", 1124 | "iterator" 1125 | ], 1126 | "time": "2015-06-21 13:08:43" 1127 | }, 1128 | { 1129 | "name": "phpunit/php-text-template", 1130 | "version": "1.2.1", 1131 | "source": { 1132 | "type": "git", 1133 | "url": "https://github.com/sebastianbergmann/php-text-template.git", 1134 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" 1135 | }, 1136 | "dist": { 1137 | "type": "zip", 1138 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 1139 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 1140 | "shasum": "" 1141 | }, 1142 | "require": { 1143 | "php": ">=5.3.3" 1144 | }, 1145 | "type": "library", 1146 | "autoload": { 1147 | "classmap": [ 1148 | "src/" 1149 | ] 1150 | }, 1151 | "notification-url": "https://packagist.org/downloads/", 1152 | "license": [ 1153 | "BSD-3-Clause" 1154 | ], 1155 | "authors": [ 1156 | { 1157 | "name": "Sebastian Bergmann", 1158 | "email": "sebastian@phpunit.de", 1159 | "role": "lead" 1160 | } 1161 | ], 1162 | "description": "Simple template engine.", 1163 | "homepage": "https://github.com/sebastianbergmann/php-text-template/", 1164 | "keywords": [ 1165 | "template" 1166 | ], 1167 | "time": "2015-06-21 13:50:34" 1168 | }, 1169 | { 1170 | "name": "phpunit/php-timer", 1171 | "version": "1.0.8", 1172 | "source": { 1173 | "type": "git", 1174 | "url": "https://github.com/sebastianbergmann/php-timer.git", 1175 | "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260" 1176 | }, 1177 | "dist": { 1178 | "type": "zip", 1179 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260", 1180 | "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260", 1181 | "shasum": "" 1182 | }, 1183 | "require": { 1184 | "php": ">=5.3.3" 1185 | }, 1186 | "require-dev": { 1187 | "phpunit/phpunit": "~4|~5" 1188 | }, 1189 | "type": "library", 1190 | "autoload": { 1191 | "classmap": [ 1192 | "src/" 1193 | ] 1194 | }, 1195 | "notification-url": "https://packagist.org/downloads/", 1196 | "license": [ 1197 | "BSD-3-Clause" 1198 | ], 1199 | "authors": [ 1200 | { 1201 | "name": "Sebastian Bergmann", 1202 | "email": "sb@sebastian-bergmann.de", 1203 | "role": "lead" 1204 | } 1205 | ], 1206 | "description": "Utility class for timing", 1207 | "homepage": "https://github.com/sebastianbergmann/php-timer/", 1208 | "keywords": [ 1209 | "timer" 1210 | ], 1211 | "time": "2016-05-12 18:03:57" 1212 | }, 1213 | { 1214 | "name": "phpunit/php-token-stream", 1215 | "version": "1.4.8", 1216 | "source": { 1217 | "type": "git", 1218 | "url": "https://github.com/sebastianbergmann/php-token-stream.git", 1219 | "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da" 1220 | }, 1221 | "dist": { 1222 | "type": "zip", 1223 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", 1224 | "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", 1225 | "shasum": "" 1226 | }, 1227 | "require": { 1228 | "ext-tokenizer": "*", 1229 | "php": ">=5.3.3" 1230 | }, 1231 | "require-dev": { 1232 | "phpunit/phpunit": "~4.2" 1233 | }, 1234 | "type": "library", 1235 | "extra": { 1236 | "branch-alias": { 1237 | "dev-master": "1.4-dev" 1238 | } 1239 | }, 1240 | "autoload": { 1241 | "classmap": [ 1242 | "src/" 1243 | ] 1244 | }, 1245 | "notification-url": "https://packagist.org/downloads/", 1246 | "license": [ 1247 | "BSD-3-Clause" 1248 | ], 1249 | "authors": [ 1250 | { 1251 | "name": "Sebastian Bergmann", 1252 | "email": "sebastian@phpunit.de" 1253 | } 1254 | ], 1255 | "description": "Wrapper around PHP's tokenizer extension.", 1256 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/", 1257 | "keywords": [ 1258 | "tokenizer" 1259 | ], 1260 | "time": "2015-09-15 10:49:45" 1261 | }, 1262 | { 1263 | "name": "phpunit/phpunit", 1264 | "version": "5.4.4", 1265 | "source": { 1266 | "type": "git", 1267 | "url": "https://github.com/sebastianbergmann/phpunit.git", 1268 | "reference": "02d5b64aa0837a038a5a4faeeefa5ef44bdcb928" 1269 | }, 1270 | "dist": { 1271 | "type": "zip", 1272 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/02d5b64aa0837a038a5a4faeeefa5ef44bdcb928", 1273 | "reference": "02d5b64aa0837a038a5a4faeeefa5ef44bdcb928", 1274 | "shasum": "" 1275 | }, 1276 | "require": { 1277 | "ext-dom": "*", 1278 | "ext-json": "*", 1279 | "ext-pcre": "*", 1280 | "ext-reflection": "*", 1281 | "ext-spl": "*", 1282 | "myclabs/deep-copy": "~1.3", 1283 | "php": "^5.6 || ^7.0", 1284 | "phpspec/prophecy": "^1.3.1", 1285 | "phpunit/php-code-coverage": "^4.0", 1286 | "phpunit/php-file-iterator": "~1.4", 1287 | "phpunit/php-text-template": "~1.2", 1288 | "phpunit/php-timer": "^1.0.6", 1289 | "phpunit/phpunit-mock-objects": "^3.2", 1290 | "sebastian/comparator": "~1.1", 1291 | "sebastian/diff": "~1.2", 1292 | "sebastian/environment": "~1.3", 1293 | "sebastian/exporter": "~1.2", 1294 | "sebastian/global-state": "~1.0", 1295 | "sebastian/object-enumerator": "~1.0", 1296 | "sebastian/resource-operations": "~1.0", 1297 | "sebastian/version": "~1.0|~2.0", 1298 | "symfony/yaml": "~2.1|~3.0" 1299 | }, 1300 | "conflict": { 1301 | "phpdocumentor/reflection-docblock": "3.0.2" 1302 | }, 1303 | "suggest": { 1304 | "phpunit/php-invoker": "~1.1" 1305 | }, 1306 | "bin": [ 1307 | "phpunit" 1308 | ], 1309 | "type": "library", 1310 | "extra": { 1311 | "branch-alias": { 1312 | "dev-master": "5.4.x-dev" 1313 | } 1314 | }, 1315 | "autoload": { 1316 | "classmap": [ 1317 | "src/" 1318 | ] 1319 | }, 1320 | "notification-url": "https://packagist.org/downloads/", 1321 | "license": [ 1322 | "BSD-3-Clause" 1323 | ], 1324 | "authors": [ 1325 | { 1326 | "name": "Sebastian Bergmann", 1327 | "email": "sebastian@phpunit.de", 1328 | "role": "lead" 1329 | } 1330 | ], 1331 | "description": "The PHP Unit Testing framework.", 1332 | "homepage": "https://phpunit.de/", 1333 | "keywords": [ 1334 | "phpunit", 1335 | "testing", 1336 | "xunit" 1337 | ], 1338 | "time": "2016-06-09 09:09:27" 1339 | }, 1340 | { 1341 | "name": "phpunit/phpunit-mock-objects", 1342 | "version": "3.2.1", 1343 | "source": { 1344 | "type": "git", 1345 | "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", 1346 | "reference": "0dc8fd8e87e0366c22b6c25d1f43c4e2e66847b3" 1347 | }, 1348 | "dist": { 1349 | "type": "zip", 1350 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/0dc8fd8e87e0366c22b6c25d1f43c4e2e66847b3", 1351 | "reference": "0dc8fd8e87e0366c22b6c25d1f43c4e2e66847b3", 1352 | "shasum": "" 1353 | }, 1354 | "require": { 1355 | "doctrine/instantiator": "^1.0.2", 1356 | "php": "^5.6 || ^7.0", 1357 | "phpunit/php-text-template": "^1.2", 1358 | "sebastian/exporter": "^1.2" 1359 | }, 1360 | "conflict": { 1361 | "phpunit/phpunit": "<5.4.0" 1362 | }, 1363 | "require-dev": { 1364 | "phpunit/phpunit": "^5.4" 1365 | }, 1366 | "suggest": { 1367 | "ext-soap": "*" 1368 | }, 1369 | "type": "library", 1370 | "extra": { 1371 | "branch-alias": { 1372 | "dev-master": "3.2.x-dev" 1373 | } 1374 | }, 1375 | "autoload": { 1376 | "classmap": [ 1377 | "src/" 1378 | ] 1379 | }, 1380 | "notification-url": "https://packagist.org/downloads/", 1381 | "license": [ 1382 | "BSD-3-Clause" 1383 | ], 1384 | "authors": [ 1385 | { 1386 | "name": "Sebastian Bergmann", 1387 | "email": "sb@sebastian-bergmann.de", 1388 | "role": "lead" 1389 | } 1390 | ], 1391 | "description": "Mock Object library for PHPUnit", 1392 | "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", 1393 | "keywords": [ 1394 | "mock", 1395 | "xunit" 1396 | ], 1397 | "time": "2016-06-04 05:52:19" 1398 | }, 1399 | { 1400 | "name": "sebastian/code-unit-reverse-lookup", 1401 | "version": "1.0.0", 1402 | "source": { 1403 | "type": "git", 1404 | "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", 1405 | "reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe" 1406 | }, 1407 | "dist": { 1408 | "type": "zip", 1409 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/c36f5e7cfce482fde5bf8d10d41a53591e0198fe", 1410 | "reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe", 1411 | "shasum": "" 1412 | }, 1413 | "require": { 1414 | "php": ">=5.6" 1415 | }, 1416 | "require-dev": { 1417 | "phpunit/phpunit": "~5" 1418 | }, 1419 | "type": "library", 1420 | "extra": { 1421 | "branch-alias": { 1422 | "dev-master": "1.0.x-dev" 1423 | } 1424 | }, 1425 | "autoload": { 1426 | "classmap": [ 1427 | "src/" 1428 | ] 1429 | }, 1430 | "notification-url": "https://packagist.org/downloads/", 1431 | "license": [ 1432 | "BSD-3-Clause" 1433 | ], 1434 | "authors": [ 1435 | { 1436 | "name": "Sebastian Bergmann", 1437 | "email": "sebastian@phpunit.de" 1438 | } 1439 | ], 1440 | "description": "Looks up which function or method a line of code belongs to", 1441 | "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", 1442 | "time": "2016-02-13 06:45:14" 1443 | }, 1444 | { 1445 | "name": "sebastian/comparator", 1446 | "version": "1.2.0", 1447 | "source": { 1448 | "type": "git", 1449 | "url": "https://github.com/sebastianbergmann/comparator.git", 1450 | "reference": "937efb279bd37a375bcadf584dec0726f84dbf22" 1451 | }, 1452 | "dist": { 1453 | "type": "zip", 1454 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22", 1455 | "reference": "937efb279bd37a375bcadf584dec0726f84dbf22", 1456 | "shasum": "" 1457 | }, 1458 | "require": { 1459 | "php": ">=5.3.3", 1460 | "sebastian/diff": "~1.2", 1461 | "sebastian/exporter": "~1.2" 1462 | }, 1463 | "require-dev": { 1464 | "phpunit/phpunit": "~4.4" 1465 | }, 1466 | "type": "library", 1467 | "extra": { 1468 | "branch-alias": { 1469 | "dev-master": "1.2.x-dev" 1470 | } 1471 | }, 1472 | "autoload": { 1473 | "classmap": [ 1474 | "src/" 1475 | ] 1476 | }, 1477 | "notification-url": "https://packagist.org/downloads/", 1478 | "license": [ 1479 | "BSD-3-Clause" 1480 | ], 1481 | "authors": [ 1482 | { 1483 | "name": "Jeff Welch", 1484 | "email": "whatthejeff@gmail.com" 1485 | }, 1486 | { 1487 | "name": "Volker Dusch", 1488 | "email": "github@wallbash.com" 1489 | }, 1490 | { 1491 | "name": "Bernhard Schussek", 1492 | "email": "bschussek@2bepublished.at" 1493 | }, 1494 | { 1495 | "name": "Sebastian Bergmann", 1496 | "email": "sebastian@phpunit.de" 1497 | } 1498 | ], 1499 | "description": "Provides the functionality to compare PHP values for equality", 1500 | "homepage": "http://www.github.com/sebastianbergmann/comparator", 1501 | "keywords": [ 1502 | "comparator", 1503 | "compare", 1504 | "equality" 1505 | ], 1506 | "time": "2015-07-26 15:48:44" 1507 | }, 1508 | { 1509 | "name": "sebastian/diff", 1510 | "version": "1.4.1", 1511 | "source": { 1512 | "type": "git", 1513 | "url": "https://github.com/sebastianbergmann/diff.git", 1514 | "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e" 1515 | }, 1516 | "dist": { 1517 | "type": "zip", 1518 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e", 1519 | "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e", 1520 | "shasum": "" 1521 | }, 1522 | "require": { 1523 | "php": ">=5.3.3" 1524 | }, 1525 | "require-dev": { 1526 | "phpunit/phpunit": "~4.8" 1527 | }, 1528 | "type": "library", 1529 | "extra": { 1530 | "branch-alias": { 1531 | "dev-master": "1.4-dev" 1532 | } 1533 | }, 1534 | "autoload": { 1535 | "classmap": [ 1536 | "src/" 1537 | ] 1538 | }, 1539 | "notification-url": "https://packagist.org/downloads/", 1540 | "license": [ 1541 | "BSD-3-Clause" 1542 | ], 1543 | "authors": [ 1544 | { 1545 | "name": "Kore Nordmann", 1546 | "email": "mail@kore-nordmann.de" 1547 | }, 1548 | { 1549 | "name": "Sebastian Bergmann", 1550 | "email": "sebastian@phpunit.de" 1551 | } 1552 | ], 1553 | "description": "Diff implementation", 1554 | "homepage": "https://github.com/sebastianbergmann/diff", 1555 | "keywords": [ 1556 | "diff" 1557 | ], 1558 | "time": "2015-12-08 07:14:41" 1559 | }, 1560 | { 1561 | "name": "sebastian/environment", 1562 | "version": "1.3.7", 1563 | "source": { 1564 | "type": "git", 1565 | "url": "https://github.com/sebastianbergmann/environment.git", 1566 | "reference": "4e8f0da10ac5802913afc151413bc8c53b6c2716" 1567 | }, 1568 | "dist": { 1569 | "type": "zip", 1570 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/4e8f0da10ac5802913afc151413bc8c53b6c2716", 1571 | "reference": "4e8f0da10ac5802913afc151413bc8c53b6c2716", 1572 | "shasum": "" 1573 | }, 1574 | "require": { 1575 | "php": ">=5.3.3" 1576 | }, 1577 | "require-dev": { 1578 | "phpunit/phpunit": "~4.4" 1579 | }, 1580 | "type": "library", 1581 | "extra": { 1582 | "branch-alias": { 1583 | "dev-master": "1.3.x-dev" 1584 | } 1585 | }, 1586 | "autoload": { 1587 | "classmap": [ 1588 | "src/" 1589 | ] 1590 | }, 1591 | "notification-url": "https://packagist.org/downloads/", 1592 | "license": [ 1593 | "BSD-3-Clause" 1594 | ], 1595 | "authors": [ 1596 | { 1597 | "name": "Sebastian Bergmann", 1598 | "email": "sebastian@phpunit.de" 1599 | } 1600 | ], 1601 | "description": "Provides functionality to handle HHVM/PHP environments", 1602 | "homepage": "http://www.github.com/sebastianbergmann/environment", 1603 | "keywords": [ 1604 | "Xdebug", 1605 | "environment", 1606 | "hhvm" 1607 | ], 1608 | "time": "2016-05-17 03:18:57" 1609 | }, 1610 | { 1611 | "name": "sebastian/exporter", 1612 | "version": "1.2.1", 1613 | "source": { 1614 | "type": "git", 1615 | "url": "https://github.com/sebastianbergmann/exporter.git", 1616 | "reference": "7ae5513327cb536431847bcc0c10edba2701064e" 1617 | }, 1618 | "dist": { 1619 | "type": "zip", 1620 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7ae5513327cb536431847bcc0c10edba2701064e", 1621 | "reference": "7ae5513327cb536431847bcc0c10edba2701064e", 1622 | "shasum": "" 1623 | }, 1624 | "require": { 1625 | "php": ">=5.3.3", 1626 | "sebastian/recursion-context": "~1.0" 1627 | }, 1628 | "require-dev": { 1629 | "phpunit/phpunit": "~4.4" 1630 | }, 1631 | "type": "library", 1632 | "extra": { 1633 | "branch-alias": { 1634 | "dev-master": "1.2.x-dev" 1635 | } 1636 | }, 1637 | "autoload": { 1638 | "classmap": [ 1639 | "src/" 1640 | ] 1641 | }, 1642 | "notification-url": "https://packagist.org/downloads/", 1643 | "license": [ 1644 | "BSD-3-Clause" 1645 | ], 1646 | "authors": [ 1647 | { 1648 | "name": "Jeff Welch", 1649 | "email": "whatthejeff@gmail.com" 1650 | }, 1651 | { 1652 | "name": "Volker Dusch", 1653 | "email": "github@wallbash.com" 1654 | }, 1655 | { 1656 | "name": "Bernhard Schussek", 1657 | "email": "bschussek@2bepublished.at" 1658 | }, 1659 | { 1660 | "name": "Sebastian Bergmann", 1661 | "email": "sebastian@phpunit.de" 1662 | }, 1663 | { 1664 | "name": "Adam Harvey", 1665 | "email": "aharvey@php.net" 1666 | } 1667 | ], 1668 | "description": "Provides the functionality to export PHP variables for visualization", 1669 | "homepage": "http://www.github.com/sebastianbergmann/exporter", 1670 | "keywords": [ 1671 | "export", 1672 | "exporter" 1673 | ], 1674 | "time": "2015-06-21 07:55:53" 1675 | }, 1676 | { 1677 | "name": "sebastian/global-state", 1678 | "version": "1.1.1", 1679 | "source": { 1680 | "type": "git", 1681 | "url": "https://github.com/sebastianbergmann/global-state.git", 1682 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" 1683 | }, 1684 | "dist": { 1685 | "type": "zip", 1686 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", 1687 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", 1688 | "shasum": "" 1689 | }, 1690 | "require": { 1691 | "php": ">=5.3.3" 1692 | }, 1693 | "require-dev": { 1694 | "phpunit/phpunit": "~4.2" 1695 | }, 1696 | "suggest": { 1697 | "ext-uopz": "*" 1698 | }, 1699 | "type": "library", 1700 | "extra": { 1701 | "branch-alias": { 1702 | "dev-master": "1.0-dev" 1703 | } 1704 | }, 1705 | "autoload": { 1706 | "classmap": [ 1707 | "src/" 1708 | ] 1709 | }, 1710 | "notification-url": "https://packagist.org/downloads/", 1711 | "license": [ 1712 | "BSD-3-Clause" 1713 | ], 1714 | "authors": [ 1715 | { 1716 | "name": "Sebastian Bergmann", 1717 | "email": "sebastian@phpunit.de" 1718 | } 1719 | ], 1720 | "description": "Snapshotting of global state", 1721 | "homepage": "http://www.github.com/sebastianbergmann/global-state", 1722 | "keywords": [ 1723 | "global state" 1724 | ], 1725 | "time": "2015-10-12 03:26:01" 1726 | }, 1727 | { 1728 | "name": "sebastian/object-enumerator", 1729 | "version": "1.0.0", 1730 | "source": { 1731 | "type": "git", 1732 | "url": "https://github.com/sebastianbergmann/object-enumerator.git", 1733 | "reference": "d4ca2fb70344987502567bc50081c03e6192fb26" 1734 | }, 1735 | "dist": { 1736 | "type": "zip", 1737 | "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/d4ca2fb70344987502567bc50081c03e6192fb26", 1738 | "reference": "d4ca2fb70344987502567bc50081c03e6192fb26", 1739 | "shasum": "" 1740 | }, 1741 | "require": { 1742 | "php": ">=5.6", 1743 | "sebastian/recursion-context": "~1.0" 1744 | }, 1745 | "require-dev": { 1746 | "phpunit/phpunit": "~5" 1747 | }, 1748 | "type": "library", 1749 | "extra": { 1750 | "branch-alias": { 1751 | "dev-master": "1.0.x-dev" 1752 | } 1753 | }, 1754 | "autoload": { 1755 | "classmap": [ 1756 | "src/" 1757 | ] 1758 | }, 1759 | "notification-url": "https://packagist.org/downloads/", 1760 | "license": [ 1761 | "BSD-3-Clause" 1762 | ], 1763 | "authors": [ 1764 | { 1765 | "name": "Sebastian Bergmann", 1766 | "email": "sebastian@phpunit.de" 1767 | } 1768 | ], 1769 | "description": "Traverses array structures and object graphs to enumerate all referenced objects", 1770 | "homepage": "https://github.com/sebastianbergmann/object-enumerator/", 1771 | "time": "2016-01-28 13:25:10" 1772 | }, 1773 | { 1774 | "name": "sebastian/recursion-context", 1775 | "version": "1.0.2", 1776 | "source": { 1777 | "type": "git", 1778 | "url": "https://github.com/sebastianbergmann/recursion-context.git", 1779 | "reference": "913401df809e99e4f47b27cdd781f4a258d58791" 1780 | }, 1781 | "dist": { 1782 | "type": "zip", 1783 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/913401df809e99e4f47b27cdd781f4a258d58791", 1784 | "reference": "913401df809e99e4f47b27cdd781f4a258d58791", 1785 | "shasum": "" 1786 | }, 1787 | "require": { 1788 | "php": ">=5.3.3" 1789 | }, 1790 | "require-dev": { 1791 | "phpunit/phpunit": "~4.4" 1792 | }, 1793 | "type": "library", 1794 | "extra": { 1795 | "branch-alias": { 1796 | "dev-master": "1.0.x-dev" 1797 | } 1798 | }, 1799 | "autoload": { 1800 | "classmap": [ 1801 | "src/" 1802 | ] 1803 | }, 1804 | "notification-url": "https://packagist.org/downloads/", 1805 | "license": [ 1806 | "BSD-3-Clause" 1807 | ], 1808 | "authors": [ 1809 | { 1810 | "name": "Jeff Welch", 1811 | "email": "whatthejeff@gmail.com" 1812 | }, 1813 | { 1814 | "name": "Sebastian Bergmann", 1815 | "email": "sebastian@phpunit.de" 1816 | }, 1817 | { 1818 | "name": "Adam Harvey", 1819 | "email": "aharvey@php.net" 1820 | } 1821 | ], 1822 | "description": "Provides functionality to recursively process PHP variables", 1823 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context", 1824 | "time": "2015-11-11 19:50:13" 1825 | }, 1826 | { 1827 | "name": "sebastian/resource-operations", 1828 | "version": "1.0.0", 1829 | "source": { 1830 | "type": "git", 1831 | "url": "https://github.com/sebastianbergmann/resource-operations.git", 1832 | "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" 1833 | }, 1834 | "dist": { 1835 | "type": "zip", 1836 | "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", 1837 | "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", 1838 | "shasum": "" 1839 | }, 1840 | "require": { 1841 | "php": ">=5.6.0" 1842 | }, 1843 | "type": "library", 1844 | "extra": { 1845 | "branch-alias": { 1846 | "dev-master": "1.0.x-dev" 1847 | } 1848 | }, 1849 | "autoload": { 1850 | "classmap": [ 1851 | "src/" 1852 | ] 1853 | }, 1854 | "notification-url": "https://packagist.org/downloads/", 1855 | "license": [ 1856 | "BSD-3-Clause" 1857 | ], 1858 | "authors": [ 1859 | { 1860 | "name": "Sebastian Bergmann", 1861 | "email": "sebastian@phpunit.de" 1862 | } 1863 | ], 1864 | "description": "Provides a list of PHP built-in functions that operate on resources", 1865 | "homepage": "https://www.github.com/sebastianbergmann/resource-operations", 1866 | "time": "2015-07-28 20:34:47" 1867 | }, 1868 | { 1869 | "name": "sebastian/version", 1870 | "version": "2.0.0", 1871 | "source": { 1872 | "type": "git", 1873 | "url": "https://github.com/sebastianbergmann/version.git", 1874 | "reference": "c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5" 1875 | }, 1876 | "dist": { 1877 | "type": "zip", 1878 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5", 1879 | "reference": "c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5", 1880 | "shasum": "" 1881 | }, 1882 | "require": { 1883 | "php": ">=5.6" 1884 | }, 1885 | "type": "library", 1886 | "extra": { 1887 | "branch-alias": { 1888 | "dev-master": "2.0.x-dev" 1889 | } 1890 | }, 1891 | "autoload": { 1892 | "classmap": [ 1893 | "src/" 1894 | ] 1895 | }, 1896 | "notification-url": "https://packagist.org/downloads/", 1897 | "license": [ 1898 | "BSD-3-Clause" 1899 | ], 1900 | "authors": [ 1901 | { 1902 | "name": "Sebastian Bergmann", 1903 | "email": "sebastian@phpunit.de", 1904 | "role": "lead" 1905 | } 1906 | ], 1907 | "description": "Library that helps with managing the version number of Git-hosted PHP projects", 1908 | "homepage": "https://github.com/sebastianbergmann/version", 1909 | "time": "2016-02-04 12:56:52" 1910 | }, 1911 | { 1912 | "name": "symfony/yaml", 1913 | "version": "v3.1.0", 1914 | "source": { 1915 | "type": "git", 1916 | "url": "https://github.com/symfony/yaml.git", 1917 | "reference": "eca51b7b65eb9be6af88ad7cc91685f1556f5c9a" 1918 | }, 1919 | "dist": { 1920 | "type": "zip", 1921 | "url": "https://api.github.com/repos/symfony/yaml/zipball/eca51b7b65eb9be6af88ad7cc91685f1556f5c9a", 1922 | "reference": "eca51b7b65eb9be6af88ad7cc91685f1556f5c9a", 1923 | "shasum": "" 1924 | }, 1925 | "require": { 1926 | "php": ">=5.5.9" 1927 | }, 1928 | "type": "library", 1929 | "extra": { 1930 | "branch-alias": { 1931 | "dev-master": "3.1-dev" 1932 | } 1933 | }, 1934 | "autoload": { 1935 | "psr-4": { 1936 | "Symfony\\Component\\Yaml\\": "" 1937 | }, 1938 | "exclude-from-classmap": [ 1939 | "/Tests/" 1940 | ] 1941 | }, 1942 | "notification-url": "https://packagist.org/downloads/", 1943 | "license": [ 1944 | "MIT" 1945 | ], 1946 | "authors": [ 1947 | { 1948 | "name": "Fabien Potencier", 1949 | "email": "fabien@symfony.com" 1950 | }, 1951 | { 1952 | "name": "Symfony Community", 1953 | "homepage": "https://symfony.com/contributors" 1954 | } 1955 | ], 1956 | "description": "Symfony Yaml Component", 1957 | "homepage": "https://symfony.com", 1958 | "time": "2016-05-26 21:46:24" 1959 | } 1960 | ], 1961 | "aliases": [], 1962 | "minimum-stability": "stable", 1963 | "stability-flags": [], 1964 | "prefer-stable": false, 1965 | "prefer-lowest": false, 1966 | "platform": [], 1967 | "platform-dev": [] 1968 | } 1969 | --------------------------------------------------------------------------------