├── .gitignore ├── .travis.yml ├── CHANCHELOG.md ├── LICENSE.md ├── README.md ├── codeception.yml ├── composer.json ├── composer.lock ├── docs └── ru │ └── README.md ├── src ├── ActiveQuery.php └── ActiveRecordTrait.php └── tests ├── .gitignore ├── _bootstrap.php ├── _data ├── Config.php ├── Config2.php └── dump.sql ├── unit.suite.yml └── unit ├── MappableARTest.php ├── _bootstrap.php └── _config.php /.gitignore: -------------------------------------------------------------------------------- 1 | # phpstorm project files 2 | .idea 3 | 4 | # netbeans project files 5 | nbproject 6 | 7 | # zend studio for eclipse project files 8 | .buildpath 9 | .project 10 | .settings 11 | 12 | # sublime text project / workspace files 13 | *.sublime-project 14 | *.sublime-workspace 15 | 16 | # windows thumbnail cache 17 | Thumbs.db 18 | 19 | # composer vendor dir 20 | /vendor 21 | # cubrid install dir 22 | /cubrid 23 | 24 | # composer itself is not needed 25 | composer.phar 26 | 27 | # composer.lock in applications is ignored since it's automatically created by composer when application is installed 28 | /apps/*/composer.lock 29 | 30 | # Mac DS_Store Files 31 | .DS_Store 32 | 33 | # phpunit itself is not needed 34 | phpunit.phar 35 | # local phpunit config 36 | /phpunit.xml 37 | 38 | tests/_output/* 39 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - 5.5 5 | - 5.6 6 | - 7.0 7 | 8 | install: 9 | - travis_retry composer global self-update 10 | - travis_retry composer global require fxp/composer-asset-plugin:~1.1.1 11 | - travis_retry composer install --prefer-dist --dev 12 | - vendor/codeception/codeception/codecept build 13 | 14 | before_script: 15 | - | 16 | if [ $TRAVIS_PHP_VERSION = '5.6' ]; then 17 | CODECEPT_FLAGS="--coverage --coverage-xml" 18 | fi 19 | script: 20 | - vendor/codeception/codeception/codecept run --verbose $CODECEPT_FLAGS 21 | 22 | cache: 23 | - vendor 24 | - $HOME/.composer/cache 25 | 26 | after_script: 27 | - | 28 | if [ $TRAVIS_PHP_VERSION = '5.6' ]; then 29 | bash <(curl -s https://codecov.io/bash) 30 | fi 31 | -------------------------------------------------------------------------------- /CHANCHELOG.md: -------------------------------------------------------------------------------- 1 | Yii2 Mappable ActiveRecord Change Log 2 | ===================================== 3 | 4 | 1.1.0 under development 5 | ----------------------- 6 | 7 | - Bug #4: Added new tests (fps01) 8 | 9 | 1.0.5 October 10, 2016 10 | ---------------------- 11 | 12 | - Enh #3: Implemented an identity map resorting (fps01) 13 | 14 | 1.0.4 August 25, 2016 15 | --------------------- 16 | 17 | - Fix #7: Fixed the bug with `find` method overriding (fps01) 18 | 19 | 1.0.3 July 20, 2016 20 | ------------------- 21 | 22 | - Enh #6: Implemented a new logic of `getByAttribute` method (fps01) 23 | 24 | 1.0.2 July 17, 2016 25 | ------------------- 26 | 27 | - Enh: Added an ability to set a primary key attribute and a maximum count of items in identity map (fps01) 28 | 29 | 1.0.1 July 16, 2016 30 | ------------------- 31 | 32 | - New #2: Added a russian documentation (fps01) 33 | - Enh #2: Fixed an english documentation (fps01) 34 | 35 | 1.0.0 March 20, 2016 36 | -------------------- 37 | 38 | - Initial release -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, Yiister 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of qwe nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Yii2 mappable ActiveRecord 2 | ========================== 3 | 4 | It is an extension for Yii framework 2 that gives an ability to use identity map for any ActiveRecord model. 5 | 6 | [![Build Status](https://travis-ci.org/yiister/yii2-mappable-ar.svg?branch=master)](https://travis-ci.org/yiister/yii2-mappable-ar) 7 | [![codecov.io](https://codecov.io/github/yiister/yii2-mappable-ar/coverage.svg?branch=master)](https://codecov.io/github/yiister/yii2-mappable-ar?branch=master) 8 | 9 | 10 | [Russian documentation](docs/ru). 11 | 12 | How it works 13 | ------------ 14 | 15 | `ActiveRecordTrait` overrides a `find` method of model. This method creates a custom `ActiveQuery`. When `one` (`all`) method is called, a got model (models) save to `identityMap` as array of attributes (It saves a memory). The next requests return data without queries to data base. 16 | 17 | By the way the next methods are allowed: 18 | 19 | - `getById(integer $id, boolean $asArray = false)` - get a model or an array of attributes (It depends on second param value) by primary key; 20 | - `getByAttribute(string $attribute, string $value, boolean $asArray = false)` - get a model or an array of attributes (It depends on second param value) by unique attribute value; 21 | - `getMap()` - get all models from `identityMap` as array of attributes; 22 | - `clearMap()` - clear an `identityMap`. 23 | 24 | Installation 25 | ------------ 26 | 27 | The preferred way to install this extension is through [composer](http://getcomposer.org/download/). 28 | 29 | Either run 30 | 31 | ``` 32 | composer require --prefer-dist yiister/yii2-mappable-ar 33 | ``` 34 | 35 | or add 36 | 37 | ```json 38 | "yiister/yii2-mappable-ar": "~1.0.0" 39 | ``` 40 | 41 | to the `require` section of your composer.json. 42 | 43 | Setting 44 | ------- 45 | 46 | The extension supports the next settings: 47 | 48 | - `idAttribute` - the primary key attribute (by default `id`); 49 | - `identityMapMaxSize` - the maximum elements count in identityMap (by default `-1` = no limit); 50 | - `uniqueAttributes` - array of attribute names that contains unique values. It is used at the `getByAttribute` method. 51 | 52 | For example, for change a primary key attribute to `key` add to your model `public static $idAttribute = 'key';`. 53 | 54 | Using 55 | ----- 56 | 57 | Just add `use yiister\mappable\ActiveRecordTrait;` to your model for using an identityMap. You got all features after it. 58 | 59 | **Warn!** If you have overridden `find` method in your model you have to call `activeRecordTraitFind()` method and work with its result. 60 | 61 | Example: 62 | 63 | ```php 64 | public static function find() 65 | { 66 | $query = static::activeRecordTraitFind(); 67 | // another work with $query 68 | return $query; 69 | } 70 | ``` 71 | -------------------------------------------------------------------------------- /codeception.yml: -------------------------------------------------------------------------------- 1 | actor: Tester 2 | paths: 3 | tests: tests 4 | log: tests/_output 5 | data: tests/_data 6 | helpers: tests/_support 7 | envs: tests/_envs 8 | settings: 9 | bootstrap: _bootstrap.php 10 | colors: true 11 | memory_limit: 1024M 12 | extensions: 13 | enabled: 14 | - Codeception\Extension\RunFailed 15 | modules: 16 | config: 17 | Db: 18 | dsn: 'sqlite:tests/_output/temp.db' 19 | user: '' 20 | password: '' 21 | dump: tests/_data/dump.sql 22 | coverage: 23 | enabled: true 24 | include: 25 | - src/* 26 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "yiister/yii2-mappable-ar", 3 | "description": "It is an extension for Yii framework 2 that gives an ability to use identity map for any ActiveRecord model.", 4 | "keywords": [ 5 | "yii2", 6 | "utils", 7 | "extension", 8 | "backend", 9 | "mappable", 10 | "active-record", 11 | "identity-map", 12 | "AR" 13 | ], 14 | "homepage": "https://github.com/yiister/yii2-mappable-ar", 15 | "type": "yii2-extension", 16 | "license": "BSD-3-Clause", 17 | "authors": [ 18 | { 19 | "name": "Pavel Fedotov", 20 | "email": "fps.06@mail.ru", 21 | "homepage": "https://github.com/fps01", 22 | "role": "Creator" 23 | } 24 | ], 25 | "support": { 26 | "issues": "https://github.com/yiister/yii2-mappable-ar/issues", 27 | "source": "https://github.com/yiister/yii2-mappable-ar" 28 | }, 29 | "require": { 30 | "php": ">=5.4.0", 31 | "yiisoft/yii2": "~2.0.0" 32 | }, 33 | "require-dev": { 34 | "codeception/codeception": "^2.2", 35 | "yiisoft/yii2-codeception": "^2.0" 36 | }, 37 | "autoload": { 38 | "psr-4": { 39 | "yiister\\mappable\\": "src/" 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /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": "423ec235ad63e43d30691cb5a1c07d27", 8 | "content-hash": "4dc04ab21366cc5bc2b9e3ac61b7ecb2", 9 | "packages": [ 10 | { 11 | "name": "bower-asset/jquery", 12 | "version": "2.2.4", 13 | "source": { 14 | "type": "git", 15 | "url": "https://github.com/jquery/jquery-dist.git", 16 | "reference": "c0185ab7c75aab88762c5aae780b9d83b80eda72" 17 | }, 18 | "dist": { 19 | "type": "zip", 20 | "url": "https://api.github.com/repos/jquery/jquery-dist/zipball/c0185ab7c75aab88762c5aae780b9d83b80eda72", 21 | "reference": "c0185ab7c75aab88762c5aae780b9d83b80eda72", 22 | "shasum": "" 23 | }, 24 | "type": "bower-asset-library", 25 | "extra": { 26 | "bower-asset-main": "dist/jquery.js", 27 | "bower-asset-ignore": [ 28 | "package.json" 29 | ] 30 | }, 31 | "license": [ 32 | "MIT" 33 | ], 34 | "keywords": [ 35 | "browser", 36 | "javascript", 37 | "jquery", 38 | "library" 39 | ] 40 | }, 41 | { 42 | "name": "bower-asset/jquery.inputmask", 43 | "version": "3.2.7", 44 | "source": { 45 | "type": "git", 46 | "url": "https://github.com/RobinHerbots/Inputmask.git", 47 | "reference": "5a72c563b502b8e05958a524cdfffafe9987be38" 48 | }, 49 | "dist": { 50 | "type": "zip", 51 | "url": "https://api.github.com/repos/RobinHerbots/Inputmask/zipball/5a72c563b502b8e05958a524cdfffafe9987be38", 52 | "reference": "5a72c563b502b8e05958a524cdfffafe9987be38", 53 | "shasum": "" 54 | }, 55 | "require": { 56 | "bower-asset/jquery": ">=1.7" 57 | }, 58 | "type": "bower-asset-library", 59 | "extra": { 60 | "bower-asset-main": [ 61 | "./dist/inputmask/inputmask.js" 62 | ], 63 | "bower-asset-ignore": [ 64 | "**/*", 65 | "!dist/*", 66 | "!dist/inputmask/*", 67 | "!dist/min/*", 68 | "!dist/min/inputmask/*", 69 | "!extra/bindings/*", 70 | "!extra/dependencyLibs/*", 71 | "!extra/phone-codes/*" 72 | ] 73 | }, 74 | "license": [ 75 | "http://opensource.org/licenses/mit-license.php" 76 | ], 77 | "description": "jquery.inputmask is a jquery plugin which create an input mask.", 78 | "keywords": [ 79 | "form", 80 | "input", 81 | "inputmask", 82 | "jquery", 83 | "mask", 84 | "plugins" 85 | ] 86 | }, 87 | { 88 | "name": "bower-asset/punycode", 89 | "version": "v1.3.2", 90 | "source": { 91 | "type": "git", 92 | "url": "https://github.com/bestiejs/punycode.js.git", 93 | "reference": "38c8d3131a82567bfef18da09f7f4db68c84f8a3" 94 | }, 95 | "dist": { 96 | "type": "zip", 97 | "url": "https://api.github.com/repos/bestiejs/punycode.js/zipball/38c8d3131a82567bfef18da09f7f4db68c84f8a3", 98 | "reference": "38c8d3131a82567bfef18da09f7f4db68c84f8a3", 99 | "shasum": "" 100 | }, 101 | "type": "bower-asset-library", 102 | "extra": { 103 | "bower-asset-main": "punycode.js", 104 | "bower-asset-ignore": [ 105 | "coverage", 106 | "tests", 107 | ".*", 108 | "component.json", 109 | "Gruntfile.js", 110 | "node_modules", 111 | "package.json" 112 | ] 113 | } 114 | }, 115 | { 116 | "name": "bower-asset/yii2-pjax", 117 | "version": "v2.0.6", 118 | "source": { 119 | "type": "git", 120 | "url": "https://github.com/yiisoft/jquery-pjax.git", 121 | "reference": "60728da6ade5879e807a49ce59ef9a72039b8978" 122 | }, 123 | "dist": { 124 | "type": "zip", 125 | "url": "https://api.github.com/repos/yiisoft/jquery-pjax/zipball/60728da6ade5879e807a49ce59ef9a72039b8978", 126 | "reference": "60728da6ade5879e807a49ce59ef9a72039b8978", 127 | "shasum": "" 128 | }, 129 | "require": { 130 | "bower-asset/jquery": ">=1.8" 131 | }, 132 | "type": "bower-asset-library", 133 | "extra": { 134 | "bower-asset-main": "./jquery.pjax.js", 135 | "bower-asset-ignore": [ 136 | ".travis.yml", 137 | "Gemfile", 138 | "Gemfile.lock", 139 | "CONTRIBUTING.md", 140 | "vendor/", 141 | "script/", 142 | "test/" 143 | ] 144 | }, 145 | "license": [ 146 | "MIT" 147 | ] 148 | }, 149 | { 150 | "name": "cebe/markdown", 151 | "version": "1.1.1", 152 | "source": { 153 | "type": "git", 154 | "url": "https://github.com/cebe/markdown.git", 155 | "reference": "c30eb5e01fe021cc5bba2f9ee0eeef96d4931166" 156 | }, 157 | "dist": { 158 | "type": "zip", 159 | "url": "https://api.github.com/repos/cebe/markdown/zipball/c30eb5e01fe021cc5bba2f9ee0eeef96d4931166", 160 | "reference": "c30eb5e01fe021cc5bba2f9ee0eeef96d4931166", 161 | "shasum": "" 162 | }, 163 | "require": { 164 | "lib-pcre": "*", 165 | "php": ">=5.4.0" 166 | }, 167 | "require-dev": { 168 | "cebe/indent": "*", 169 | "facebook/xhprof": "*@dev", 170 | "phpunit/phpunit": "4.1.*" 171 | }, 172 | "bin": [ 173 | "bin/markdown" 174 | ], 175 | "type": "library", 176 | "extra": { 177 | "branch-alias": { 178 | "dev-master": "1.1.x-dev" 179 | } 180 | }, 181 | "autoload": { 182 | "psr-4": { 183 | "cebe\\markdown\\": "" 184 | } 185 | }, 186 | "notification-url": "https://packagist.org/downloads/", 187 | "license": [ 188 | "MIT" 189 | ], 190 | "authors": [ 191 | { 192 | "name": "Carsten Brandt", 193 | "email": "mail@cebe.cc", 194 | "homepage": "http://cebe.cc/", 195 | "role": "Creator" 196 | } 197 | ], 198 | "description": "A super fast, highly extensible markdown parser for PHP", 199 | "homepage": "https://github.com/cebe/markdown#readme", 200 | "keywords": [ 201 | "extensible", 202 | "fast", 203 | "gfm", 204 | "markdown", 205 | "markdown-extra" 206 | ], 207 | "time": "2016-09-14 20:40:20" 208 | }, 209 | { 210 | "name": "ezyang/htmlpurifier", 211 | "version": "v4.8.0", 212 | "source": { 213 | "type": "git", 214 | "url": "https://github.com/ezyang/htmlpurifier.git", 215 | "reference": "d0c392f77d2f2a3dcf7fcb79e2a1e2b8804e75b2" 216 | }, 217 | "dist": { 218 | "type": "zip", 219 | "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/d0c392f77d2f2a3dcf7fcb79e2a1e2b8804e75b2", 220 | "reference": "d0c392f77d2f2a3dcf7fcb79e2a1e2b8804e75b2", 221 | "shasum": "" 222 | }, 223 | "require": { 224 | "php": ">=5.2" 225 | }, 226 | "type": "library", 227 | "autoload": { 228 | "psr-0": { 229 | "HTMLPurifier": "library/" 230 | }, 231 | "files": [ 232 | "library/HTMLPurifier.composer.php" 233 | ] 234 | }, 235 | "notification-url": "https://packagist.org/downloads/", 236 | "license": [ 237 | "LGPL" 238 | ], 239 | "authors": [ 240 | { 241 | "name": "Edward Z. Yang", 242 | "email": "admin@htmlpurifier.org", 243 | "homepage": "http://ezyang.com" 244 | } 245 | ], 246 | "description": "Standards compliant HTML filter written in PHP", 247 | "homepage": "http://htmlpurifier.org/", 248 | "keywords": [ 249 | "html" 250 | ], 251 | "time": "2016-07-16 12:58:58" 252 | }, 253 | { 254 | "name": "yiisoft/yii2", 255 | "version": "2.0.9", 256 | "source": { 257 | "type": "git", 258 | "url": "https://github.com/yiisoft/yii2-framework.git", 259 | "reference": "2b75151ea60e1fd820046416eee2e89c3dda1133" 260 | }, 261 | "dist": { 262 | "type": "zip", 263 | "url": "https://api.github.com/repos/yiisoft/yii2-framework/zipball/2b75151ea60e1fd820046416eee2e89c3dda1133", 264 | "reference": "2b75151ea60e1fd820046416eee2e89c3dda1133", 265 | "shasum": "" 266 | }, 267 | "require": { 268 | "bower-asset/jquery": "2.2.*@stable | 2.1.*@stable | 1.11.*@stable | 1.12.*@stable", 269 | "bower-asset/jquery.inputmask": "~3.2.2", 270 | "bower-asset/punycode": "1.3.*", 271 | "bower-asset/yii2-pjax": "~2.0.1", 272 | "cebe/markdown": "~1.0.0 | ~1.1.0", 273 | "ext-ctype": "*", 274 | "ext-mbstring": "*", 275 | "ezyang/htmlpurifier": "~4.6", 276 | "lib-pcre": "*", 277 | "php": ">=5.4.0", 278 | "yiisoft/yii2-composer": "~2.0.4" 279 | }, 280 | "bin": [ 281 | "yii" 282 | ], 283 | "type": "library", 284 | "extra": { 285 | "branch-alias": { 286 | "dev-master": "2.0.x-dev" 287 | } 288 | }, 289 | "autoload": { 290 | "psr-4": { 291 | "yii\\": "" 292 | } 293 | }, 294 | "notification-url": "https://packagist.org/downloads/", 295 | "license": [ 296 | "BSD-3-Clause" 297 | ], 298 | "authors": [ 299 | { 300 | "name": "Qiang Xue", 301 | "email": "qiang.xue@gmail.com", 302 | "homepage": "http://www.yiiframework.com/", 303 | "role": "Founder and project lead" 304 | }, 305 | { 306 | "name": "Alexander Makarov", 307 | "email": "sam@rmcreative.ru", 308 | "homepage": "http://rmcreative.ru/", 309 | "role": "Core framework development" 310 | }, 311 | { 312 | "name": "Maurizio Domba", 313 | "homepage": "http://mdomba.info/", 314 | "role": "Core framework development" 315 | }, 316 | { 317 | "name": "Carsten Brandt", 318 | "email": "mail@cebe.cc", 319 | "homepage": "http://cebe.cc/", 320 | "role": "Core framework development" 321 | }, 322 | { 323 | "name": "Timur Ruziev", 324 | "email": "resurtm@gmail.com", 325 | "homepage": "http://resurtm.com/", 326 | "role": "Core framework development" 327 | }, 328 | { 329 | "name": "Paul Klimov", 330 | "email": "klimov.paul@gmail.com", 331 | "role": "Core framework development" 332 | }, 333 | { 334 | "name": "Dmitry Naumenko", 335 | "email": "d.naumenko.a@gmail.com", 336 | "role": "Core framework development" 337 | } 338 | ], 339 | "description": "Yii PHP Framework Version 2", 340 | "homepage": "http://www.yiiframework.com/", 341 | "keywords": [ 342 | "framework", 343 | "yii2" 344 | ], 345 | "time": "2016-07-11 13:36:42" 346 | }, 347 | { 348 | "name": "yiisoft/yii2-composer", 349 | "version": "2.0.4", 350 | "source": { 351 | "type": "git", 352 | "url": "https://github.com/yiisoft/yii2-composer.git", 353 | "reference": "7452fd908a5023b8bb5ea1b123a174ca080de464" 354 | }, 355 | "dist": { 356 | "type": "zip", 357 | "url": "https://api.github.com/repos/yiisoft/yii2-composer/zipball/7452fd908a5023b8bb5ea1b123a174ca080de464", 358 | "reference": "7452fd908a5023b8bb5ea1b123a174ca080de464", 359 | "shasum": "" 360 | }, 361 | "require": { 362 | "composer-plugin-api": "^1.0" 363 | }, 364 | "type": "composer-plugin", 365 | "extra": { 366 | "class": "yii\\composer\\Plugin", 367 | "branch-alias": { 368 | "dev-master": "2.0.x-dev" 369 | } 370 | }, 371 | "autoload": { 372 | "psr-4": { 373 | "yii\\composer\\": "" 374 | } 375 | }, 376 | "notification-url": "https://packagist.org/downloads/", 377 | "license": [ 378 | "BSD-3-Clause" 379 | ], 380 | "authors": [ 381 | { 382 | "name": "Qiang Xue", 383 | "email": "qiang.xue@gmail.com" 384 | } 385 | ], 386 | "description": "The composer plugin for Yii extension installer", 387 | "keywords": [ 388 | "composer", 389 | "extension installer", 390 | "yii2" 391 | ], 392 | "time": "2016-02-06 00:49:24" 393 | } 394 | ], 395 | "packages-dev": [ 396 | { 397 | "name": "behat/gherkin", 398 | "version": "v4.4.4", 399 | "source": { 400 | "type": "git", 401 | "url": "https://github.com/Behat/Gherkin.git", 402 | "reference": "cf8cc94647101e02a33d690245896d83d880aea1" 403 | }, 404 | "dist": { 405 | "type": "zip", 406 | "url": "https://api.github.com/repos/Behat/Gherkin/zipball/cf8cc94647101e02a33d690245896d83d880aea1", 407 | "reference": "cf8cc94647101e02a33d690245896d83d880aea1", 408 | "shasum": "" 409 | }, 410 | "require": { 411 | "php": ">=5.3.1" 412 | }, 413 | "require-dev": { 414 | "phpunit/phpunit": "~4.5|~5", 415 | "symfony/phpunit-bridge": "~2.7|~3", 416 | "symfony/yaml": "~2.3|~3" 417 | }, 418 | "suggest": { 419 | "symfony/yaml": "If you want to parse features, represented in YAML files" 420 | }, 421 | "type": "library", 422 | "extra": { 423 | "branch-alias": { 424 | "dev-master": "4.4-dev" 425 | } 426 | }, 427 | "autoload": { 428 | "psr-0": { 429 | "Behat\\Gherkin": "src/" 430 | } 431 | }, 432 | "notification-url": "https://packagist.org/downloads/", 433 | "license": [ 434 | "MIT" 435 | ], 436 | "authors": [ 437 | { 438 | "name": "Konstantin Kudryashov", 439 | "email": "ever.zet@gmail.com", 440 | "homepage": "http://everzet.com" 441 | } 442 | ], 443 | "description": "Gherkin DSL parser for PHP 5.3", 444 | "homepage": "http://behat.org/", 445 | "keywords": [ 446 | "BDD", 447 | "Behat", 448 | "Cucumber", 449 | "DSL", 450 | "gherkin", 451 | "parser" 452 | ], 453 | "time": "2016-09-18 12:16:14" 454 | }, 455 | { 456 | "name": "codeception/codeception", 457 | "version": "2.2.5", 458 | "source": { 459 | "type": "git", 460 | "url": "https://github.com/Codeception/Codeception.git", 461 | "reference": "b4729341e469d0f174f3cade85718ff5bf8dd751" 462 | }, 463 | "dist": { 464 | "type": "zip", 465 | "url": "https://api.github.com/repos/Codeception/Codeception/zipball/b4729341e469d0f174f3cade85718ff5bf8dd751", 466 | "reference": "b4729341e469d0f174f3cade85718ff5bf8dd751", 467 | "shasum": "" 468 | }, 469 | "require": { 470 | "behat/gherkin": "~4.4.0", 471 | "ext-json": "*", 472 | "ext-mbstring": "*", 473 | "facebook/webdriver": ">=1.0.1 <2.0", 474 | "guzzlehttp/guzzle": ">=4.1.4 <7.0", 475 | "guzzlehttp/psr7": "~1.0", 476 | "php": ">=5.4.0 <8.0", 477 | "phpunit/php-code-coverage": ">=2.1.3 <5.0", 478 | "phpunit/phpunit": ">4.8.20 <6.0", 479 | "sebastian/comparator": "~1.1", 480 | "sebastian/diff": "^1.4", 481 | "symfony/browser-kit": ">=2.7 <4.0", 482 | "symfony/console": ">=2.7 <4.0", 483 | "symfony/css-selector": ">=2.7 <4.0", 484 | "symfony/dom-crawler": ">=2.7 <4.0", 485 | "symfony/event-dispatcher": ">=2.7 <4.0", 486 | "symfony/finder": ">=2.7 <4.0", 487 | "symfony/yaml": ">=2.7 <4.0" 488 | }, 489 | "require-dev": { 490 | "codeception/specify": "~0.3", 491 | "facebook/graph-sdk": "~5.3", 492 | "flow/jsonpath": "~0.2", 493 | "league/factory-muffin": "^3.0", 494 | "league/factory-muffin-faker": "^1.0", 495 | "mongodb/mongodb": "^1.0", 496 | "monolog/monolog": "~1.8", 497 | "pda/pheanstalk": "~3.0", 498 | "php-amqplib/php-amqplib": "~2.4", 499 | "predis/predis": "^1.0", 500 | "squizlabs/php_codesniffer": "~2.0" 501 | }, 502 | "suggest": { 503 | "codeception/specify": "BDD-style code blocks", 504 | "codeception/verify": "BDD-style assertions", 505 | "flow/jsonpath": "For using JSONPath in REST module", 506 | "league/factory-muffin": "For DataFactory module", 507 | "league/factory-muffin-faker": "For Faker support in DataFactory module", 508 | "phpseclib/phpseclib": "for SFTP option in FTP Module", 509 | "symfony/phpunit-bridge": "For phpunit-bridge support" 510 | }, 511 | "bin": [ 512 | "codecept" 513 | ], 514 | "type": "library", 515 | "extra": { 516 | "branch-alias": [] 517 | }, 518 | "autoload": { 519 | "psr-4": { 520 | "Codeception\\": "src\\Codeception", 521 | "Codeception\\Extension\\": "ext" 522 | } 523 | }, 524 | "notification-url": "https://packagist.org/downloads/", 525 | "license": [ 526 | "MIT" 527 | ], 528 | "authors": [ 529 | { 530 | "name": "Michael Bodnarchuk", 531 | "email": "davert@mail.ua", 532 | "homepage": "http://codegyre.com" 533 | } 534 | ], 535 | "description": "BDD-style testing framework", 536 | "homepage": "http://codeception.com/", 537 | "keywords": [ 538 | "BDD", 539 | "TDD", 540 | "acceptance testing", 541 | "functional testing", 542 | "unit testing" 543 | ], 544 | "time": "2016-09-29 01:29:59" 545 | }, 546 | { 547 | "name": "doctrine/instantiator", 548 | "version": "1.0.5", 549 | "source": { 550 | "type": "git", 551 | "url": "https://github.com/doctrine/instantiator.git", 552 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" 553 | }, 554 | "dist": { 555 | "type": "zip", 556 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", 557 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", 558 | "shasum": "" 559 | }, 560 | "require": { 561 | "php": ">=5.3,<8.0-DEV" 562 | }, 563 | "require-dev": { 564 | "athletic/athletic": "~0.1.8", 565 | "ext-pdo": "*", 566 | "ext-phar": "*", 567 | "phpunit/phpunit": "~4.0", 568 | "squizlabs/php_codesniffer": "~2.0" 569 | }, 570 | "type": "library", 571 | "extra": { 572 | "branch-alias": { 573 | "dev-master": "1.0.x-dev" 574 | } 575 | }, 576 | "autoload": { 577 | "psr-4": { 578 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" 579 | } 580 | }, 581 | "notification-url": "https://packagist.org/downloads/", 582 | "license": [ 583 | "MIT" 584 | ], 585 | "authors": [ 586 | { 587 | "name": "Marco Pivetta", 588 | "email": "ocramius@gmail.com", 589 | "homepage": "http://ocramius.github.com/" 590 | } 591 | ], 592 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", 593 | "homepage": "https://github.com/doctrine/instantiator", 594 | "keywords": [ 595 | "constructor", 596 | "instantiate" 597 | ], 598 | "time": "2015-06-14 21:17:01" 599 | }, 600 | { 601 | "name": "facebook/webdriver", 602 | "version": "1.1.3", 603 | "source": { 604 | "type": "git", 605 | "url": "https://github.com/facebook/php-webdriver.git", 606 | "reference": "b7186fb1bcfda956d237f59face250d06ef47253" 607 | }, 608 | "dist": { 609 | "type": "zip", 610 | "url": "https://api.github.com/repos/facebook/php-webdriver/zipball/b7186fb1bcfda956d237f59face250d06ef47253", 611 | "reference": "b7186fb1bcfda956d237f59face250d06ef47253", 612 | "shasum": "" 613 | }, 614 | "require": { 615 | "ext-curl": "*", 616 | "php": ">=5.3.19" 617 | }, 618 | "require-dev": { 619 | "friendsofphp/php-cs-fixer": "^1.11", 620 | "phpunit/phpunit": "4.6.* || ~5.0", 621 | "squizlabs/php_codesniffer": "^2.6" 622 | }, 623 | "suggest": { 624 | "phpdocumentor/phpdocumentor": "2.*" 625 | }, 626 | "type": "library", 627 | "autoload": { 628 | "psr-4": { 629 | "Facebook\\WebDriver\\": "lib/" 630 | } 631 | }, 632 | "notification-url": "https://packagist.org/downloads/", 633 | "license": [ 634 | "Apache-2.0" 635 | ], 636 | "description": "A PHP client for WebDriver", 637 | "homepage": "https://github.com/facebook/php-webdriver", 638 | "keywords": [ 639 | "facebook", 640 | "php", 641 | "selenium", 642 | "webdriver" 643 | ], 644 | "time": "2016-08-10 00:44:08" 645 | }, 646 | { 647 | "name": "guzzlehttp/guzzle", 648 | "version": "6.2.1", 649 | "source": { 650 | "type": "git", 651 | "url": "https://github.com/guzzle/guzzle.git", 652 | "reference": "3f808fba627f2c5b69e2501217bf31af349c1427" 653 | }, 654 | "dist": { 655 | "type": "zip", 656 | "url": "https://api.github.com/repos/guzzle/guzzle/zipball/3f808fba627f2c5b69e2501217bf31af349c1427", 657 | "reference": "3f808fba627f2c5b69e2501217bf31af349c1427", 658 | "shasum": "" 659 | }, 660 | "require": { 661 | "guzzlehttp/promises": "^1.0", 662 | "guzzlehttp/psr7": "^1.3.1", 663 | "php": ">=5.5" 664 | }, 665 | "require-dev": { 666 | "ext-curl": "*", 667 | "phpunit/phpunit": "^4.0", 668 | "psr/log": "^1.0" 669 | }, 670 | "type": "library", 671 | "extra": { 672 | "branch-alias": { 673 | "dev-master": "6.2-dev" 674 | } 675 | }, 676 | "autoload": { 677 | "files": [ 678 | "src/functions_include.php" 679 | ], 680 | "psr-4": { 681 | "GuzzleHttp\\": "src/" 682 | } 683 | }, 684 | "notification-url": "https://packagist.org/downloads/", 685 | "license": [ 686 | "MIT" 687 | ], 688 | "authors": [ 689 | { 690 | "name": "Michael Dowling", 691 | "email": "mtdowling@gmail.com", 692 | "homepage": "https://github.com/mtdowling" 693 | } 694 | ], 695 | "description": "Guzzle is a PHP HTTP client library", 696 | "homepage": "http://guzzlephp.org/", 697 | "keywords": [ 698 | "client", 699 | "curl", 700 | "framework", 701 | "http", 702 | "http client", 703 | "rest", 704 | "web service" 705 | ], 706 | "time": "2016-07-15 17:22:37" 707 | }, 708 | { 709 | "name": "guzzlehttp/promises", 710 | "version": "1.2.0", 711 | "source": { 712 | "type": "git", 713 | "url": "https://github.com/guzzle/promises.git", 714 | "reference": "c10d860e2a9595f8883527fa0021c7da9e65f579" 715 | }, 716 | "dist": { 717 | "type": "zip", 718 | "url": "https://api.github.com/repos/guzzle/promises/zipball/c10d860e2a9595f8883527fa0021c7da9e65f579", 719 | "reference": "c10d860e2a9595f8883527fa0021c7da9e65f579", 720 | "shasum": "" 721 | }, 722 | "require": { 723 | "php": ">=5.5.0" 724 | }, 725 | "require-dev": { 726 | "phpunit/phpunit": "~4.0" 727 | }, 728 | "type": "library", 729 | "extra": { 730 | "branch-alias": { 731 | "dev-master": "1.0-dev" 732 | } 733 | }, 734 | "autoload": { 735 | "psr-4": { 736 | "GuzzleHttp\\Promise\\": "src/" 737 | }, 738 | "files": [ 739 | "src/functions_include.php" 740 | ] 741 | }, 742 | "notification-url": "https://packagist.org/downloads/", 743 | "license": [ 744 | "MIT" 745 | ], 746 | "authors": [ 747 | { 748 | "name": "Michael Dowling", 749 | "email": "mtdowling@gmail.com", 750 | "homepage": "https://github.com/mtdowling" 751 | } 752 | ], 753 | "description": "Guzzle promises library", 754 | "keywords": [ 755 | "promise" 756 | ], 757 | "time": "2016-05-18 16:56:05" 758 | }, 759 | { 760 | "name": "guzzlehttp/psr7", 761 | "version": "1.3.1", 762 | "source": { 763 | "type": "git", 764 | "url": "https://github.com/guzzle/psr7.git", 765 | "reference": "5c6447c9df362e8f8093bda8f5d8873fe5c7f65b" 766 | }, 767 | "dist": { 768 | "type": "zip", 769 | "url": "https://api.github.com/repos/guzzle/psr7/zipball/5c6447c9df362e8f8093bda8f5d8873fe5c7f65b", 770 | "reference": "5c6447c9df362e8f8093bda8f5d8873fe5c7f65b", 771 | "shasum": "" 772 | }, 773 | "require": { 774 | "php": ">=5.4.0", 775 | "psr/http-message": "~1.0" 776 | }, 777 | "provide": { 778 | "psr/http-message-implementation": "1.0" 779 | }, 780 | "require-dev": { 781 | "phpunit/phpunit": "~4.0" 782 | }, 783 | "type": "library", 784 | "extra": { 785 | "branch-alias": { 786 | "dev-master": "1.4-dev" 787 | } 788 | }, 789 | "autoload": { 790 | "psr-4": { 791 | "GuzzleHttp\\Psr7\\": "src/" 792 | }, 793 | "files": [ 794 | "src/functions_include.php" 795 | ] 796 | }, 797 | "notification-url": "https://packagist.org/downloads/", 798 | "license": [ 799 | "MIT" 800 | ], 801 | "authors": [ 802 | { 803 | "name": "Michael Dowling", 804 | "email": "mtdowling@gmail.com", 805 | "homepage": "https://github.com/mtdowling" 806 | } 807 | ], 808 | "description": "PSR-7 message implementation", 809 | "keywords": [ 810 | "http", 811 | "message", 812 | "stream", 813 | "uri" 814 | ], 815 | "time": "2016-06-24 23:00:38" 816 | }, 817 | { 818 | "name": "phpdocumentor/reflection-common", 819 | "version": "1.0", 820 | "source": { 821 | "type": "git", 822 | "url": "https://github.com/phpDocumentor/ReflectionCommon.git", 823 | "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c" 824 | }, 825 | "dist": { 826 | "type": "zip", 827 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c", 828 | "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c", 829 | "shasum": "" 830 | }, 831 | "require": { 832 | "php": ">=5.5" 833 | }, 834 | "require-dev": { 835 | "phpunit/phpunit": "^4.6" 836 | }, 837 | "type": "library", 838 | "extra": { 839 | "branch-alias": { 840 | "dev-master": "1.0.x-dev" 841 | } 842 | }, 843 | "autoload": { 844 | "psr-4": { 845 | "phpDocumentor\\Reflection\\": [ 846 | "src" 847 | ] 848 | } 849 | }, 850 | "notification-url": "https://packagist.org/downloads/", 851 | "license": [ 852 | "MIT" 853 | ], 854 | "authors": [ 855 | { 856 | "name": "Jaap van Otterdijk", 857 | "email": "opensource@ijaap.nl" 858 | } 859 | ], 860 | "description": "Common reflection classes used by phpdocumentor to reflect the code structure", 861 | "homepage": "http://www.phpdoc.org", 862 | "keywords": [ 863 | "FQSEN", 864 | "phpDocumentor", 865 | "phpdoc", 866 | "reflection", 867 | "static analysis" 868 | ], 869 | "time": "2015-12-27 11:43:31" 870 | }, 871 | { 872 | "name": "phpdocumentor/reflection-docblock", 873 | "version": "3.1.1", 874 | "source": { 875 | "type": "git", 876 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", 877 | "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e" 878 | }, 879 | "dist": { 880 | "type": "zip", 881 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/8331b5efe816ae05461b7ca1e721c01b46bafb3e", 882 | "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e", 883 | "shasum": "" 884 | }, 885 | "require": { 886 | "php": ">=5.5", 887 | "phpdocumentor/reflection-common": "^1.0@dev", 888 | "phpdocumentor/type-resolver": "^0.2.0", 889 | "webmozart/assert": "^1.0" 890 | }, 891 | "require-dev": { 892 | "mockery/mockery": "^0.9.4", 893 | "phpunit/phpunit": "^4.4" 894 | }, 895 | "type": "library", 896 | "autoload": { 897 | "psr-4": { 898 | "phpDocumentor\\Reflection\\": [ 899 | "src/" 900 | ] 901 | } 902 | }, 903 | "notification-url": "https://packagist.org/downloads/", 904 | "license": [ 905 | "MIT" 906 | ], 907 | "authors": [ 908 | { 909 | "name": "Mike van Riel", 910 | "email": "me@mikevanriel.com" 911 | } 912 | ], 913 | "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", 914 | "time": "2016-09-30 07:12:33" 915 | }, 916 | { 917 | "name": "phpdocumentor/type-resolver", 918 | "version": "0.2", 919 | "source": { 920 | "type": "git", 921 | "url": "https://github.com/phpDocumentor/TypeResolver.git", 922 | "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443" 923 | }, 924 | "dist": { 925 | "type": "zip", 926 | "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/b39c7a5b194f9ed7bd0dd345c751007a41862443", 927 | "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443", 928 | "shasum": "" 929 | }, 930 | "require": { 931 | "php": ">=5.5", 932 | "phpdocumentor/reflection-common": "^1.0" 933 | }, 934 | "require-dev": { 935 | "mockery/mockery": "^0.9.4", 936 | "phpunit/phpunit": "^5.2||^4.8.24" 937 | }, 938 | "type": "library", 939 | "extra": { 940 | "branch-alias": { 941 | "dev-master": "1.0.x-dev" 942 | } 943 | }, 944 | "autoload": { 945 | "psr-4": { 946 | "phpDocumentor\\Reflection\\": [ 947 | "src/" 948 | ] 949 | } 950 | }, 951 | "notification-url": "https://packagist.org/downloads/", 952 | "license": [ 953 | "MIT" 954 | ], 955 | "authors": [ 956 | { 957 | "name": "Mike van Riel", 958 | "email": "me@mikevanriel.com" 959 | } 960 | ], 961 | "time": "2016-06-10 07:14:17" 962 | }, 963 | { 964 | "name": "phpspec/prophecy", 965 | "version": "v1.6.1", 966 | "source": { 967 | "type": "git", 968 | "url": "https://github.com/phpspec/prophecy.git", 969 | "reference": "58a8137754bc24b25740d4281399a4a3596058e0" 970 | }, 971 | "dist": { 972 | "type": "zip", 973 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/58a8137754bc24b25740d4281399a4a3596058e0", 974 | "reference": "58a8137754bc24b25740d4281399a4a3596058e0", 975 | "shasum": "" 976 | }, 977 | "require": { 978 | "doctrine/instantiator": "^1.0.2", 979 | "php": "^5.3|^7.0", 980 | "phpdocumentor/reflection-docblock": "^2.0|^3.0.2", 981 | "sebastian/comparator": "^1.1", 982 | "sebastian/recursion-context": "^1.0" 983 | }, 984 | "require-dev": { 985 | "phpspec/phpspec": "^2.0" 986 | }, 987 | "type": "library", 988 | "extra": { 989 | "branch-alias": { 990 | "dev-master": "1.6.x-dev" 991 | } 992 | }, 993 | "autoload": { 994 | "psr-0": { 995 | "Prophecy\\": "src/" 996 | } 997 | }, 998 | "notification-url": "https://packagist.org/downloads/", 999 | "license": [ 1000 | "MIT" 1001 | ], 1002 | "authors": [ 1003 | { 1004 | "name": "Konstantin Kudryashov", 1005 | "email": "ever.zet@gmail.com", 1006 | "homepage": "http://everzet.com" 1007 | }, 1008 | { 1009 | "name": "Marcello Duarte", 1010 | "email": "marcello.duarte@gmail.com" 1011 | } 1012 | ], 1013 | "description": "Highly opinionated mocking framework for PHP 5.3+", 1014 | "homepage": "https://github.com/phpspec/prophecy", 1015 | "keywords": [ 1016 | "Double", 1017 | "Dummy", 1018 | "fake", 1019 | "mock", 1020 | "spy", 1021 | "stub" 1022 | ], 1023 | "time": "2016-06-07 08:13:47" 1024 | }, 1025 | { 1026 | "name": "phpunit/php-code-coverage", 1027 | "version": "2.2.4", 1028 | "source": { 1029 | "type": "git", 1030 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git", 1031 | "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979" 1032 | }, 1033 | "dist": { 1034 | "type": "zip", 1035 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979", 1036 | "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979", 1037 | "shasum": "" 1038 | }, 1039 | "require": { 1040 | "php": ">=5.3.3", 1041 | "phpunit/php-file-iterator": "~1.3", 1042 | "phpunit/php-text-template": "~1.2", 1043 | "phpunit/php-token-stream": "~1.3", 1044 | "sebastian/environment": "^1.3.2", 1045 | "sebastian/version": "~1.0" 1046 | }, 1047 | "require-dev": { 1048 | "ext-xdebug": ">=2.1.4", 1049 | "phpunit/phpunit": "~4" 1050 | }, 1051 | "suggest": { 1052 | "ext-dom": "*", 1053 | "ext-xdebug": ">=2.2.1", 1054 | "ext-xmlwriter": "*" 1055 | }, 1056 | "type": "library", 1057 | "extra": { 1058 | "branch-alias": { 1059 | "dev-master": "2.2.x-dev" 1060 | } 1061 | }, 1062 | "autoload": { 1063 | "classmap": [ 1064 | "src/" 1065 | ] 1066 | }, 1067 | "notification-url": "https://packagist.org/downloads/", 1068 | "license": [ 1069 | "BSD-3-Clause" 1070 | ], 1071 | "authors": [ 1072 | { 1073 | "name": "Sebastian Bergmann", 1074 | "email": "sb@sebastian-bergmann.de", 1075 | "role": "lead" 1076 | } 1077 | ], 1078 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", 1079 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage", 1080 | "keywords": [ 1081 | "coverage", 1082 | "testing", 1083 | "xunit" 1084 | ], 1085 | "time": "2015-10-06 15:47:00" 1086 | }, 1087 | { 1088 | "name": "phpunit/php-file-iterator", 1089 | "version": "1.4.1", 1090 | "source": { 1091 | "type": "git", 1092 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git", 1093 | "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0" 1094 | }, 1095 | "dist": { 1096 | "type": "zip", 1097 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0", 1098 | "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0", 1099 | "shasum": "" 1100 | }, 1101 | "require": { 1102 | "php": ">=5.3.3" 1103 | }, 1104 | "type": "library", 1105 | "extra": { 1106 | "branch-alias": { 1107 | "dev-master": "1.4.x-dev" 1108 | } 1109 | }, 1110 | "autoload": { 1111 | "classmap": [ 1112 | "src/" 1113 | ] 1114 | }, 1115 | "notification-url": "https://packagist.org/downloads/", 1116 | "license": [ 1117 | "BSD-3-Clause" 1118 | ], 1119 | "authors": [ 1120 | { 1121 | "name": "Sebastian Bergmann", 1122 | "email": "sb@sebastian-bergmann.de", 1123 | "role": "lead" 1124 | } 1125 | ], 1126 | "description": "FilterIterator implementation that filters files based on a list of suffixes.", 1127 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", 1128 | "keywords": [ 1129 | "filesystem", 1130 | "iterator" 1131 | ], 1132 | "time": "2015-06-21 13:08:43" 1133 | }, 1134 | { 1135 | "name": "phpunit/php-text-template", 1136 | "version": "1.2.1", 1137 | "source": { 1138 | "type": "git", 1139 | "url": "https://github.com/sebastianbergmann/php-text-template.git", 1140 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" 1141 | }, 1142 | "dist": { 1143 | "type": "zip", 1144 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 1145 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 1146 | "shasum": "" 1147 | }, 1148 | "require": { 1149 | "php": ">=5.3.3" 1150 | }, 1151 | "type": "library", 1152 | "autoload": { 1153 | "classmap": [ 1154 | "src/" 1155 | ] 1156 | }, 1157 | "notification-url": "https://packagist.org/downloads/", 1158 | "license": [ 1159 | "BSD-3-Clause" 1160 | ], 1161 | "authors": [ 1162 | { 1163 | "name": "Sebastian Bergmann", 1164 | "email": "sebastian@phpunit.de", 1165 | "role": "lead" 1166 | } 1167 | ], 1168 | "description": "Simple template engine.", 1169 | "homepage": "https://github.com/sebastianbergmann/php-text-template/", 1170 | "keywords": [ 1171 | "template" 1172 | ], 1173 | "time": "2015-06-21 13:50:34" 1174 | }, 1175 | { 1176 | "name": "phpunit/php-timer", 1177 | "version": "1.0.8", 1178 | "source": { 1179 | "type": "git", 1180 | "url": "https://github.com/sebastianbergmann/php-timer.git", 1181 | "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260" 1182 | }, 1183 | "dist": { 1184 | "type": "zip", 1185 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260", 1186 | "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260", 1187 | "shasum": "" 1188 | }, 1189 | "require": { 1190 | "php": ">=5.3.3" 1191 | }, 1192 | "require-dev": { 1193 | "phpunit/phpunit": "~4|~5" 1194 | }, 1195 | "type": "library", 1196 | "autoload": { 1197 | "classmap": [ 1198 | "src/" 1199 | ] 1200 | }, 1201 | "notification-url": "https://packagist.org/downloads/", 1202 | "license": [ 1203 | "BSD-3-Clause" 1204 | ], 1205 | "authors": [ 1206 | { 1207 | "name": "Sebastian Bergmann", 1208 | "email": "sb@sebastian-bergmann.de", 1209 | "role": "lead" 1210 | } 1211 | ], 1212 | "description": "Utility class for timing", 1213 | "homepage": "https://github.com/sebastianbergmann/php-timer/", 1214 | "keywords": [ 1215 | "timer" 1216 | ], 1217 | "time": "2016-05-12 18:03:57" 1218 | }, 1219 | { 1220 | "name": "phpunit/php-token-stream", 1221 | "version": "1.4.8", 1222 | "source": { 1223 | "type": "git", 1224 | "url": "https://github.com/sebastianbergmann/php-token-stream.git", 1225 | "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da" 1226 | }, 1227 | "dist": { 1228 | "type": "zip", 1229 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", 1230 | "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", 1231 | "shasum": "" 1232 | }, 1233 | "require": { 1234 | "ext-tokenizer": "*", 1235 | "php": ">=5.3.3" 1236 | }, 1237 | "require-dev": { 1238 | "phpunit/phpunit": "~4.2" 1239 | }, 1240 | "type": "library", 1241 | "extra": { 1242 | "branch-alias": { 1243 | "dev-master": "1.4-dev" 1244 | } 1245 | }, 1246 | "autoload": { 1247 | "classmap": [ 1248 | "src/" 1249 | ] 1250 | }, 1251 | "notification-url": "https://packagist.org/downloads/", 1252 | "license": [ 1253 | "BSD-3-Clause" 1254 | ], 1255 | "authors": [ 1256 | { 1257 | "name": "Sebastian Bergmann", 1258 | "email": "sebastian@phpunit.de" 1259 | } 1260 | ], 1261 | "description": "Wrapper around PHP's tokenizer extension.", 1262 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/", 1263 | "keywords": [ 1264 | "tokenizer" 1265 | ], 1266 | "time": "2015-09-15 10:49:45" 1267 | }, 1268 | { 1269 | "name": "phpunit/phpunit", 1270 | "version": "4.8.27", 1271 | "source": { 1272 | "type": "git", 1273 | "url": "https://github.com/sebastianbergmann/phpunit.git", 1274 | "reference": "c062dddcb68e44b563f66ee319ddae2b5a322a90" 1275 | }, 1276 | "dist": { 1277 | "type": "zip", 1278 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c062dddcb68e44b563f66ee319ddae2b5a322a90", 1279 | "reference": "c062dddcb68e44b563f66ee319ddae2b5a322a90", 1280 | "shasum": "" 1281 | }, 1282 | "require": { 1283 | "ext-dom": "*", 1284 | "ext-json": "*", 1285 | "ext-pcre": "*", 1286 | "ext-reflection": "*", 1287 | "ext-spl": "*", 1288 | "php": ">=5.3.3", 1289 | "phpspec/prophecy": "^1.3.1", 1290 | "phpunit/php-code-coverage": "~2.1", 1291 | "phpunit/php-file-iterator": "~1.4", 1292 | "phpunit/php-text-template": "~1.2", 1293 | "phpunit/php-timer": "^1.0.6", 1294 | "phpunit/phpunit-mock-objects": "~2.3", 1295 | "sebastian/comparator": "~1.1", 1296 | "sebastian/diff": "~1.2", 1297 | "sebastian/environment": "~1.3", 1298 | "sebastian/exporter": "~1.2", 1299 | "sebastian/global-state": "~1.0", 1300 | "sebastian/version": "~1.0", 1301 | "symfony/yaml": "~2.1|~3.0" 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": "4.8.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-07-21 06:48:14" 1339 | }, 1340 | { 1341 | "name": "phpunit/phpunit-mock-objects", 1342 | "version": "2.3.8", 1343 | "source": { 1344 | "type": "git", 1345 | "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", 1346 | "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983" 1347 | }, 1348 | "dist": { 1349 | "type": "zip", 1350 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983", 1351 | "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983", 1352 | "shasum": "" 1353 | }, 1354 | "require": { 1355 | "doctrine/instantiator": "^1.0.2", 1356 | "php": ">=5.3.3", 1357 | "phpunit/php-text-template": "~1.2", 1358 | "sebastian/exporter": "~1.2" 1359 | }, 1360 | "require-dev": { 1361 | "phpunit/phpunit": "~4.4" 1362 | }, 1363 | "suggest": { 1364 | "ext-soap": "*" 1365 | }, 1366 | "type": "library", 1367 | "extra": { 1368 | "branch-alias": { 1369 | "dev-master": "2.3.x-dev" 1370 | } 1371 | }, 1372 | "autoload": { 1373 | "classmap": [ 1374 | "src/" 1375 | ] 1376 | }, 1377 | "notification-url": "https://packagist.org/downloads/", 1378 | "license": [ 1379 | "BSD-3-Clause" 1380 | ], 1381 | "authors": [ 1382 | { 1383 | "name": "Sebastian Bergmann", 1384 | "email": "sb@sebastian-bergmann.de", 1385 | "role": "lead" 1386 | } 1387 | ], 1388 | "description": "Mock Object library for PHPUnit", 1389 | "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", 1390 | "keywords": [ 1391 | "mock", 1392 | "xunit" 1393 | ], 1394 | "time": "2015-10-02 06:51:40" 1395 | }, 1396 | { 1397 | "name": "psr/http-message", 1398 | "version": "1.0.1", 1399 | "source": { 1400 | "type": "git", 1401 | "url": "https://github.com/php-fig/http-message.git", 1402 | "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" 1403 | }, 1404 | "dist": { 1405 | "type": "zip", 1406 | "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", 1407 | "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", 1408 | "shasum": "" 1409 | }, 1410 | "require": { 1411 | "php": ">=5.3.0" 1412 | }, 1413 | "type": "library", 1414 | "extra": { 1415 | "branch-alias": { 1416 | "dev-master": "1.0.x-dev" 1417 | } 1418 | }, 1419 | "autoload": { 1420 | "psr-4": { 1421 | "Psr\\Http\\Message\\": "src/" 1422 | } 1423 | }, 1424 | "notification-url": "https://packagist.org/downloads/", 1425 | "license": [ 1426 | "MIT" 1427 | ], 1428 | "authors": [ 1429 | { 1430 | "name": "PHP-FIG", 1431 | "homepage": "http://www.php-fig.org/" 1432 | } 1433 | ], 1434 | "description": "Common interface for HTTP messages", 1435 | "homepage": "https://github.com/php-fig/http-message", 1436 | "keywords": [ 1437 | "http", 1438 | "http-message", 1439 | "psr", 1440 | "psr-7", 1441 | "request", 1442 | "response" 1443 | ], 1444 | "time": "2016-08-06 14:39:51" 1445 | }, 1446 | { 1447 | "name": "psr/log", 1448 | "version": "1.0.1", 1449 | "source": { 1450 | "type": "git", 1451 | "url": "https://github.com/php-fig/log.git", 1452 | "reference": "5277094ed527a1c4477177d102fe4c53551953e0" 1453 | }, 1454 | "dist": { 1455 | "type": "zip", 1456 | "url": "https://api.github.com/repos/php-fig/log/zipball/5277094ed527a1c4477177d102fe4c53551953e0", 1457 | "reference": "5277094ed527a1c4477177d102fe4c53551953e0", 1458 | "shasum": "" 1459 | }, 1460 | "require": { 1461 | "php": ">=5.3.0" 1462 | }, 1463 | "type": "library", 1464 | "extra": { 1465 | "branch-alias": { 1466 | "dev-master": "1.0.x-dev" 1467 | } 1468 | }, 1469 | "autoload": { 1470 | "psr-4": { 1471 | "Psr\\Log\\": "Psr/Log/" 1472 | } 1473 | }, 1474 | "notification-url": "https://packagist.org/downloads/", 1475 | "license": [ 1476 | "MIT" 1477 | ], 1478 | "authors": [ 1479 | { 1480 | "name": "PHP-FIG", 1481 | "homepage": "http://www.php-fig.org/" 1482 | } 1483 | ], 1484 | "description": "Common interface for logging libraries", 1485 | "homepage": "https://github.com/php-fig/log", 1486 | "keywords": [ 1487 | "log", 1488 | "psr", 1489 | "psr-3" 1490 | ], 1491 | "time": "2016-09-19 16:02:08" 1492 | }, 1493 | { 1494 | "name": "sebastian/comparator", 1495 | "version": "1.2.0", 1496 | "source": { 1497 | "type": "git", 1498 | "url": "https://github.com/sebastianbergmann/comparator.git", 1499 | "reference": "937efb279bd37a375bcadf584dec0726f84dbf22" 1500 | }, 1501 | "dist": { 1502 | "type": "zip", 1503 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22", 1504 | "reference": "937efb279bd37a375bcadf584dec0726f84dbf22", 1505 | "shasum": "" 1506 | }, 1507 | "require": { 1508 | "php": ">=5.3.3", 1509 | "sebastian/diff": "~1.2", 1510 | "sebastian/exporter": "~1.2" 1511 | }, 1512 | "require-dev": { 1513 | "phpunit/phpunit": "~4.4" 1514 | }, 1515 | "type": "library", 1516 | "extra": { 1517 | "branch-alias": { 1518 | "dev-master": "1.2.x-dev" 1519 | } 1520 | }, 1521 | "autoload": { 1522 | "classmap": [ 1523 | "src/" 1524 | ] 1525 | }, 1526 | "notification-url": "https://packagist.org/downloads/", 1527 | "license": [ 1528 | "BSD-3-Clause" 1529 | ], 1530 | "authors": [ 1531 | { 1532 | "name": "Jeff Welch", 1533 | "email": "whatthejeff@gmail.com" 1534 | }, 1535 | { 1536 | "name": "Volker Dusch", 1537 | "email": "github@wallbash.com" 1538 | }, 1539 | { 1540 | "name": "Bernhard Schussek", 1541 | "email": "bschussek@2bepublished.at" 1542 | }, 1543 | { 1544 | "name": "Sebastian Bergmann", 1545 | "email": "sebastian@phpunit.de" 1546 | } 1547 | ], 1548 | "description": "Provides the functionality to compare PHP values for equality", 1549 | "homepage": "http://www.github.com/sebastianbergmann/comparator", 1550 | "keywords": [ 1551 | "comparator", 1552 | "compare", 1553 | "equality" 1554 | ], 1555 | "time": "2015-07-26 15:48:44" 1556 | }, 1557 | { 1558 | "name": "sebastian/diff", 1559 | "version": "1.4.1", 1560 | "source": { 1561 | "type": "git", 1562 | "url": "https://github.com/sebastianbergmann/diff.git", 1563 | "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e" 1564 | }, 1565 | "dist": { 1566 | "type": "zip", 1567 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e", 1568 | "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e", 1569 | "shasum": "" 1570 | }, 1571 | "require": { 1572 | "php": ">=5.3.3" 1573 | }, 1574 | "require-dev": { 1575 | "phpunit/phpunit": "~4.8" 1576 | }, 1577 | "type": "library", 1578 | "extra": { 1579 | "branch-alias": { 1580 | "dev-master": "1.4-dev" 1581 | } 1582 | }, 1583 | "autoload": { 1584 | "classmap": [ 1585 | "src/" 1586 | ] 1587 | }, 1588 | "notification-url": "https://packagist.org/downloads/", 1589 | "license": [ 1590 | "BSD-3-Clause" 1591 | ], 1592 | "authors": [ 1593 | { 1594 | "name": "Kore Nordmann", 1595 | "email": "mail@kore-nordmann.de" 1596 | }, 1597 | { 1598 | "name": "Sebastian Bergmann", 1599 | "email": "sebastian@phpunit.de" 1600 | } 1601 | ], 1602 | "description": "Diff implementation", 1603 | "homepage": "https://github.com/sebastianbergmann/diff", 1604 | "keywords": [ 1605 | "diff" 1606 | ], 1607 | "time": "2015-12-08 07:14:41" 1608 | }, 1609 | { 1610 | "name": "sebastian/environment", 1611 | "version": "1.3.8", 1612 | "source": { 1613 | "type": "git", 1614 | "url": "https://github.com/sebastianbergmann/environment.git", 1615 | "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea" 1616 | }, 1617 | "dist": { 1618 | "type": "zip", 1619 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea", 1620 | "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea", 1621 | "shasum": "" 1622 | }, 1623 | "require": { 1624 | "php": "^5.3.3 || ^7.0" 1625 | }, 1626 | "require-dev": { 1627 | "phpunit/phpunit": "^4.8 || ^5.0" 1628 | }, 1629 | "type": "library", 1630 | "extra": { 1631 | "branch-alias": { 1632 | "dev-master": "1.3.x-dev" 1633 | } 1634 | }, 1635 | "autoload": { 1636 | "classmap": [ 1637 | "src/" 1638 | ] 1639 | }, 1640 | "notification-url": "https://packagist.org/downloads/", 1641 | "license": [ 1642 | "BSD-3-Clause" 1643 | ], 1644 | "authors": [ 1645 | { 1646 | "name": "Sebastian Bergmann", 1647 | "email": "sebastian@phpunit.de" 1648 | } 1649 | ], 1650 | "description": "Provides functionality to handle HHVM/PHP environments", 1651 | "homepage": "http://www.github.com/sebastianbergmann/environment", 1652 | "keywords": [ 1653 | "Xdebug", 1654 | "environment", 1655 | "hhvm" 1656 | ], 1657 | "time": "2016-08-18 05:49:44" 1658 | }, 1659 | { 1660 | "name": "sebastian/exporter", 1661 | "version": "1.2.2", 1662 | "source": { 1663 | "type": "git", 1664 | "url": "https://github.com/sebastianbergmann/exporter.git", 1665 | "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4" 1666 | }, 1667 | "dist": { 1668 | "type": "zip", 1669 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4", 1670 | "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4", 1671 | "shasum": "" 1672 | }, 1673 | "require": { 1674 | "php": ">=5.3.3", 1675 | "sebastian/recursion-context": "~1.0" 1676 | }, 1677 | "require-dev": { 1678 | "ext-mbstring": "*", 1679 | "phpunit/phpunit": "~4.4" 1680 | }, 1681 | "type": "library", 1682 | "extra": { 1683 | "branch-alias": { 1684 | "dev-master": "1.3.x-dev" 1685 | } 1686 | }, 1687 | "autoload": { 1688 | "classmap": [ 1689 | "src/" 1690 | ] 1691 | }, 1692 | "notification-url": "https://packagist.org/downloads/", 1693 | "license": [ 1694 | "BSD-3-Clause" 1695 | ], 1696 | "authors": [ 1697 | { 1698 | "name": "Jeff Welch", 1699 | "email": "whatthejeff@gmail.com" 1700 | }, 1701 | { 1702 | "name": "Volker Dusch", 1703 | "email": "github@wallbash.com" 1704 | }, 1705 | { 1706 | "name": "Bernhard Schussek", 1707 | "email": "bschussek@2bepublished.at" 1708 | }, 1709 | { 1710 | "name": "Sebastian Bergmann", 1711 | "email": "sebastian@phpunit.de" 1712 | }, 1713 | { 1714 | "name": "Adam Harvey", 1715 | "email": "aharvey@php.net" 1716 | } 1717 | ], 1718 | "description": "Provides the functionality to export PHP variables for visualization", 1719 | "homepage": "http://www.github.com/sebastianbergmann/exporter", 1720 | "keywords": [ 1721 | "export", 1722 | "exporter" 1723 | ], 1724 | "time": "2016-06-17 09:04:28" 1725 | }, 1726 | { 1727 | "name": "sebastian/global-state", 1728 | "version": "1.1.1", 1729 | "source": { 1730 | "type": "git", 1731 | "url": "https://github.com/sebastianbergmann/global-state.git", 1732 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" 1733 | }, 1734 | "dist": { 1735 | "type": "zip", 1736 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", 1737 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", 1738 | "shasum": "" 1739 | }, 1740 | "require": { 1741 | "php": ">=5.3.3" 1742 | }, 1743 | "require-dev": { 1744 | "phpunit/phpunit": "~4.2" 1745 | }, 1746 | "suggest": { 1747 | "ext-uopz": "*" 1748 | }, 1749 | "type": "library", 1750 | "extra": { 1751 | "branch-alias": { 1752 | "dev-master": "1.0-dev" 1753 | } 1754 | }, 1755 | "autoload": { 1756 | "classmap": [ 1757 | "src/" 1758 | ] 1759 | }, 1760 | "notification-url": "https://packagist.org/downloads/", 1761 | "license": [ 1762 | "BSD-3-Clause" 1763 | ], 1764 | "authors": [ 1765 | { 1766 | "name": "Sebastian Bergmann", 1767 | "email": "sebastian@phpunit.de" 1768 | } 1769 | ], 1770 | "description": "Snapshotting of global state", 1771 | "homepage": "http://www.github.com/sebastianbergmann/global-state", 1772 | "keywords": [ 1773 | "global state" 1774 | ], 1775 | "time": "2015-10-12 03:26:01" 1776 | }, 1777 | { 1778 | "name": "sebastian/recursion-context", 1779 | "version": "1.0.2", 1780 | "source": { 1781 | "type": "git", 1782 | "url": "https://github.com/sebastianbergmann/recursion-context.git", 1783 | "reference": "913401df809e99e4f47b27cdd781f4a258d58791" 1784 | }, 1785 | "dist": { 1786 | "type": "zip", 1787 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/913401df809e99e4f47b27cdd781f4a258d58791", 1788 | "reference": "913401df809e99e4f47b27cdd781f4a258d58791", 1789 | "shasum": "" 1790 | }, 1791 | "require": { 1792 | "php": ">=5.3.3" 1793 | }, 1794 | "require-dev": { 1795 | "phpunit/phpunit": "~4.4" 1796 | }, 1797 | "type": "library", 1798 | "extra": { 1799 | "branch-alias": { 1800 | "dev-master": "1.0.x-dev" 1801 | } 1802 | }, 1803 | "autoload": { 1804 | "classmap": [ 1805 | "src/" 1806 | ] 1807 | }, 1808 | "notification-url": "https://packagist.org/downloads/", 1809 | "license": [ 1810 | "BSD-3-Clause" 1811 | ], 1812 | "authors": [ 1813 | { 1814 | "name": "Jeff Welch", 1815 | "email": "whatthejeff@gmail.com" 1816 | }, 1817 | { 1818 | "name": "Sebastian Bergmann", 1819 | "email": "sebastian@phpunit.de" 1820 | }, 1821 | { 1822 | "name": "Adam Harvey", 1823 | "email": "aharvey@php.net" 1824 | } 1825 | ], 1826 | "description": "Provides functionality to recursively process PHP variables", 1827 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context", 1828 | "time": "2015-11-11 19:50:13" 1829 | }, 1830 | { 1831 | "name": "sebastian/version", 1832 | "version": "1.0.6", 1833 | "source": { 1834 | "type": "git", 1835 | "url": "https://github.com/sebastianbergmann/version.git", 1836 | "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" 1837 | }, 1838 | "dist": { 1839 | "type": "zip", 1840 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", 1841 | "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", 1842 | "shasum": "" 1843 | }, 1844 | "type": "library", 1845 | "autoload": { 1846 | "classmap": [ 1847 | "src/" 1848 | ] 1849 | }, 1850 | "notification-url": "https://packagist.org/downloads/", 1851 | "license": [ 1852 | "BSD-3-Clause" 1853 | ], 1854 | "authors": [ 1855 | { 1856 | "name": "Sebastian Bergmann", 1857 | "email": "sebastian@phpunit.de", 1858 | "role": "lead" 1859 | } 1860 | ], 1861 | "description": "Library that helps with managing the version number of Git-hosted PHP projects", 1862 | "homepage": "https://github.com/sebastianbergmann/version", 1863 | "time": "2015-06-21 13:59:46" 1864 | }, 1865 | { 1866 | "name": "symfony/browser-kit", 1867 | "version": "v3.1.5", 1868 | "source": { 1869 | "type": "git", 1870 | "url": "https://github.com/symfony/browser-kit.git", 1871 | "reference": "901319a31c9b3cee7857b4aeeb81b5d64dfa34fc" 1872 | }, 1873 | "dist": { 1874 | "type": "zip", 1875 | "url": "https://api.github.com/repos/symfony/browser-kit/zipball/901319a31c9b3cee7857b4aeeb81b5d64dfa34fc", 1876 | "reference": "901319a31c9b3cee7857b4aeeb81b5d64dfa34fc", 1877 | "shasum": "" 1878 | }, 1879 | "require": { 1880 | "php": ">=5.5.9", 1881 | "symfony/dom-crawler": "~2.8|~3.0" 1882 | }, 1883 | "require-dev": { 1884 | "symfony/css-selector": "~2.8|~3.0", 1885 | "symfony/process": "~2.8|~3.0" 1886 | }, 1887 | "suggest": { 1888 | "symfony/process": "" 1889 | }, 1890 | "type": "library", 1891 | "extra": { 1892 | "branch-alias": { 1893 | "dev-master": "3.1-dev" 1894 | } 1895 | }, 1896 | "autoload": { 1897 | "psr-4": { 1898 | "Symfony\\Component\\BrowserKit\\": "" 1899 | }, 1900 | "exclude-from-classmap": [ 1901 | "/Tests/" 1902 | ] 1903 | }, 1904 | "notification-url": "https://packagist.org/downloads/", 1905 | "license": [ 1906 | "MIT" 1907 | ], 1908 | "authors": [ 1909 | { 1910 | "name": "Fabien Potencier", 1911 | "email": "fabien@symfony.com" 1912 | }, 1913 | { 1914 | "name": "Symfony Community", 1915 | "homepage": "https://symfony.com/contributors" 1916 | } 1917 | ], 1918 | "description": "Symfony BrowserKit Component", 1919 | "homepage": "https://symfony.com", 1920 | "time": "2016-09-06 11:02:40" 1921 | }, 1922 | { 1923 | "name": "symfony/console", 1924 | "version": "v3.1.5", 1925 | "source": { 1926 | "type": "git", 1927 | "url": "https://github.com/symfony/console.git", 1928 | "reference": "6cb0872fb57b38b3b09ff213c21ed693956b9eb0" 1929 | }, 1930 | "dist": { 1931 | "type": "zip", 1932 | "url": "https://api.github.com/repos/symfony/console/zipball/6cb0872fb57b38b3b09ff213c21ed693956b9eb0", 1933 | "reference": "6cb0872fb57b38b3b09ff213c21ed693956b9eb0", 1934 | "shasum": "" 1935 | }, 1936 | "require": { 1937 | "php": ">=5.5.9", 1938 | "symfony/debug": "~2.8|~3.0", 1939 | "symfony/polyfill-mbstring": "~1.0" 1940 | }, 1941 | "require-dev": { 1942 | "psr/log": "~1.0", 1943 | "symfony/event-dispatcher": "~2.8|~3.0", 1944 | "symfony/process": "~2.8|~3.0" 1945 | }, 1946 | "suggest": { 1947 | "psr/log": "For using the console logger", 1948 | "symfony/event-dispatcher": "", 1949 | "symfony/process": "" 1950 | }, 1951 | "type": "library", 1952 | "extra": { 1953 | "branch-alias": { 1954 | "dev-master": "3.1-dev" 1955 | } 1956 | }, 1957 | "autoload": { 1958 | "psr-4": { 1959 | "Symfony\\Component\\Console\\": "" 1960 | }, 1961 | "exclude-from-classmap": [ 1962 | "/Tests/" 1963 | ] 1964 | }, 1965 | "notification-url": "https://packagist.org/downloads/", 1966 | "license": [ 1967 | "MIT" 1968 | ], 1969 | "authors": [ 1970 | { 1971 | "name": "Fabien Potencier", 1972 | "email": "fabien@symfony.com" 1973 | }, 1974 | { 1975 | "name": "Symfony Community", 1976 | "homepage": "https://symfony.com/contributors" 1977 | } 1978 | ], 1979 | "description": "Symfony Console Component", 1980 | "homepage": "https://symfony.com", 1981 | "time": "2016-09-28 00:11:12" 1982 | }, 1983 | { 1984 | "name": "symfony/css-selector", 1985 | "version": "v3.1.5", 1986 | "source": { 1987 | "type": "git", 1988 | "url": "https://github.com/symfony/css-selector.git", 1989 | "reference": "ca809c64072e0fe61c1c7fb3c76cdc32265042ac" 1990 | }, 1991 | "dist": { 1992 | "type": "zip", 1993 | "url": "https://api.github.com/repos/symfony/css-selector/zipball/ca809c64072e0fe61c1c7fb3c76cdc32265042ac", 1994 | "reference": "ca809c64072e0fe61c1c7fb3c76cdc32265042ac", 1995 | "shasum": "" 1996 | }, 1997 | "require": { 1998 | "php": ">=5.5.9" 1999 | }, 2000 | "type": "library", 2001 | "extra": { 2002 | "branch-alias": { 2003 | "dev-master": "3.1-dev" 2004 | } 2005 | }, 2006 | "autoload": { 2007 | "psr-4": { 2008 | "Symfony\\Component\\CssSelector\\": "" 2009 | }, 2010 | "exclude-from-classmap": [ 2011 | "/Tests/" 2012 | ] 2013 | }, 2014 | "notification-url": "https://packagist.org/downloads/", 2015 | "license": [ 2016 | "MIT" 2017 | ], 2018 | "authors": [ 2019 | { 2020 | "name": "Jean-François Simon", 2021 | "email": "jeanfrancois.simon@sensiolabs.com" 2022 | }, 2023 | { 2024 | "name": "Fabien Potencier", 2025 | "email": "fabien@symfony.com" 2026 | }, 2027 | { 2028 | "name": "Symfony Community", 2029 | "homepage": "https://symfony.com/contributors" 2030 | } 2031 | ], 2032 | "description": "Symfony CssSelector Component", 2033 | "homepage": "https://symfony.com", 2034 | "time": "2016-09-06 11:02:40" 2035 | }, 2036 | { 2037 | "name": "symfony/debug", 2038 | "version": "v3.1.5", 2039 | "source": { 2040 | "type": "git", 2041 | "url": "https://github.com/symfony/debug.git", 2042 | "reference": "e2b3f74a67fc928adc3c1b9027f73e1bc01190a8" 2043 | }, 2044 | "dist": { 2045 | "type": "zip", 2046 | "url": "https://api.github.com/repos/symfony/debug/zipball/e2b3f74a67fc928adc3c1b9027f73e1bc01190a8", 2047 | "reference": "e2b3f74a67fc928adc3c1b9027f73e1bc01190a8", 2048 | "shasum": "" 2049 | }, 2050 | "require": { 2051 | "php": ">=5.5.9", 2052 | "psr/log": "~1.0" 2053 | }, 2054 | "conflict": { 2055 | "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" 2056 | }, 2057 | "require-dev": { 2058 | "symfony/class-loader": "~2.8|~3.0", 2059 | "symfony/http-kernel": "~2.8|~3.0" 2060 | }, 2061 | "type": "library", 2062 | "extra": { 2063 | "branch-alias": { 2064 | "dev-master": "3.1-dev" 2065 | } 2066 | }, 2067 | "autoload": { 2068 | "psr-4": { 2069 | "Symfony\\Component\\Debug\\": "" 2070 | }, 2071 | "exclude-from-classmap": [ 2072 | "/Tests/" 2073 | ] 2074 | }, 2075 | "notification-url": "https://packagist.org/downloads/", 2076 | "license": [ 2077 | "MIT" 2078 | ], 2079 | "authors": [ 2080 | { 2081 | "name": "Fabien Potencier", 2082 | "email": "fabien@symfony.com" 2083 | }, 2084 | { 2085 | "name": "Symfony Community", 2086 | "homepage": "https://symfony.com/contributors" 2087 | } 2088 | ], 2089 | "description": "Symfony Debug Component", 2090 | "homepage": "https://symfony.com", 2091 | "time": "2016-09-06 11:02:40" 2092 | }, 2093 | { 2094 | "name": "symfony/dom-crawler", 2095 | "version": "v3.1.5", 2096 | "source": { 2097 | "type": "git", 2098 | "url": "https://github.com/symfony/dom-crawler.git", 2099 | "reference": "bb7395e8b1db3654de82b9f35d019958276de4d7" 2100 | }, 2101 | "dist": { 2102 | "type": "zip", 2103 | "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/bb7395e8b1db3654de82b9f35d019958276de4d7", 2104 | "reference": "bb7395e8b1db3654de82b9f35d019958276de4d7", 2105 | "shasum": "" 2106 | }, 2107 | "require": { 2108 | "php": ">=5.5.9", 2109 | "symfony/polyfill-mbstring": "~1.0" 2110 | }, 2111 | "require-dev": { 2112 | "symfony/css-selector": "~2.8|~3.0" 2113 | }, 2114 | "suggest": { 2115 | "symfony/css-selector": "" 2116 | }, 2117 | "type": "library", 2118 | "extra": { 2119 | "branch-alias": { 2120 | "dev-master": "3.1-dev" 2121 | } 2122 | }, 2123 | "autoload": { 2124 | "psr-4": { 2125 | "Symfony\\Component\\DomCrawler\\": "" 2126 | }, 2127 | "exclude-from-classmap": [ 2128 | "/Tests/" 2129 | ] 2130 | }, 2131 | "notification-url": "https://packagist.org/downloads/", 2132 | "license": [ 2133 | "MIT" 2134 | ], 2135 | "authors": [ 2136 | { 2137 | "name": "Fabien Potencier", 2138 | "email": "fabien@symfony.com" 2139 | }, 2140 | { 2141 | "name": "Symfony Community", 2142 | "homepage": "https://symfony.com/contributors" 2143 | } 2144 | ], 2145 | "description": "Symfony DomCrawler Component", 2146 | "homepage": "https://symfony.com", 2147 | "time": "2016-08-05 08:37:39" 2148 | }, 2149 | { 2150 | "name": "symfony/event-dispatcher", 2151 | "version": "v3.1.5", 2152 | "source": { 2153 | "type": "git", 2154 | "url": "https://github.com/symfony/event-dispatcher.git", 2155 | "reference": "c0c00c80b3a69132c4e55c3e7db32b4a387615e5" 2156 | }, 2157 | "dist": { 2158 | "type": "zip", 2159 | "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/c0c00c80b3a69132c4e55c3e7db32b4a387615e5", 2160 | "reference": "c0c00c80b3a69132c4e55c3e7db32b4a387615e5", 2161 | "shasum": "" 2162 | }, 2163 | "require": { 2164 | "php": ">=5.5.9" 2165 | }, 2166 | "require-dev": { 2167 | "psr/log": "~1.0", 2168 | "symfony/config": "~2.8|~3.0", 2169 | "symfony/dependency-injection": "~2.8|~3.0", 2170 | "symfony/expression-language": "~2.8|~3.0", 2171 | "symfony/stopwatch": "~2.8|~3.0" 2172 | }, 2173 | "suggest": { 2174 | "symfony/dependency-injection": "", 2175 | "symfony/http-kernel": "" 2176 | }, 2177 | "type": "library", 2178 | "extra": { 2179 | "branch-alias": { 2180 | "dev-master": "3.1-dev" 2181 | } 2182 | }, 2183 | "autoload": { 2184 | "psr-4": { 2185 | "Symfony\\Component\\EventDispatcher\\": "" 2186 | }, 2187 | "exclude-from-classmap": [ 2188 | "/Tests/" 2189 | ] 2190 | }, 2191 | "notification-url": "https://packagist.org/downloads/", 2192 | "license": [ 2193 | "MIT" 2194 | ], 2195 | "authors": [ 2196 | { 2197 | "name": "Fabien Potencier", 2198 | "email": "fabien@symfony.com" 2199 | }, 2200 | { 2201 | "name": "Symfony Community", 2202 | "homepage": "https://symfony.com/contributors" 2203 | } 2204 | ], 2205 | "description": "Symfony EventDispatcher Component", 2206 | "homepage": "https://symfony.com", 2207 | "time": "2016-07-19 10:45:57" 2208 | }, 2209 | { 2210 | "name": "symfony/finder", 2211 | "version": "v3.1.5", 2212 | "source": { 2213 | "type": "git", 2214 | "url": "https://github.com/symfony/finder.git", 2215 | "reference": "205b5ffbb518a98ba2ae60a52656c4a31ab00c6f" 2216 | }, 2217 | "dist": { 2218 | "type": "zip", 2219 | "url": "https://api.github.com/repos/symfony/finder/zipball/205b5ffbb518a98ba2ae60a52656c4a31ab00c6f", 2220 | "reference": "205b5ffbb518a98ba2ae60a52656c4a31ab00c6f", 2221 | "shasum": "" 2222 | }, 2223 | "require": { 2224 | "php": ">=5.5.9" 2225 | }, 2226 | "type": "library", 2227 | "extra": { 2228 | "branch-alias": { 2229 | "dev-master": "3.1-dev" 2230 | } 2231 | }, 2232 | "autoload": { 2233 | "psr-4": { 2234 | "Symfony\\Component\\Finder\\": "" 2235 | }, 2236 | "exclude-from-classmap": [ 2237 | "/Tests/" 2238 | ] 2239 | }, 2240 | "notification-url": "https://packagist.org/downloads/", 2241 | "license": [ 2242 | "MIT" 2243 | ], 2244 | "authors": [ 2245 | { 2246 | "name": "Fabien Potencier", 2247 | "email": "fabien@symfony.com" 2248 | }, 2249 | { 2250 | "name": "Symfony Community", 2251 | "homepage": "https://symfony.com/contributors" 2252 | } 2253 | ], 2254 | "description": "Symfony Finder Component", 2255 | "homepage": "https://symfony.com", 2256 | "time": "2016-09-28 00:11:12" 2257 | }, 2258 | { 2259 | "name": "symfony/polyfill-mbstring", 2260 | "version": "v1.2.0", 2261 | "source": { 2262 | "type": "git", 2263 | "url": "https://github.com/symfony/polyfill-mbstring.git", 2264 | "reference": "dff51f72b0706335131b00a7f49606168c582594" 2265 | }, 2266 | "dist": { 2267 | "type": "zip", 2268 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/dff51f72b0706335131b00a7f49606168c582594", 2269 | "reference": "dff51f72b0706335131b00a7f49606168c582594", 2270 | "shasum": "" 2271 | }, 2272 | "require": { 2273 | "php": ">=5.3.3" 2274 | }, 2275 | "suggest": { 2276 | "ext-mbstring": "For best performance" 2277 | }, 2278 | "type": "library", 2279 | "extra": { 2280 | "branch-alias": { 2281 | "dev-master": "1.2-dev" 2282 | } 2283 | }, 2284 | "autoload": { 2285 | "psr-4": { 2286 | "Symfony\\Polyfill\\Mbstring\\": "" 2287 | }, 2288 | "files": [ 2289 | "bootstrap.php" 2290 | ] 2291 | }, 2292 | "notification-url": "https://packagist.org/downloads/", 2293 | "license": [ 2294 | "MIT" 2295 | ], 2296 | "authors": [ 2297 | { 2298 | "name": "Nicolas Grekas", 2299 | "email": "p@tchwork.com" 2300 | }, 2301 | { 2302 | "name": "Symfony Community", 2303 | "homepage": "https://symfony.com/contributors" 2304 | } 2305 | ], 2306 | "description": "Symfony polyfill for the Mbstring extension", 2307 | "homepage": "https://symfony.com", 2308 | "keywords": [ 2309 | "compatibility", 2310 | "mbstring", 2311 | "polyfill", 2312 | "portable", 2313 | "shim" 2314 | ], 2315 | "time": "2016-05-18 14:26:46" 2316 | }, 2317 | { 2318 | "name": "symfony/yaml", 2319 | "version": "v3.1.5", 2320 | "source": { 2321 | "type": "git", 2322 | "url": "https://github.com/symfony/yaml.git", 2323 | "reference": "368b9738d4033c8b93454cb0dbd45d305135a6d3" 2324 | }, 2325 | "dist": { 2326 | "type": "zip", 2327 | "url": "https://api.github.com/repos/symfony/yaml/zipball/368b9738d4033c8b93454cb0dbd45d305135a6d3", 2328 | "reference": "368b9738d4033c8b93454cb0dbd45d305135a6d3", 2329 | "shasum": "" 2330 | }, 2331 | "require": { 2332 | "php": ">=5.5.9" 2333 | }, 2334 | "type": "library", 2335 | "extra": { 2336 | "branch-alias": { 2337 | "dev-master": "3.1-dev" 2338 | } 2339 | }, 2340 | "autoload": { 2341 | "psr-4": { 2342 | "Symfony\\Component\\Yaml\\": "" 2343 | }, 2344 | "exclude-from-classmap": [ 2345 | "/Tests/" 2346 | ] 2347 | }, 2348 | "notification-url": "https://packagist.org/downloads/", 2349 | "license": [ 2350 | "MIT" 2351 | ], 2352 | "authors": [ 2353 | { 2354 | "name": "Fabien Potencier", 2355 | "email": "fabien@symfony.com" 2356 | }, 2357 | { 2358 | "name": "Symfony Community", 2359 | "homepage": "https://symfony.com/contributors" 2360 | } 2361 | ], 2362 | "description": "Symfony Yaml Component", 2363 | "homepage": "https://symfony.com", 2364 | "time": "2016-09-25 08:27:07" 2365 | }, 2366 | { 2367 | "name": "webmozart/assert", 2368 | "version": "1.1.0", 2369 | "source": { 2370 | "type": "git", 2371 | "url": "https://github.com/webmozart/assert.git", 2372 | "reference": "bb2d123231c095735130cc8f6d31385a44c7b308" 2373 | }, 2374 | "dist": { 2375 | "type": "zip", 2376 | "url": "https://api.github.com/repos/webmozart/assert/zipball/bb2d123231c095735130cc8f6d31385a44c7b308", 2377 | "reference": "bb2d123231c095735130cc8f6d31385a44c7b308", 2378 | "shasum": "" 2379 | }, 2380 | "require": { 2381 | "php": "^5.3.3|^7.0" 2382 | }, 2383 | "require-dev": { 2384 | "phpunit/phpunit": "^4.6", 2385 | "sebastian/version": "^1.0.1" 2386 | }, 2387 | "type": "library", 2388 | "extra": { 2389 | "branch-alias": { 2390 | "dev-master": "1.2-dev" 2391 | } 2392 | }, 2393 | "autoload": { 2394 | "psr-4": { 2395 | "Webmozart\\Assert\\": "src/" 2396 | } 2397 | }, 2398 | "notification-url": "https://packagist.org/downloads/", 2399 | "license": [ 2400 | "MIT" 2401 | ], 2402 | "authors": [ 2403 | { 2404 | "name": "Bernhard Schussek", 2405 | "email": "bschussek@gmail.com" 2406 | } 2407 | ], 2408 | "description": "Assertions to validate method input/output with nice error messages.", 2409 | "keywords": [ 2410 | "assert", 2411 | "check", 2412 | "validate" 2413 | ], 2414 | "time": "2016-08-09 15:02:57" 2415 | }, 2416 | { 2417 | "name": "yiisoft/yii2-codeception", 2418 | "version": "2.0.5", 2419 | "source": { 2420 | "type": "git", 2421 | "url": "https://github.com/yiisoft/yii2-codeception.git", 2422 | "reference": "c916a36d09fc128b05a374e7922bc56854334d56" 2423 | }, 2424 | "dist": { 2425 | "type": "zip", 2426 | "url": "https://api.github.com/repos/yiisoft/yii2-codeception/zipball/c916a36d09fc128b05a374e7922bc56854334d56", 2427 | "reference": "c916a36d09fc128b05a374e7922bc56854334d56", 2428 | "shasum": "" 2429 | }, 2430 | "require": { 2431 | "yiisoft/yii2": ">=2.0.4" 2432 | }, 2433 | "type": "yii2-extension", 2434 | "extra": { 2435 | "branch-alias": { 2436 | "dev-master": "2.0.x-dev" 2437 | } 2438 | }, 2439 | "autoload": { 2440 | "psr-4": { 2441 | "yii\\codeception\\": "" 2442 | } 2443 | }, 2444 | "notification-url": "https://packagist.org/downloads/", 2445 | "license": [ 2446 | "BSD-3-Clause" 2447 | ], 2448 | "authors": [ 2449 | { 2450 | "name": "Mark Jebri", 2451 | "email": "mark.github@yandex.ru" 2452 | } 2453 | ], 2454 | "description": "The Codeception integration for the Yii framework", 2455 | "keywords": [ 2456 | "codeception", 2457 | "yii2" 2458 | ], 2459 | "time": "2016-03-17 03:41:26" 2460 | } 2461 | ], 2462 | "aliases": [], 2463 | "minimum-stability": "stable", 2464 | "stability-flags": [], 2465 | "prefer-stable": false, 2466 | "prefer-lowest": false, 2467 | "platform": { 2468 | "php": ">=5.4.0" 2469 | }, 2470 | "platform-dev": [] 2471 | } 2472 | -------------------------------------------------------------------------------- /docs/ru/README.md: -------------------------------------------------------------------------------- 1 | Yii2 mappable ActiveRecord 2 | ========================== 3 | 4 | Это расширение для Yii framework 2 которое дает возможность использовать паттерн `IdentityMap` для любой модели `ActiveRecord`. 5 | 6 | Как это работает 7 | ---------------- 8 | 9 | `ActiveRecordTrait` переопределяет метод `find` модели. Этот метод создает свой собственный `ActiveQuery`. В последствии при вызове метода `one` (`all`) полученная модель (модели) сохраняются в `identityMap` в виде массива атрибутов (это экономит память). При последующих запросах, данные возвращаются без обращения к базе данных. 10 | 11 | Кроме этого, доступны следующие методы: 12 | 13 | - `getById(integer $id, boolean $asArray = false)` - получить модель или массив атрибутов (зависит от значения второго параметра) по первичному ключу; 14 | - `getByAttribute(string $attribute, string $value, boolean $asArray = false)` - получить модель или массив атрибутов (зависит от значения второго параметра) по значению уникального атрибута; 15 | - `getMap()` - получить все полученные модели из `identityMap` в виде массива атрибутов; 16 | - `clearMap()` - очистить `identityMap`. 17 | 18 | Установка 19 | --------- 20 | 21 | Предпочтительным вариантом установки является [composer](http://getcomposer.org/download/). 22 | 23 | Просто выполните команду 24 | 25 | ``` 26 | composer require --prefer-dist yiister/yii2-mappable-ar 27 | ``` 28 | 29 | или добавьте 30 | 31 | ```json 32 | "yiister/yii2-mappable-ar": "~1.0.0" 33 | ``` 34 | 35 | в секцию `require` вашего файла composer.json. 36 | 37 | Настройка 38 | --------- 39 | 40 | Расщирение поддерживает следующие настройки: 41 | 42 | - `idAttribute` - атрибут первичного ключа (по умолчанию `id`); 43 | - `identityMapMaxSize` - максимальное количество элементов в identityMap (по умолчанию `-1` = без ограничений); 44 | - `uniqueAttributes` - массив названии аттирутов, которые содержат уникальные значения. Используется в методе `getByAttribute`. 45 | 46 | Например, для изменения поля первичного ключа на `key` достаточно указать в вашей модели `public static $idAttribute = 'key';`. 47 | 48 | Использование 49 | ------------- 50 | 51 | Для использования расширения достаточно указать для модели `use yiister\mappable\ActiveRecordTrait;`. После этого вам станут доступны все описанные возможности. 52 | 53 | **Важно!** Если у вас переопределен метод `find`, то необходимо вызвать метод `activeRecordTraitFind()` и работать с его результатом. 54 | 55 | Пример: 56 | 57 | ```php 58 | public static function find() 59 | { 60 | $query = static::activeRecordTraitFind(); 61 | // манипуляции с query 62 | return $query; 63 | } 64 | ``` 65 | -------------------------------------------------------------------------------- /src/ActiveQuery.php: -------------------------------------------------------------------------------- 1 | select === null && $this->sql === null; 26 | } 27 | 28 | /** 29 | * @inheritdoc 30 | */ 31 | public function one($db = null) 32 | { 33 | $row = parent::one($db); 34 | if ($row !== null && $this->isMappableQuery()) { 35 | /** @var ActiveRecord|ActiveRecordTrait $className */ 36 | $className = $this->modelClass; 37 | $className::addRowToMap($row); 38 | } 39 | return $row; 40 | } 41 | 42 | /** 43 | * @inheritdoc 44 | */ 45 | public function all($db = null) 46 | { 47 | $rows = parent::all($db); 48 | if (count($rows) > 0 && $this->isMappableQuery()) { 49 | /** @var ActiveRecord|ActiveRecordTrait $className */ 50 | $className = $this->modelClass; 51 | $className::addRowsToMap($rows); 52 | } 53 | return $rows; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/ActiveRecordTrait.php: -------------------------------------------------------------------------------- 1 | where(['id' => 1])->one(); 78 | * 79 | * // find all active customers and order them by their age: 80 | * $customers = Customer::find() 81 | * ->where(['status' => 1]) 82 | * ->orderBy('age') 83 | * ->all(); 84 | * ``` 85 | * 86 | * This method is also called by [[BaseActiveRecord::hasOne()]] and [[BaseActiveRecord::hasMany()]] to 87 | * create a relational query. 88 | * 89 | * You may override this method to return a customized query. For example, 90 | * 91 | * ```php 92 | * class Customer extends ActiveRecord 93 | * { 94 | * public static function find() 95 | * { 96 | * // use CustomerQuery instead of the default ActiveQuery 97 | * return new CustomerQuery(get_called_class()); 98 | * } 99 | * } 100 | * ``` 101 | * 102 | * The following code shows how to apply a default condition for all queries: 103 | * 104 | * ```php 105 | * class Customer extends ActiveRecord 106 | * { 107 | * public static function find() 108 | * { 109 | * return parent::find()->where(['deleted' => false]); 110 | * } 111 | * } 112 | * 113 | * // Use andWhere()/orWhere() to apply the default condition 114 | * // SELECT FROM customer WHERE `deleted`=:deleted AND age>30 115 | * $customers = Customer::find()->andWhere('age>30')->all(); 116 | * 117 | * // Use where() to ignore the default condition 118 | * // SELECT FROM customer WHERE age>30 119 | * $customers = Customer::find()->where('age>30')->all(); 120 | * 121 | * @return ActiveQuery the newly created [[ActiveQuery]] instance. 122 | */ 123 | public static function find() 124 | { 125 | return static::activeRecordTraitFind(); 126 | } 127 | 128 | /** 129 | * Saves the current record. 130 | * 131 | * This method will call [[insert()]] when [[isNewRecord]] is true, or [[update()]] 132 | * when [[isNewRecord]] is false. 133 | * 134 | * For example, to save a customer record: 135 | * 136 | * ```php 137 | * $customer = new Customer; // or $customer = Customer::findOne($id); 138 | * $customer->name = $name; 139 | * $customer->email = $email; 140 | * $customer->save(); 141 | * ``` 142 | * 143 | * @param boolean $runValidation whether to perform validation (calling [[validate()]]) 144 | * before saving the record. Defaults to `true`. If the validation fails, the record 145 | * will not be saved to the database and this method will return `false`. 146 | * @param array $attributeNames list of attribute names that need to be saved. Defaults to null, 147 | * meaning all attributes that are loaded from DB will be saved. 148 | * @return boolean whether the saving succeeded (i.e. no validation errors occurred). 149 | */ 150 | public function save($runValidation = true, $attributeNames = null) 151 | { 152 | if (parent::save($runValidation, $attributeNames) === false) { 153 | return false; 154 | } 155 | static::addRowToMap($this); 156 | return true; 157 | } 158 | 159 | /** 160 | * Add a one row to identity map 161 | * @param ActiveRecord | array $row 162 | */ 163 | public static function addRowToMap($row) 164 | { 165 | $id = static::getIdAttribute(); 166 | if ($row !== null && isset($row[$id])) { 167 | self::$identityMap[$row[$id]] = $row instanceof ActiveRecord ? $row->toArray() : $row; 168 | $maxSize = static::getIdentityMapMaxSize(); 169 | foreach (static::getUniqueAttributes() as $uniqueAttribute) { 170 | self::$uniqueAttributeToId[$uniqueAttribute][$row[$uniqueAttribute]] = $row[$id]; 171 | } 172 | if ($maxSize !== -1 && count(self::$identityMap) > $maxSize) { 173 | array_shift(self::$identityMap); 174 | } 175 | } 176 | } 177 | 178 | /** 179 | * Add rows to identity map 180 | * @param ActiveRecord[]|array[] $rows 181 | */ 182 | public static function addRowsToMap($rows) 183 | { 184 | $firstRow = reset($rows); 185 | $idAttribute = static::getIdAttribute(); 186 | if ($firstRow instanceof ActiveRecord) { 187 | foreach ($rows as $row) { 188 | self::$identityMap[$row[$idAttribute]] = $row->toArray(); 189 | foreach (static::getUniqueAttributes() as $uniqueAttribute) { 190 | self::$uniqueAttributeToId[$uniqueAttribute][$row[$uniqueAttribute]] = $row[$idAttribute]; 191 | } 192 | } 193 | } else { 194 | foreach ($rows as $row) { 195 | self::$identityMap[$row[$idAttribute]] = $row; 196 | foreach (static::getUniqueAttributes() as $uniqueAttribute) { 197 | self::$uniqueAttributeToId[$uniqueAttribute][$row[$uniqueAttribute]] = $row[$idAttribute]; 198 | } 199 | } 200 | } 201 | $maxSize = self::getIdentityMapMaxSize(); 202 | if ($maxSize !== -1) { 203 | $count = count(self::$identityMap); 204 | if ($count > $maxSize) { 205 | self::$identityMap = array_slice( 206 | self::$identityMap, 207 | $count - $maxSize, 208 | $maxSize 209 | ); 210 | } 211 | } 212 | } 213 | 214 | /** 215 | * Get a single record by id 216 | * @param string|int $id 217 | * @param bool $asArray Return a result as array 218 | * @return array|null|ActiveRecord 219 | */ 220 | public static function getById($id, $asArray = false) 221 | { 222 | if (isset(self::$identityMap[$id])) { 223 | if (self::getIdentityMapMaxSize() !== -1) { 224 | $row = self::$identityMap[$id]; 225 | unset(self::$identityMap[$id]); 226 | self::$identityMap[$id] = $row; 227 | } 228 | if ($asArray) { 229 | return self::$identityMap[$id]; 230 | } else { 231 | $model = new static; 232 | /** @var ActiveRecord $modelClass */ 233 | $modelClass = get_class($model); 234 | $modelClass::populateRecord($model, self::$identityMap[$id]); 235 | return $model; 236 | } 237 | } else { 238 | $row = static::find() 239 | ->where([static::getIdAttribute() => $id]) 240 | ->asArray($asArray) 241 | ->one(); 242 | static::addRowToMap($row); 243 | return $row; 244 | } 245 | } 246 | 247 | /** 248 | * Get a single record by unique attribute 249 | * @param string $attribute 250 | * @param mixed $value 251 | * @param bool $asArray 252 | * @return array|null|ActiveRecord 253 | */ 254 | public static function getByAttribute($attribute, $value, $asArray = false) 255 | { 256 | if (isset(self::$uniqueAttributeToId[$attribute][$value])) { 257 | return static::getById(self::$uniqueAttributeToId[$attribute][$value], $asArray); 258 | } 259 | $row = static::find() 260 | ->where([$attribute => $value]) 261 | ->asArray($asArray) 262 | ->one(); 263 | static::addRowToMap($row); 264 | return $row; 265 | } 266 | 267 | /** 268 | * Get a current identity map array 269 | * @return array 270 | */ 271 | public static function getMap() 272 | { 273 | return self::$identityMap; 274 | } 275 | 276 | /** 277 | * Clear an identity map array 278 | */ 279 | public static function clearMap() 280 | { 281 | self::$identityMap = []; 282 | self::$uniqueAttributeToId = []; 283 | } 284 | } 285 | -------------------------------------------------------------------------------- /tests/.gitignore: -------------------------------------------------------------------------------- 1 | /_support/* -------------------------------------------------------------------------------- /tests/_bootstrap.php: -------------------------------------------------------------------------------- 1 | 100], 38 | [['value', 'description'], 'string', 'max' => 255] 39 | ]; 40 | } 41 | 42 | /** 43 | * @inheritdoc 44 | */ 45 | public function attributeLabels() 46 | { 47 | return [ 48 | 'id' => 'ID', 49 | 'key' => 'Key', 50 | 'value' => 'Value', 51 | 'description' => 'Description', 52 | ]; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /tests/_data/Config2.php: -------------------------------------------------------------------------------- 1 | 100], 42 | [['value', 'description'], 'string', 'max' => 255] 43 | ]; 44 | } 45 | 46 | /** 47 | * @inheritdoc 48 | */ 49 | public function attributeLabels() 50 | { 51 | return [ 52 | 'id' => 'ID', 53 | 'key' => 'Key', 54 | 'value' => 'Value', 55 | 'description' => 'Description', 56 | ]; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /tests/_data/dump.sql: -------------------------------------------------------------------------------- 1 | BEGIN TRANSACTION; 2 | CREATE TABLE "config" ( 3 | `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 4 | `key` VARCHAR(100) NOT NULL, 5 | `value` VARCHAR(255) NOT NULL, 6 | `description` VARCHAR(255) DEFAULT NULL 7 | ); 8 | 9 | INSERT INTO `config` (`id`, `key`, `value`, `description`) VALUES 10 | (1, 'email.username', 'test@example.com', NULL), 11 | (2, 'email.password', 'qwerty123', NULL), 12 | (3, 'email.smtp_port', '465', NULL), 13 | (4, 'email.smtp_address', 'smtp.example.com', NULL), 14 | (5, 'email.smtp_encryption', 'ssl', NULL); 15 | COMMIT; -------------------------------------------------------------------------------- /tests/unit.suite.yml: -------------------------------------------------------------------------------- 1 | # Codeception Test Suite Configuration 2 | # 3 | # Suite for unit (internal) tests. 4 | 5 | class_name: UnitTester 6 | modules: 7 | enabled: 8 | - Asserts 9 | - Db -------------------------------------------------------------------------------- /tests/unit/MappableARTest.php: -------------------------------------------------------------------------------- 1 | markTestSkipped('I have not a logger'); 16 | } 17 | return $logger->getDbProfiling()[0]; 18 | } 19 | 20 | protected function setUp() 21 | { 22 | Config::clearMap(); 23 | parent::setUp(); 24 | } 25 | 26 | public function testCleanMap() 27 | { 28 | $this->assertEquals(count(Config::getMap()), 0, 'No item in map'); 29 | } 30 | 31 | public function testGetById() 32 | { 33 | $model = Config::getById(1); 34 | $this->assertTrue($model !== null, 'Item found'); 35 | $this->assertTrue($model instanceof ActiveRecord, 'Item instance of ActiveRecord'); 36 | $this->assertEquals(count(Config::getMap()), 1, '1 item in map'); 37 | $row = Config::getById(2, true); 38 | $queriesCount = $this->getQueryCount(); 39 | $this->assertTrue(is_array($row), 'Item is array'); 40 | $this->assertEquals(count(Config::getMap()), 2, '2 items in map'); 41 | $modelArray = Config::getById(1, true); 42 | $this->assertSame($model->attributes, $modelArray); 43 | $this->assertSame($queriesCount, $this->getQueryCount()); 44 | } 45 | 46 | public function testGetAll() 47 | { 48 | $models = Config::find()->asArray(true)->all(); 49 | $this->assertEquals(count($models), 5, '5 items in map'); 50 | $this->assertEquals(count(Config::getMap()), 5, '5 items in map'); 51 | Config::clearMap(); 52 | $this->assertEquals(count(Config::getMap()), 0, '0 items in map'); 53 | } 54 | 55 | public function testGetByAttribute() 56 | { 57 | $model = Config::getByAttribute('key', 'email.smtp_address'); 58 | $this->assertTrue($model !== null, 'Item found'); 59 | $this->assertTrue($model instanceof ActiveRecord, 'Item instance of ActiveRecord'); 60 | $this->assertEquals(count(Config::getMap()), 1, '1 item in map'); 61 | $model2 = Config::getByAttribute('key', 'email.smtp_address', true); 62 | $this->assertTrue($model2 !== null, 'Item found'); 63 | $this->assertTrue(is_array($model2), 'It is array'); 64 | $this->assertEquals(count(Config::getMap()), 1, '1 item in map'); 65 | } 66 | 67 | public function testSelectCustomFields() 68 | { 69 | $model = Config::find()->select('value')->where(['id' => 1])->one(); 70 | $this->assertTrue($model !== null, 'Item found'); 71 | $this->assertEquals(count(Config::getMap()), 0, 'No item in map'); 72 | } 73 | 74 | public function testFindBySql() 75 | { 76 | $model = Config::findBySql('SELECT * FROM config WHERE id = 1'); 77 | $this->assertTrue($model !== null, 'Item found'); 78 | $this->assertEquals(count(Config::getMap()), 0, 'No item in map'); 79 | } 80 | 81 | public function testSave() 82 | { 83 | $model = Config::getById(1); 84 | $model->value = 'no-reply@example.com'; 85 | $model->save(); 86 | $model2 = Config::getById(1); 87 | $this->assertEquals($model->value, $model2->value, 'Model1 equals Model2'); 88 | $model->key = ''; 89 | $this->assertFalse($model->save()); 90 | $model = Config::getById(1); 91 | $this->assertNotEmpty($model->key); 92 | } 93 | 94 | public function testAnotherId() 95 | { 96 | $model = Config2::getById('email.username'); 97 | $model2 = Config::getById($model->id); 98 | $this->assertEquals($model->attributes, $model2->attributes); 99 | } 100 | 101 | public function testMaxLimit() 102 | { 103 | $limit = Config2::getIdentityMapMaxSize(); 104 | $models = Config2::find()->limit($limit + 1)->all(); 105 | $this->assertSame($limit + 1, count($models)); 106 | $this->assertSame($limit, count(Config2::getMap())); 107 | Config2::find()->one(); 108 | $this->assertSame($limit, count(Config2::getMap())); 109 | } 110 | 111 | public function testResort() 112 | { 113 | $model1 = Config2::getById('email.username'); 114 | $model2 = Config2::getById('email.password', true); 115 | $model1 = Config2::getById('email.username', true); 116 | $modelMap = Config2::getMap(); 117 | $model = array_shift($modelMap); 118 | $this->assertSame($model2, $model); 119 | $model = array_shift($modelMap); 120 | $this->assertSame($model1, $model); 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /tests/unit/_bootstrap.php: -------------------------------------------------------------------------------- 1 | 'app-console', 4 | 'class' => 'yii\console\Application', 5 | 'basePath' => \Yii::getAlias('@tests'), 6 | 'runtimePath' => \Yii::getAlias('@tests/_output'), 7 | 'bootstrap' => [], 8 | 'components' => [ 9 | 'db' => [ 10 | 'class' => '\yii\db\Connection', 11 | 'dsn' => 'sqlite:'.\Yii::getAlias('@tests/_output/temp.db'), 12 | 'username' => '', 13 | 'password' => '', 14 | ] 15 | ] 16 | ]; 17 | --------------------------------------------------------------------------------