├── vendor ├── mike182uk │ └── cart │ │ ├── .gitignore │ │ ├── src │ │ ├── CartRestoreException.php │ │ ├── Arrayable.php │ │ ├── Storage │ │ │ ├── SessionStore.php │ │ │ ├── Store.php │ │ │ └── CookieStore.php │ │ ├── CartItem.php │ │ └── Cart.php │ │ ├── .scrutinizer.yml │ │ ├── .editorconfig │ │ ├── .php_cs │ │ ├── tests │ │ ├── CookieStoreTest.php │ │ ├── SessionStoreTest.php │ │ ├── CartItemTest.php │ │ └── CartTest.php │ │ ├── .travis.yml │ │ ├── phpunit.xml │ │ ├── composer.json │ │ ├── LICENSE │ │ ├── CONTRIBUTING.md │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ └── composer.lock ├── autoload.php └── composer │ ├── autoload_classmap.php │ ├── autoload_namespaces.php │ ├── autoload_psr4.php │ ├── autoload_static.php │ ├── LICENSE │ ├── installed.json │ ├── autoload_real.php │ └── ClassLoader.php ├── composer.json ├── package.yml ├── lib ├── ShoppingCartItem.php ├── ShoppingCart.php └── Storage │ ├── MemcacheStore.php │ ├── MemcachedStore.php │ └── RedisStore.php ├── LICENSE └── README.md /vendor/mike182uk/cart/.gitignore: -------------------------------------------------------------------------------- 1 | /vendor/ 2 | coverage.clover 3 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": { 3 | "mike182uk/cart": "^3.0" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /vendor/mike182uk/cart/src/CartRestoreException.php: -------------------------------------------------------------------------------- 1 | =5.6' 10 | -------------------------------------------------------------------------------- /lib/ShoppingCartItem.php: -------------------------------------------------------------------------------- 1 | array($vendorDir . '/mike182uk/cart/src'), 10 | ); 11 | -------------------------------------------------------------------------------- /vendor/mike182uk/cart/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_style = space 7 | insert_final_newline = true 8 | indent_size = 2 9 | trim_trailing_whitespace = true 10 | 11 | [*.php] 12 | indent_size = 4 13 | 14 | [*.md] 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /vendor/mike182uk/cart/.php_cs: -------------------------------------------------------------------------------- 1 | in(__DIR__ . '/src') 5 | ->in(__DIR__ . '/tests') 6 | ; 7 | 8 | return PhpCsFixer\Config::create() 9 | ->setRules([ 10 | '@PSR2' => true, 11 | 'array_syntax' => [ 12 | 'syntax' => 'short', 13 | ], 14 | ]) 15 | ->setUsingCache(false) 16 | ->setFinder($finder) 17 | ; 18 | -------------------------------------------------------------------------------- /vendor/mike182uk/cart/tests/CookieStoreTest.php: -------------------------------------------------------------------------------- 1 | encode($data); 15 | 16 | $this->assertSame($data, $store->decode($encodedData)); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /vendor/mike182uk/cart/.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - 5.6 5 | - 7.0 6 | - 7.1 7 | - hhvm 8 | 9 | sudo: false 10 | 11 | cache: 12 | directories: 13 | - vendor 14 | - $HOME/.composer/cache 15 | 16 | before_script: 17 | - composer self-update 18 | - composer install --no-interaction 19 | 20 | script: 21 | - composer lint 22 | - composer test-coverage 23 | 24 | after_script: 25 | - wget https://scrutinizer-ci.com/ocular.phar 26 | - php ocular.phar code-coverage:upload --format=php-clover coverage.clover 27 | 28 | matrix: 29 | allow_failures: 30 | - php: hhvm 31 | fast_finish: true 32 | -------------------------------------------------------------------------------- /vendor/mike182uk/cart/src/Storage/SessionStore.php: -------------------------------------------------------------------------------- 1 | 11 | 12 | 13 | ./tests/ 14 | 15 | 16 | 17 | 18 | 19 | ./src/ 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /vendor/mike182uk/cart/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mike182uk/cart", 3 | "description" : "A flexible and modern shopping cart package", 4 | "license": "MIT", 5 | "authors": [ 6 | { 7 | "name": "Michael David Barrett", 8 | "email": "mike182uk@gmail.com" 9 | } 10 | ], 11 | "require" : { 12 | "php": ">=5.6.0" 13 | }, 14 | "require-dev": { 15 | "phpunit/phpunit": "~5.0", 16 | "mockery/mockery": "~0.0", 17 | "friendsofphp/php-cs-fixer": "~2.0" 18 | }, 19 | "autoload": { 20 | "psr-4": { 21 | "Cart\\": "src" 22 | } 23 | }, 24 | "scripts": { 25 | "test": "./vendor/bin/phpunit", 26 | "test-coverage": "./vendor/bin/phpunit --coverage-clover coverage.clover", 27 | "lint": "./vendor/bin/php-cs-fixer fix --dry-run --verbose", 28 | "fix": "./vendor/bin/php-cs-fixer fix" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /vendor/mike182uk/cart/tests/SessionStoreTest.php: -------------------------------------------------------------------------------- 1 | put('foo', $data); 13 | 14 | $this->assertSame($store->get('foo'), $data); 15 | } 16 | 17 | public function testPut() 18 | { 19 | $data = 'bar'; 20 | 21 | $store = new SessionStore(); 22 | $store->put('foo', $data); 23 | 24 | $this->assertSame($_SESSION['foo'], $data); 25 | } 26 | 27 | public function testFlush() 28 | { 29 | $store = new SessionStore(); 30 | $store->put('foo', 'bar'); 31 | 32 | $store->flush('foo'); 33 | 34 | $this->assertFalse(isset($_SESSION['foo'])); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /vendor/composer/autoload_static.php: -------------------------------------------------------------------------------- 1 | 11 | array ( 12 | 'Cart\\' => 5, 13 | ), 14 | ); 15 | 16 | public static $prefixDirsPsr4 = array ( 17 | 'Cart\\' => 18 | array ( 19 | 0 => __DIR__ . '/..' . '/mike182uk/cart/src', 20 | ), 21 | ); 22 | 23 | public static function getInitializer(ClassLoader $loader) 24 | { 25 | return \Closure::bind(function () use ($loader) { 26 | $loader->prefixLengthsPsr4 = ComposerStaticInit5747378947eaae148a1e12d31f3f7aef::$prefixLengthsPsr4; 27 | $loader->prefixDirsPsr4 = ComposerStaticInit5747378947eaae148a1e12d31f3f7aef::$prefixDirsPsr4; 28 | 29 | }, null, ClassLoader::class); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Friends Of REDAXO 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /vendor/mike182uk/cart/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) Michael David Barrett 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /vendor/composer/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Copyright (c) 2016 Nils Adermann, Jordi Boggiano 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is furnished 9 | to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | 22 | -------------------------------------------------------------------------------- /vendor/mike182uk/cart/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Contributions are **welcome!** 4 | 5 | Contributions can be made via a Pull Request on [Github](https://github.com/mike182uk/cart). 6 | 7 | ## Reporting an Issue 8 | 9 | Please report issues via the issue tracker on [Github](https://github.com/mike182uk/cart). For security-related issues, please email the maintainer directly. 10 | 11 | ## Pull Requests 12 | 13 | - **[PSR-2 Coding Standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)** - [PHP CS Fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer). Make sure you run `composer fix` before committing your code. 14 | 15 | - **Add tests where appropriate** - [PHPUnit](https://phpunit.de/) 16 | 17 | - **Document any change in behaviour** - Make sure the README and any other relevant documentation are kept up-to-date. 18 | 19 | - **Create topic branches** - i.e `feature/some-awesome-feature`. 20 | 21 | - **One pull request per feature** 22 | 23 | - **Send coherent history** - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please squash them before submitting. 24 | 25 | ## Running Tests 26 | 27 | You can run all of the tests in the project using: 28 | 29 | ```bash 30 | composer test 31 | ``` 32 | -------------------------------------------------------------------------------- /vendor/composer/installed.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "mike182uk/cart", 4 | "version": "v3.0.0", 5 | "version_normalized": "3.0.0.0", 6 | "source": { 7 | "type": "git", 8 | "url": "https://github.com/mike182uk/cart.git", 9 | "reference": "6243f5130971bf410374aeb844429a9fca5c7469" 10 | }, 11 | "dist": { 12 | "type": "zip", 13 | "url": "https://api.github.com/repos/mike182uk/cart/zipball/6243f5130971bf410374aeb844429a9fca5c7469", 14 | "reference": "6243f5130971bf410374aeb844429a9fca5c7469", 15 | "shasum": "" 16 | }, 17 | "require": { 18 | "php": ">=5.6.0" 19 | }, 20 | "require-dev": { 21 | "friendsofphp/php-cs-fixer": "~2.0", 22 | "mockery/mockery": "~0.0", 23 | "phpunit/phpunit": "~5.0" 24 | }, 25 | "time": "2017-01-04T21:04:06+00:00", 26 | "type": "library", 27 | "installation-source": "dist", 28 | "autoload": { 29 | "psr-4": { 30 | "Cart\\": "src" 31 | } 32 | }, 33 | "notification-url": "https://packagist.org/downloads/", 34 | "license": [ 35 | "MIT" 36 | ], 37 | "authors": [ 38 | { 39 | "name": "Michael David Barrett", 40 | "email": "mike182uk@gmail.com" 41 | } 42 | ], 43 | "description": "A flexible and modern shopping cart package" 44 | } 45 | ] 46 | -------------------------------------------------------------------------------- /vendor/mike182uk/cart/src/Storage/CookieStore.php: -------------------------------------------------------------------------------- 1 | decode($_COOKIE[$cartId]) : serialize([]); 13 | } 14 | 15 | /** 16 | * {@inheritdoc} 17 | */ 18 | public function put($cartId, $data) 19 | { 20 | $this->setCookie($cartId, $this->encode($data)); 21 | } 22 | 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | public function flush($cartId) 27 | { 28 | $this->unsetCookie($cartId); 29 | } 30 | 31 | /** 32 | * Encode data to be saved in cookie. 33 | * 34 | * @param string $data 35 | * 36 | * @return string 37 | */ 38 | public function encode($data) 39 | { 40 | return base64_encode($data); 41 | } 42 | 43 | /** 44 | * Decode data that has been saved in a cookie. 45 | * 46 | * @param string $data 47 | * 48 | * @return string 49 | */ 50 | public function decode($data) 51 | { 52 | return base64_decode($data); 53 | } 54 | 55 | /** 56 | * Set cookie. 57 | * 58 | * @param string $name 59 | * @param string $data 60 | */ 61 | private function setCookie($name, $data) 62 | { 63 | setcookie($name, $data); 64 | } 65 | 66 | /** 67 | * Unset cookie. 68 | * 69 | * @param string $name 70 | */ 71 | private function unsetCookie($name) 72 | { 73 | unset($_COOKIE[$name]); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /vendor/composer/autoload_real.php: -------------------------------------------------------------------------------- 1 | = 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); 27 | if ($useStaticLoader) { 28 | require_once __DIR__ . '/autoload_static.php'; 29 | 30 | call_user_func(\Composer\Autoload\ComposerStaticInit5747378947eaae148a1e12d31f3f7aef::getInitializer($loader)); 31 | } else { 32 | $map = require __DIR__ . '/autoload_namespaces.php'; 33 | foreach ($map as $namespace => $path) { 34 | $loader->set($namespace, $path); 35 | } 36 | 37 | $map = require __DIR__ . '/autoload_psr4.php'; 38 | foreach ($map as $namespace => $path) { 39 | $loader->setPsr4($namespace, $path); 40 | } 41 | 42 | $classMap = require __DIR__ . '/autoload_classmap.php'; 43 | if ($classMap) { 44 | $loader->addClassMap($classMap); 45 | } 46 | } 47 | 48 | $loader->register(true); 49 | 50 | return $loader; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /vendor/mike182uk/cart/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 3.0.0 4 | 5 | - drop support for <5.6 6 | - update dependencies 7 | - misc refactoring 8 | 9 | ## 2.2.3 10 | 11 | - cart can be restored from an empty state without an exception being thrown 12 | - use default bin location 13 | - update dependencies 14 | 15 | ## 2.2.2 16 | 17 | - modernize project 18 | 19 | ## 2.2.1 20 | 21 | - misc refactoring 22 | 23 | ## 2.2.0 24 | 25 | - add `Cart\Store\CookieStore` 26 | - rename `Cart\SessionStore` to `Cart\Storage\SessionStore` 27 | - rename `Cart\StorageInterface` to `Cart\Storage\Store` 28 | - rename `Cart\ArrayableInterface` to `Cart\Arrayable` 29 | - add scrutinizer config 30 | - fix scrutinizer recommendations 31 | - misc comments / code cleanup 32 | 33 | ## 2.1.0 34 | 35 | - rename `Cart\Store\Native\SessionStore` to `Cart\SessionStore` 36 | - add more error checking to `Cart::restore`. `Cart\CartRestoreException` is thrown if the cart state cannot be restored due to: 37 | - unserializable data 38 | - invalid unserialized data (not an array) 39 | - missing id 40 | - missing items 41 | - invalid id (not a string) 42 | - invalid items (not an array) 43 | - add `Cart\CartItem::getSingleTax` 44 | - `Cart\CartItem::getSinglePrice` and `Cart\CartItem::getTotalPrice` always return price including tax 45 | - add `Cart\CartItem::getSinglePriceExlcudingTax` and `Cart\CartItem::getTotalPriceExcludingTax` 46 | - `Cart\Cart::total` always return total including tax 47 | - add `Cart\Cart::totalExcludingTax` 48 | 49 | ## 2.0.0 50 | 51 | - rewrite 52 | 53 | ## 1.1.0 54 | 55 | - remove `Cart\Proxy` 56 | - remove all static methods from `Cart\Manager` 57 | - add `Cart\Facade\Cart` and `Cart\Facade\Manager` (these replace `Cart\Proxy` and static methods in `Cart\Manager`) 58 | - remove `Cart\Storage\Session` 59 | - refactor storage implementations - No restrictions on name our placement of storage driver 60 | - misc refactoring + cleaning up 61 | 62 | ## 1.0 63 | 64 | First release 65 | -------------------------------------------------------------------------------- /lib/Storage/MemcacheStore.php: -------------------------------------------------------------------------------- 1 | mc = new \Memcache(); 24 | 25 | if($server) { 26 | $this->server = $server; 27 | } 28 | if($port) { 29 | $this->port = $port; 30 | } 31 | if($expire) { 32 | $this->expire = $expire; 33 | } 34 | $this->mc->addServer($this->server, $this->port); 35 | 36 | return $this; 37 | } 38 | 39 | 40 | /** 41 | * {@inheritdoc} 42 | */ 43 | public function get($cartId) 44 | { 45 | return $this->mc->get($cartId) ? $this->mc->get($cartId) : serialize([]); 46 | } 47 | 48 | /** 49 | * {@inheritdoc} 50 | */ 51 | public function put($cartId, $data) 52 | { 53 | $this->mc->set($cartId, $data, $this->expire); 54 | } 55 | 56 | /** 57 | * {@inheritdoc} 58 | */ 59 | public function flush($cartId) 60 | { 61 | $this->getInstance()->delete($cartId); 62 | } 63 | 64 | /** 65 | * set memcached server. 66 | * 67 | * @param string $server 68 | * 69 | * @return string 70 | */ 71 | public function setServer($server) 72 | { 73 | $this->server = $server; 74 | 75 | return $this; 76 | } 77 | 78 | /** 79 | * set memcached port. 80 | * 81 | * @param string $server 82 | * 83 | * @return string 84 | */ 85 | public function setPort($port) 86 | { 87 | $this->port = $port; 88 | 89 | return $this; 90 | } 91 | 92 | /** 93 | * set memcached expire. 94 | * 95 | * @param int $expire 96 | * 97 | * @return string 98 | */ 99 | public function setExpire($expire) 100 | { 101 | $this->expire = $expire; 102 | 103 | return $this; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /lib/Storage/MemcachedStore.php: -------------------------------------------------------------------------------- 1 | mc = new \Memcached(); 24 | 25 | if($server) { 26 | $this->server = $server; 27 | } 28 | if($port) { 29 | $this->port = $port; 30 | } 31 | if($expire) { 32 | $this->expire = $expire; 33 | } 34 | $this->mc->addServer($this->server, $this->port); 35 | 36 | return $this; 37 | } 38 | 39 | 40 | /** 41 | * {@inheritdoc} 42 | */ 43 | public function get($cartId) 44 | { 45 | return $this->mc->get($cartId) ? $this->mc->get($cartId) : serialize([]); 46 | } 47 | 48 | /** 49 | * {@inheritdoc} 50 | */ 51 | public function put($cartId, $data) 52 | { 53 | $this->mc->set($cartId, $data, $this->expire); 54 | } 55 | 56 | /** 57 | * {@inheritdoc} 58 | */ 59 | public function flush($cartId) 60 | { 61 | $this->mc->delete($cartId); 62 | } 63 | 64 | /** 65 | * set memcached server. 66 | * 67 | * @param string $server 68 | * 69 | * @return string 70 | */ 71 | public function setServer($server) 72 | { 73 | $this->server = $server; 74 | 75 | return $this; 76 | } 77 | 78 | /** 79 | * set memcached port. 80 | * 81 | * @param string $server 82 | * 83 | * @return string 84 | */ 85 | public function setPort($port) 86 | { 87 | $this->port = $port; 88 | 89 | return $this; 90 | } 91 | 92 | /** 93 | * set memcached expire. 94 | * 95 | * @param int $expire 96 | * 97 | * @return string 98 | */ 99 | public function setExpire($expire) 100 | { 101 | $this->expire = $expire; 102 | 103 | return $this; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /lib/Storage/RedisStore.php: -------------------------------------------------------------------------------- 1 | redis = new \Redis(); 24 | 25 | if($server) { 26 | $this->server = $server; 27 | } 28 | if($port) { 29 | $this->port = $port; 30 | } 31 | if($expire) { 32 | $this->expire = $expire; 33 | } 34 | $this->redis->connect($this->server, $this->port); 35 | 36 | return $this; 37 | } 38 | 39 | 40 | /** 41 | * {@inheritdoc} 42 | */ 43 | public function get($cartId) 44 | { 45 | return $this->redis->get($cartId) ? $this->redis->get($cartId) : serialize([]); 46 | } 47 | 48 | /** 49 | * {@inheritdoc} 50 | */ 51 | public function put($cartId, $data) 52 | { 53 | $this->redis->set($cartId, $data, $this->expire); 54 | } 55 | 56 | /** 57 | * {@inheritdoc} 58 | */ 59 | public function flush($cartId) 60 | { 61 | $this->redis->delete($cartId); 62 | } 63 | 64 | /** 65 | * set redis server. 66 | * 67 | * @param string $server 68 | * 69 | * @return string 70 | */ 71 | public function setServer($server) 72 | { 73 | $this->server = $server; 74 | 75 | return $this; 76 | } 77 | 78 | /** 79 | * set redis port. 80 | * 81 | * @param string $server 82 | * 83 | * @return string 84 | */ 85 | public function setPort($port) 86 | { 87 | $this->port = $port; 88 | 89 | return $this; 90 | } 91 | 92 | /** 93 | * set redis expire. 94 | * 95 | * @param int $expire 96 | * 97 | * @return string 98 | */ 99 | public function setExpire($expire) 100 | { 101 | $this->expire = $expire; 102 | 103 | return $this; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /vendor/mike182uk/cart/tests/CartItemTest.php: -------------------------------------------------------------------------------- 1 | assertInstanceOf('Cart\Arrayable', $item); 12 | 13 | $itemArr = $item->toArray(); 14 | 15 | $this->assertTrue(is_array($itemArr)); 16 | $this->assertArrayHasKey('id', $itemArr); 17 | $this->assertArrayHasKey('data', $itemArr); 18 | $this->assertTrue(is_array($itemArr['data'])); 19 | } 20 | 21 | public function testSetAndGetData() 22 | { 23 | $item = new CartItem(); 24 | 25 | $item->name = 'foo'; 26 | $this->assertSame($item->get('name'), 'foo'); 27 | $this->assertSame($item['name'], 'foo'); 28 | $this->assertSame($item->name, 'foo'); 29 | 30 | $item['name'] = 'bar'; 31 | $this->assertSame($item->get('name'), 'bar'); 32 | $this->assertSame($item->name, 'bar'); 33 | $this->assertSame($item['name'], 'bar'); 34 | 35 | $item->set('name', 'baz'); 36 | $this->assertSame($item->get('name'), 'baz'); 37 | $this->assertSame($item['name'], 'baz'); 38 | $this->assertSame($item->name, 'baz'); 39 | } 40 | 41 | public function testIssetAndUnsetData() 42 | { 43 | $item = new CartItem([ 44 | 'name' => 'foo', 45 | 'weight' => '10kg', 46 | ]); 47 | 48 | unset($item['name']); 49 | 50 | $this->assertFalse(isset($item['name'])); 51 | 52 | unset($item->weight); 53 | 54 | $this->assertFalse(isset($item->weight)); 55 | } 56 | 57 | public function testConstructorSetsData() 58 | { 59 | $itemData = [ 60 | 'name' => 'foo', 61 | 'price' => 10.00, 62 | 'tax' => 1.00, 63 | 'quantity' => 5, 64 | ]; 65 | 66 | $item = new CartItem($itemData); 67 | 68 | $this->assertTrue($item->name == 'foo'); 69 | $this->assertTrue($item->price === 10.00); 70 | $this->assertTrue($item->tax === 1.00); 71 | $this->assertTrue($item->quantity === 5); 72 | } 73 | 74 | public function testConstructorSetsDefaults() 75 | { 76 | $itemData = [ 77 | 'name' => 'foo', 78 | ]; 79 | 80 | $item = new CartItem($itemData); 81 | 82 | $this->assertTrue($item->price === 0.00); 83 | $this->assertTrue($item->tax === 0.00); 84 | $this->assertTrue($item->quantity === 1); 85 | } 86 | 87 | public function testQuantityMustBeInteger() 88 | { 89 | $item = new CartItem(); 90 | 91 | $this->setExpectedException('InvalidArgumentException'); 92 | 93 | $item->quantity = 'one'; 94 | } 95 | 96 | public function testPriceAndTaxMustBeNumeric() 97 | { 98 | $item = new CartItem(); 99 | 100 | $this->setExpectedException('InvalidArgumentException'); 101 | $item->price = 'ten'; 102 | 103 | $this->setExpectedException('InvalidArgumentException'); 104 | $item->tax = 'ten'; 105 | } 106 | 107 | public function testPriceAndTaxAreCastToFloats() 108 | { 109 | $item = new CartItem(); 110 | 111 | $item->price = '10.00'; 112 | $item->tax = '5.00'; 113 | 114 | $this->assertTrue(is_float($item->price)); 115 | $this->assertTrue(is_float($item->tax)); 116 | } 117 | 118 | public function testGettingIdPropertyReturnsItemId() 119 | { 120 | $item = new CartItem(); 121 | 122 | $this->assertSame($item->getId(), $item->id); 123 | } 124 | 125 | public function testSetReturnsNewId() 126 | { 127 | $item = new CartItem(); 128 | 129 | $newId = $item->set('name', 'foo'); 130 | $itemId = $item->id; 131 | 132 | $this->assertSame($newId, $itemId); 133 | } 134 | 135 | public function testGetSinglePrice() 136 | { 137 | $item = new CartItem(); 138 | 139 | $item->price = 10.00; 140 | $item->tax = 5.00; 141 | 142 | $price = $item->getSinglePrice(); 143 | 144 | $this->assertEquals(15.00, $price); 145 | $this->assertTrue(is_float($price)); 146 | } 147 | 148 | public function testGetSinglePriceExcludingTax() 149 | { 150 | $item = new CartItem(); 151 | 152 | $item->price = 10.00; 153 | $item->tax = 5.00; 154 | 155 | $price = $item->getSinglePriceExcludingTax(); 156 | 157 | $this->assertEquals(10.00, $price); 158 | $this->assertTrue(is_float($price)); 159 | } 160 | 161 | public function testGetTotalPrice() 162 | { 163 | $item = new CartItem(); 164 | 165 | $item->price = 10.00; 166 | $item->tax = 5.00; 167 | $item->quantity = 2; 168 | 169 | $price = $item->getTotalPrice(); 170 | 171 | $this->assertEquals(30.00, $price); 172 | $this->assertTrue(is_float($price)); 173 | } 174 | 175 | public function testGetTotalPriceExcludingTax() 176 | { 177 | $item = new CartItem(); 178 | 179 | $item->price = 10.00; 180 | $item->tax = 5.00; 181 | $item->quantity = 2; 182 | 183 | $price = $item->getTotalPriceExcludingTax(); 184 | 185 | $this->assertEquals(20.00, $price); 186 | $this->assertTrue(is_float($price)); 187 | } 188 | 189 | public function testGetTotalTax() 190 | { 191 | $item = new CartItem(); 192 | 193 | $item->quantity = 2; 194 | $item->tax = 5.00; 195 | 196 | $tax = $item->getTotalTax(); 197 | 198 | $this->assertEquals(10.00, $tax); 199 | $this->assertTrue(is_float($tax)); 200 | } 201 | 202 | public function testGetSingleTax() 203 | { 204 | $item = new CartItem(); 205 | 206 | $item->quantity = 2; 207 | $item->tax = 5.00; 208 | 209 | $tax = $item->getSingleTax(); 210 | 211 | $this->assertEquals(5.00, $tax); 212 | $this->assertTrue(is_float($tax)); 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /vendor/mike182uk/cart/src/CartItem.php: -------------------------------------------------------------------------------- 1 | 1, 29 | 'price' => 0.00, 30 | 'tax' => 0.00, 31 | ]; 32 | 33 | $data = array_merge($defaults, $data); 34 | 35 | foreach ($data as $k => $v) { 36 | $this->$k = $v; 37 | } 38 | } 39 | 40 | /** 41 | * Get the cart item id. 42 | * 43 | * @return string 44 | */ 45 | public function getId() 46 | { 47 | // keys to ignore in the hashing process 48 | $ignoreKeys = ['quantity']; 49 | 50 | // data to use for the hashing process 51 | $hashData = $this->data; 52 | foreach ($ignoreKeys as $key) { 53 | unset($hashData[$key]); 54 | } 55 | 56 | $hash = sha1(serialize($hashData)); 57 | 58 | return $hash; 59 | } 60 | 61 | /** 62 | * Get a piece of data set on the cart item. 63 | * 64 | * @param string $key 65 | * 66 | * @return mixed 67 | */ 68 | public function get($key) 69 | { 70 | switch ($key) { 71 | case 'id': 72 | return $this->getId(); 73 | default: 74 | return $this->data[$key]; 75 | } 76 | } 77 | 78 | /** 79 | * Set a piece of data on the cart item. 80 | * 81 | * @param string $key 82 | * @param mixed $value 83 | * 84 | * @return string 85 | */ 86 | public function set($key, $value) 87 | { 88 | switch ($key) { 89 | case 'quantity': 90 | $this->setCheckTypeInteger($value, $key); 91 | break; 92 | case 'price': 93 | case 'tax': 94 | $this->setCheckIsNumeric($value, $key); 95 | 96 | $value = (float) $value; 97 | } 98 | 99 | $this->data[$key] = $value; 100 | 101 | return $this->getId(); 102 | } 103 | 104 | /** 105 | * Check the value being set is an integer. 106 | * 107 | * @param mixed $value 108 | * @param string $name 109 | * 110 | * @throws \InvalidArgumentException 111 | */ 112 | private function setCheckTypeInteger($value, $name) 113 | { 114 | if (!is_integer($value)) { 115 | throw new \InvalidArgumentException(sprintf('%s must be an integer.', $name)); 116 | } 117 | } 118 | 119 | /** 120 | * Check the value being set is an integer. 121 | * 122 | * @param mixed $value 123 | * @param string $name 124 | * 125 | * @throws \InvalidArgumentException 126 | */ 127 | private function setCheckIsNumeric($value, $name) 128 | { 129 | if (!is_numeric($value)) { 130 | throw new \InvalidArgumentException(sprintf('%s must be numeric.', $name)); 131 | } 132 | } 133 | 134 | /** 135 | * Get the total price of the cart item including tax. 136 | * 137 | * @return float 138 | */ 139 | public function getTotalPrice() 140 | { 141 | return (float) ($this->price + $this->tax) * $this->quantity; 142 | } 143 | 144 | /** 145 | * Get the total price of the cart item excluding tax. 146 | * 147 | * @return float 148 | */ 149 | public function getTotalPriceExcludingTax() 150 | { 151 | return (float) $this->price * $this->quantity; 152 | } 153 | 154 | /** 155 | * Get the single price of the cart item including tax. 156 | * 157 | * @return float 158 | */ 159 | public function getSinglePrice() 160 | { 161 | return (float) $this->price + $this->tax; 162 | } 163 | 164 | /** 165 | * Get the single price of the cart item excluding tax. 166 | * 167 | * @return float 168 | */ 169 | public function getSinglePriceExcludingTax() 170 | { 171 | return (float) $this->price; 172 | } 173 | 174 | /** 175 | * Get the total tax for the cart item. 176 | * 177 | * @return float 178 | */ 179 | public function getTotalTax() 180 | { 181 | return (float) $this->tax * $this->quantity; 182 | } 183 | 184 | /** 185 | * Get the single tax value of the cart item. 186 | * 187 | * @return float 188 | */ 189 | public function getSingleTax() 190 | { 191 | return (float) $this->tax; 192 | } 193 | 194 | /** 195 | * Export the cart item as an array. 196 | * 197 | * @return array 198 | */ 199 | public function toArray() 200 | { 201 | return [ 202 | 'id' => $this->getId(), 203 | 'data' => $this->data, 204 | ]; 205 | } 206 | 207 | /** 208 | * Determine if a piece of data is set on the cart item. 209 | * 210 | * @param string $key 211 | * 212 | * @return bool 213 | */ 214 | public function offsetExists($key) 215 | { 216 | return array_key_exists($key, $this->data); 217 | } 218 | 219 | /** 220 | * Get a piece of data set on the cart item. 221 | * 222 | * @param string $key 223 | * 224 | * @return mixed 225 | */ 226 | public function offsetGet($key) 227 | { 228 | return $this->get($key); 229 | } 230 | 231 | /** 232 | * Set a piece of data on the cart item. 233 | * 234 | * @param string $key 235 | * @param mixed $value 236 | */ 237 | public function offsetSet($key, $value) 238 | { 239 | $this->set($key, $value); 240 | } 241 | 242 | /** 243 | * Unset a piece of data from the cart item. 244 | * 245 | * @param string $key 246 | */ 247 | public function offsetUnset($key) 248 | { 249 | unset($this->data[$key]); 250 | } 251 | 252 | /** 253 | * Get a piece of data set on the cart item. 254 | * 255 | * @param string $key 256 | * 257 | * @return mixed 258 | */ 259 | public function __get($key) 260 | { 261 | return $this->get($key); 262 | } 263 | 264 | /** 265 | * Set a piece of data on the cart item. 266 | * 267 | * @param string $key 268 | * @param mixed $value 269 | */ 270 | public function __set($key, $value) 271 | { 272 | $this->set($key, $value); 273 | } 274 | 275 | /** 276 | * Determine if a piece of data is set on the cart item. 277 | * 278 | * @param string $key 279 | * 280 | * @return bool 281 | */ 282 | public function __isset($key) 283 | { 284 | return isset($this->data[$key]); 285 | } 286 | 287 | /** 288 | * Unset a piece of data from the cart item. 289 | * 290 | * @param string $key 291 | */ 292 | public function __unset($key) 293 | { 294 | unset($this->data[$key]); 295 | } 296 | } 297 | -------------------------------------------------------------------------------- /vendor/mike182uk/cart/src/Cart.php: -------------------------------------------------------------------------------- 1 | id = $id; 39 | $this->store = $store; 40 | } 41 | 42 | /** 43 | * Retrieve the cart storage implementation. 44 | * 45 | * @return Store 46 | */ 47 | public function getStore() 48 | { 49 | return $this->store; 50 | } 51 | 52 | /** 53 | * Retrieve the cart id. 54 | * 55 | * @return string 56 | */ 57 | public function getId() 58 | { 59 | return $this->id; 60 | } 61 | 62 | /** 63 | * Retrieve all of the items in the cart. 64 | * 65 | * @return CartItem[] 66 | */ 67 | public function all() 68 | { 69 | return $this->items; 70 | } 71 | 72 | /** 73 | * Add an item to the cart. 74 | * 75 | * @param CartItem $cartItem 76 | */ 77 | public function add(CartItem $cartItem) 78 | { 79 | $itemId = $cartItem->getId(); 80 | 81 | // if item already exists in the cart, just update the quantity, 82 | // otherwise add it as a new item 83 | if ($this->has($itemId)) { 84 | $existingItem = $this->find($itemId); 85 | $existingItem->quantity += $cartItem->quantity; 86 | } else { 87 | $this->items[] = $cartItem; 88 | } 89 | } 90 | 91 | /** 92 | * Remove an item from the cart. 93 | * 94 | * @param string $itemId 95 | */ 96 | public function remove($itemId) 97 | { 98 | $items = &$this->items; 99 | 100 | foreach ($items as $position => $item) { 101 | if ($itemId === $item->id) { 102 | unset($items[$position]); 103 | } 104 | } 105 | } 106 | 107 | /** 108 | * Update an item in the cart. 109 | * 110 | * @param string $itemId 111 | * @param string $key 112 | * @param mixed $value 113 | * 114 | * @return string 115 | * 116 | * @throws \InvalidArgumentException 117 | */ 118 | public function update($itemId, $key, $value) 119 | { 120 | $item = $this->find($itemId); 121 | 122 | if (!$item) { 123 | throw new \InvalidArgumentException(sprintf('Item [%s] does not exist in cart.', $itemId)); 124 | } 125 | 126 | $item->$key = $value; 127 | 128 | return $item->id; 129 | } 130 | 131 | /** 132 | * Retrieve an item from the cart by its id. 133 | * 134 | * @param string $itemId 135 | * 136 | * @return CartItem|null 137 | */ 138 | public function get($itemId) 139 | { 140 | return $this->find($itemId); 141 | } 142 | 143 | /** 144 | * Determine if an item exists in the cart. 145 | * 146 | * @param string $itemId 147 | * 148 | * @return bool 149 | */ 150 | public function has($itemId) 151 | { 152 | return !is_null($this->find($itemId)); 153 | } 154 | 155 | /** 156 | * Find an item in the cart. 157 | * 158 | * @param string $itemId 159 | * 160 | * @return CartItem|null 161 | */ 162 | public function find($itemId) 163 | { 164 | foreach ($this->items as $item) { 165 | if ($itemId === $item->id) { 166 | return $item; 167 | } 168 | } 169 | 170 | return; 171 | } 172 | 173 | /** 174 | * Get the total number of unique items in the cart. 175 | * 176 | * @return int 177 | */ 178 | public function totalUniqueItems() 179 | { 180 | return count($this->items); 181 | } 182 | 183 | /** 184 | * Get the total number of items in the cart. 185 | * 186 | * @return int 187 | */ 188 | public function totalItems() 189 | { 190 | return array_sum( 191 | array_map(function (CartItem $item) { 192 | return $item->quantity; 193 | }, $this->items) 194 | ); 195 | } 196 | 197 | /** 198 | * Get the cart total including tax. 199 | * 200 | * @return float 201 | */ 202 | public function total() 203 | { 204 | return (float) array_sum( 205 | array_map(function (CartItem $item) { 206 | return $item->getTotalPrice(); 207 | }, $this->items) 208 | ); 209 | } 210 | 211 | /** 212 | * Get the cart total excluding tax. 213 | * 214 | * @return float 215 | */ 216 | public function totalExcludingTax() 217 | { 218 | return (float) array_sum( 219 | array_map(function (CartItem $item) { 220 | return $item->getTotalPriceExcludingTax(); 221 | }, $this->items) 222 | ); 223 | } 224 | 225 | /** 226 | * Get the cart tax. 227 | * 228 | * @return float 229 | */ 230 | public function tax() 231 | { 232 | return (float) array_sum( 233 | array_map(function (CartItem $item) { 234 | return $item->getTotalTax(); 235 | }, $this->items) 236 | ); 237 | } 238 | 239 | /** 240 | * Remove all items from the cart. 241 | */ 242 | public function clear() 243 | { 244 | $this->items = []; 245 | 246 | $this->store->flush($this->id); 247 | } 248 | 249 | /** 250 | * Save the cart state. 251 | */ 252 | public function save() 253 | { 254 | $data = serialize($this->toArray()); 255 | 256 | $this->store->put($this->id, $data); 257 | } 258 | 259 | /** 260 | * Restore the cart from its saved state. 261 | * 262 | * @throws CartRestoreException 263 | */ 264 | public function restore() 265 | { 266 | $state = $this->store->get($this->id); 267 | 268 | if ($state == '') { 269 | return; 270 | } 271 | 272 | $data = @unserialize($state); // suppress unserializable error 273 | 274 | $this->restoreCheckType($data); 275 | $this->restoreCheckContents($data); 276 | $this->restoreCheckContentsType($data); 277 | 278 | $this->id = $data['id']; 279 | $this->items = []; 280 | 281 | foreach ($data['items'] as $itemArr) { 282 | $this->items[] = new CartItem($itemArr); 283 | } 284 | } 285 | 286 | /** 287 | * Check the data to be restored is of the correct type. 288 | * 289 | * @param mixed $data 290 | * 291 | * @throws CartRestoreException 292 | */ 293 | private function restoreCheckType($data) 294 | { 295 | if ($data === false) { 296 | throw new CartRestoreException('Saved cart state is unserializable.'); 297 | } 298 | 299 | if (!is_array($data)) { 300 | throw new CartRestoreException('Unserialized data is not an array.'); 301 | } 302 | } 303 | 304 | /** 305 | * Check the contents of the data to be restored contains the correct data. 306 | * 307 | * @param array $data 308 | * 309 | * @throws CartRestoreException 310 | */ 311 | private function restoreCheckContents(array $data) 312 | { 313 | if (!isset($data['id']) || !isset($data['items'])) { 314 | throw new CartRestoreException('Missing cart ID or cart items.'); 315 | } 316 | } 317 | 318 | /** 319 | * Check the contents of the data to be restored is of the correct type. 320 | * 321 | * @param array $data 322 | * 323 | * @throws CartRestoreException 324 | */ 325 | private function restoreCheckContentsType(array $data) 326 | { 327 | if (!is_string($data['id']) || !is_array($data['items'])) { 328 | throw new CartRestoreException('Cart ID not a string or cart items not an array.'); 329 | } 330 | } 331 | 332 | /** 333 | * Export the cart as an array. 334 | * 335 | * @return array 336 | */ 337 | public function toArray() 338 | { 339 | return [ 340 | 'id' => $this->id, 341 | 'items' => array_map(function (CartItem $item) { 342 | return $item->toArray(); 343 | }, $this->items), 344 | ]; 345 | } 346 | } 347 | -------------------------------------------------------------------------------- /vendor/mike182uk/cart/tests/CartTest.php: -------------------------------------------------------------------------------- 1 | getCart(); 18 | 19 | $this->assertInstanceOf('Cart\Arrayable', $cart); 20 | 21 | $cartArr = $cart->toArray(); 22 | 23 | $this->assertTrue(is_array($cartArr)); 24 | $this->assertArrayHasKey('id', $cartArr); 25 | $this->assertArrayHasKey('items', $cartArr); 26 | $this->assertTrue(is_array($cartArr['items'])); 27 | } 28 | 29 | public function testGetId() 30 | { 31 | $this->assertSame($this->getCart()->getId(), 'foo'); 32 | } 33 | 34 | public function testGetStore() 35 | { 36 | $cart = $this->getCart(); 37 | 38 | $store = $cart->getStore(); 39 | 40 | $this->assertSame($store, PHPUnit_Framework_Assert::readAttribute($cart, 'store')); 41 | } 42 | 43 | public function testAddItem() 44 | { 45 | $cart = $this->getCart(); 46 | $item = new CartItem([ 47 | 'name' => 'foo', 48 | ]); 49 | 50 | // test adding a new item 51 | $cart->add($item); 52 | $cartItems = PHPUnit_Framework_Assert::readAttribute($cart, 'items'); 53 | 54 | $this->assertSame($cartItems[0], $item); 55 | 56 | // test adding the same item again just increases the quantity of the 57 | // existing item 58 | $cart->add($item); 59 | $cartItems = PHPUnit_Framework_Assert::readAttribute($cart, 'items'); 60 | 61 | $this->assertSame($cartItems[0]->quantity, 2); 62 | } 63 | 64 | public function testHasItem() 65 | { 66 | $cart = $this->getCart(); 67 | $item = new CartItem([ 68 | 'name' => 'foo', 69 | ]); 70 | $itemId = $item->id; 71 | 72 | $cart->add($item); 73 | 74 | $this->assertTrue($cart->has($itemId)); 75 | $this->assertFalse($cart->has('foo')); 76 | } 77 | 78 | public function testRemoveItem() 79 | { 80 | $cart = $this->getCart(); 81 | $item = new CartItem([ 82 | 'name' => 'foo', 83 | ]); 84 | $itemId = $item->id; 85 | 86 | $cart->add($item); 87 | $this->assertTrue($cart->has($itemId)); 88 | 89 | $cart->remove($itemId); 90 | $this->assertFalse($cart->has($itemId)); 91 | } 92 | 93 | public function testGetItem() 94 | { 95 | $cart = $this->getCart(); 96 | $item = new CartItem([ 97 | 'name' => 'foo', 98 | ]); 99 | $itemId = $item->id; 100 | 101 | $cart->add($item); 102 | 103 | $this->assertSame($cart->get($itemId), $item); 104 | } 105 | 106 | public function testUpdateItem() 107 | { 108 | $cart = $this->getCart(); 109 | $item = new CartItem([ 110 | 'name' => 'foo', 111 | ]); 112 | $itemId = $item->id; 113 | 114 | $cart->add($item); 115 | $newId = $cart->update($itemId, 'name', 'bar'); 116 | 117 | // test Cart::update returns items new id 118 | $cartItems = PHPUnit_Framework_Assert::readAttribute($cart, 'items'); 119 | $this->assertSame($newId, $cartItems[0]->id); 120 | 121 | // test updating a property of the item 122 | $updatedItem = $cart->get($newId); 123 | 124 | $this->assertSame($updatedItem->name, 'bar'); 125 | 126 | // test trying to update a non existent item 127 | $this->setExpectedException('InvalidArgumentException'); 128 | $cart->update('foo', 'name', 'bar'); 129 | } 130 | 131 | public function testTotalUniqueItems() 132 | { 133 | $cart = $this->getCart(); 134 | 135 | $item1 = new CartItem([ 136 | 'name' => 'foo', 137 | 'quantity' => 2, 138 | ]); 139 | 140 | $item2 = new CartItem([ 141 | 'name' => 'bar', 142 | 'quantity' => 1, 143 | ]); 144 | 145 | $cart->add($item1); 146 | $cart->add($item2); 147 | 148 | $this->assertEquals(2, $cart->totalUniqueItems()); 149 | } 150 | 151 | public function testTotalItems() 152 | { 153 | $cart = $this->getCart(); 154 | 155 | $item1 = new CartItem([ 156 | 'name' => 'foo', 157 | 'quantity' => 2, 158 | ]); 159 | 160 | $item2 = new CartItem([ 161 | 'name' => 'bar', 162 | 'quantity' => 1, 163 | ]); 164 | 165 | $cart->add($item1); 166 | $cart->add($item2); 167 | 168 | $this->assertEquals(3, $cart->totalItems()); 169 | } 170 | 171 | public function testAll() 172 | { 173 | $cart = $this->getCart(); 174 | 175 | $item1 = new CartItem([ 176 | 'name' => 'foo', 177 | ]); 178 | 179 | $item2 = new CartItem([ 180 | 'name' => 'bar', 181 | ]); 182 | 183 | $cart->add($item1); 184 | $cart->add($item2); 185 | 186 | $cartItems = $cart->all(); 187 | 188 | $this->assertTrue(is_array($cartItems)); 189 | $this->assertSame($cartItems, PHPUnit_Framework_Assert::readAttribute($cart, 'items')); 190 | } 191 | 192 | public function testClear() 193 | { 194 | $store = m::mock('Cart\Storage\Store'); 195 | $store->shouldReceive('flush')->times(1); 196 | 197 | $cart = new Cart('foo', $store); 198 | 199 | $item1 = new CartItem([ 200 | 'name' => 'foo', 201 | ]); 202 | 203 | $item2 = new CartItem([ 204 | 'name' => 'bar', 205 | ]); 206 | 207 | $cart->add($item1); 208 | $cart->add($item2); 209 | 210 | $cart->clear(); 211 | 212 | $cartItems = $cart->all(); 213 | 214 | $this->assertTrue(count($cartItems) == 0); 215 | } 216 | 217 | public function testTotal() 218 | { 219 | $cart = $this->getCart(); 220 | 221 | $item1 = new CartItem([ 222 | 'name' => 'foo', 223 | 'price' => 10.00, 224 | 'tax' => 5.00, 225 | 'quantity' => 2, 226 | ]); 227 | 228 | $item2 = new CartItem([ 229 | 'name' => 'bar', 230 | 'price' => 5.00, 231 | 'tax' => 1.00, 232 | 'quantity' => 2, 233 | ]); 234 | 235 | $cart->add($item1); 236 | $cart->add($item2); 237 | 238 | $total = $cart->total(); 239 | 240 | $this->assertTrue(is_float($total)); 241 | $this->assertSame($total, 42.00); 242 | } 243 | 244 | public function testTotalExcludingTax() 245 | { 246 | $cart = $this->getCart(); 247 | 248 | $item1 = new CartItem([ 249 | 'name' => 'foo', 250 | 'price' => 10.00, 251 | 'tax' => 5.00, 252 | 'quantity' => 2, 253 | ]); 254 | 255 | $item2 = new CartItem([ 256 | 'name' => 'bar', 257 | 'price' => 5.00, 258 | 'tax' => 1.00, 259 | 'quantity' => 2, 260 | ]); 261 | 262 | $cart->add($item1); 263 | $cart->add($item2); 264 | 265 | $total = $cart->totalExcludingTax(); 266 | 267 | $this->assertTrue(is_float($total)); 268 | $this->assertSame($total, 30.00); 269 | } 270 | 271 | public function testTax() 272 | { 273 | $cart = $this->getCart(); 274 | 275 | $item1 = new CartItem([ 276 | 'name' => 'foo', 277 | 'price' => 10.00, 278 | 'tax' => 5.00, 279 | 'quantity' => 2, 280 | ]); 281 | 282 | $item2 = new CartItem([ 283 | 'name' => 'bar', 284 | 'price' => 5.00, 285 | 'tax' => 1.00, 286 | 'quantity' => 2, 287 | ]); 288 | 289 | $cart->add($item1); 290 | $cart->add($item2); 291 | 292 | $tax = $cart->tax(false); 293 | 294 | $this->assertTrue(is_float($tax)); 295 | $this->assertSame($tax, 12.00); 296 | } 297 | 298 | public function testSave() 299 | { 300 | $store = m::mock('Cart\Storage\Store'); 301 | $store->shouldReceive('put')->times(1); 302 | 303 | $cart = new Cart('foo', $store); 304 | 305 | $cart->save(); 306 | } 307 | 308 | public function testRestore() 309 | { 310 | $item1 = new CartItem([ 311 | 'name' => 'foo', 312 | ]); 313 | 314 | $item2 = new CartItem([ 315 | 'name' => 'bar', 316 | ]); 317 | 318 | $storeGetReturn = [ 319 | 'id' => 'foo', 320 | 'items' => [ 321 | $item1->toArray(), 322 | $item2->toArray(), 323 | ], 324 | ]; 325 | 326 | $store = m::mock('Cart\Storage\Store'); 327 | $store 328 | ->shouldReceive('get') 329 | ->times(1) 330 | ->andReturn(serialize($storeGetReturn)); 331 | 332 | $cart = new Cart('foo', $store); 333 | 334 | $cart->restore(); 335 | 336 | $this->assertSame('foo', $cart->getId()); 337 | $this->assertTrue($cart->totalUniqueItems() == 2); 338 | $this->assertTrue($cart->has($item1->id)); 339 | $this->assertTrue($cart->has($item2->id)); 340 | } 341 | 342 | public function testEmptyRestore() 343 | { 344 | $store = m::mock('Cart\Storage\Store'); 345 | $store 346 | ->shouldReceive('get') 347 | ->times(1) 348 | ->andReturn(''); 349 | 350 | $cart = new Cart('foo', $store); 351 | 352 | $cart->restore(); // should not throw exception 353 | } 354 | 355 | public function testRestoreExceptions() 356 | { 357 | $exceptionCounter = 0; 358 | 359 | $store = m::mock('Cart\Storage\Store'); 360 | 361 | $store 362 | ->shouldReceive('get') 363 | ->times(6) 364 | ->andReturn( 365 | '!foo!', // unserializable 366 | serialize('bar'), // not array 367 | serialize(['id' => 'foo']), // missing items 368 | serialize(['items' => []]), // missing id 369 | serialize(['id' => [], 'items' => []]), // invalid id 370 | serialize(['items' => 'foo', 'id' => 'foo']) // invalid items 371 | ); 372 | 373 | $cart = new Cart('foo', $store); 374 | 375 | for ($i = 1; $i <= 6; ++$i) { 376 | try { 377 | $cart->restore(); 378 | } catch (CartRestoreException $e) { 379 | ++$exceptionCounter; 380 | } 381 | } 382 | 383 | $this->assertEquals($exceptionCounter, 6); 384 | } 385 | 386 | public function getCart() 387 | { 388 | $store = m::mock('Cart\Storage\Store'); 389 | 390 | return new Cart('foo', $store); 391 | } 392 | } 393 | -------------------------------------------------------------------------------- /vendor/mike182uk/cart/README.md: -------------------------------------------------------------------------------- 1 | # Cart 2 | 3 | [![Packagist](https://img.shields.io/packagist/v/mike182uk/cart.svg?style=flat-square)](https://packagist.org/packages/mike182uk/cart) 4 | [![Build Status](https://img.shields.io/travis/mike182uk/cart.svg?style=flat-square)](http://travis-ci.org/mike182uk/cart) 5 | [![Scrutinizer Quality Score](https://img.shields.io/scrutinizer/g/mike182uk/cart.svg?style=flat-square)](https://scrutinizer-ci.com/g/mike182uk/cart/) 6 | [![SensioLabs Insight](https://img.shields.io/sensiolabs/i/1d82048a-1390-42d5-8605-606541e81c98.svg?style=flat-square)](https://insight.sensiolabs.com/projects/1d82048a-1390-42d5-8605-606541e81c98) 7 | [![Code Coverage](https://img.shields.io/scrutinizer/coverage/g/mike182uk/cart.svg?style=flat-square)](https://scrutinizer-ci.com/g/mike182uk/cart/) 8 | [![Total Downloads](https://img.shields.io/packagist/dt/mike182uk/cart.svg?style=flat-square)](https://packagist.org/packages/mike182uk/cart) 9 | [![License](https://img.shields.io/github/license/mike182uk/cart.svg?style=flat-square)](https://packagist.org/packages/mike182uk/cart) 10 | 11 | A flexible and modern shopping cart package. 12 | 13 | ## Prerequisites 14 | 15 | - PHP >=5.6.0 16 | 17 | ## Installation 18 | 19 | ```bash 20 | composer require mike182uk/cart 21 | ``` 22 | 23 | ## Usage 24 | 25 | - [Cart](#cart) 26 | - [Cart Item](#cart-item) 27 | - [Cart Storage Implementation](#cart-store) 28 | 29 | ### Cart 30 | 31 | #### Create a new cart 32 | 33 | To create a new cart instance you must pass an id and a storage implementation to the cart constructor: 34 | 35 | ```php 36 | use Cart\Cart; 37 | use Cart\Storage\SessionStore; 38 | 39 | $id = 'cart-01'; 40 | $cartSessionStore = new SessionStore(); 41 | 42 | $cart = new Cart($id, $cartSessionStore); 43 | ``` 44 | 45 | The storage implementation must implement `Cart\Storage\Store`. 46 | 47 | The id is used for saving / restoring cart state via the storage implementation. 48 | 49 | #### Add an item to the cart 50 | 51 | Use the `add` method to add an item to the cart. A valid `Cart\CartItem` must be passed to this method. 52 | 53 | ```php 54 | use Cart\CartItem; 55 | 56 | $item = new CartItem; 57 | $item->name = 'Macbook Pro'; 58 | $item->sku = 'MBP8GB'; 59 | $item->price = 1200; 60 | $item->tax = 200; 61 | 62 | $cart->add($item); 63 | ``` 64 | 65 | If the item already exists in the cart, the quantity of the existing item will be updated to include the quantity of the item being added. 66 | 67 | #### Remove an item from the cart 68 | 69 | Remove an item from the cart by passing the item id to the `remove` method. 70 | 71 | ```php 72 | $cart->remove('e4df90d236966195b49b0f01f5ce360a356bc76b'); 73 | ``` 74 | 75 | #### Update an item in the cart 76 | 77 | To update a property of an item in the cart use the `update` method. You will need to pass the cart item id, the name of the property to update and the new value. This method will return the item id (in case it has changed due to the update). 78 | 79 | ```php 80 | $newId = $cart->update('e4df90d236966195b49b0f01f5ce360a356bc76b', 'price', 959.99); 81 | ``` 82 | 83 | If you try and update an item that does not exist in the cart a `InvalidArgumentException` will be thrown. 84 | 85 | #### Retrieve an item in the cart 86 | 87 | Retrieve an item from the cart by its id use the `get` method. If the item does not exist `null` is returned. 88 | 89 | ```php 90 | $item = $cart->get('e4df90d236966195b49b0f01f5ce360a356bc76b'); 91 | 92 | if ($item) { 93 | // ... 94 | } 95 | ``` 96 | 97 | #### Retrieve all items in the cart 98 | 99 | Retrieve all items in the cart using the `all` method. This will return an array of all the items in the cart. 100 | 101 | ```php 102 | $cartItems = $cart->all(); 103 | 104 | if (count($cartItems) > 0) { 105 | foreach ($cartItems as $item) { 106 | // ... 107 | } 108 | } 109 | ``` 110 | 111 | #### Determine if an item exists in the cart 112 | 113 | Determine if an item exists in the cart using the `has` method. Returns `true` or `false`. 114 | 115 | ```php 116 | if ($cart->has('e4df90d236966195b49b0f01f5ce360a356bc76b')) { 117 | // ... 118 | } 119 | ``` 120 | 121 | #### Clear The Cart 122 | 123 | Clear the cart using the `clear` method. 124 | 125 | ```php 126 | $cart->clear(); 127 | ``` 128 | This will also clear the saved state for this cart in the store. 129 | 130 | #### Save / restore cart state 131 | 132 | Save the cart using the `save` method. 133 | 134 | ```php 135 | $cart->save(); 136 | ``` 137 | 138 | This will save the current cart items and cart id to the store. 139 | 140 | Restore the cart using the `restore` method. 141 | 142 | ```php 143 | $cart->restore(); 144 | ``` 145 | 146 | This will add any stored cart items back to the cart and set the cart id. If there is a problem restoring the cart a `Cart\CartRestoreException` will be thrown. This will only happen if: 147 | 148 | - the saved data is unserializable 149 | - the unserialized data is invalid (not an array) 150 | - the cart id is not present in the unserialized data 151 | - the cart items are not present in the unserialized data 152 | - the cart id is invalid (not a string) 153 | - the cart items are invalid (not an array) 154 | 155 | #### Other Cart Methods 156 | 157 | ##### totalUniqueItems 158 | 159 | Get the total number of unique items in the cart. 160 | 161 | ```php 162 | $cart->totalUniqueItems(); 163 | ``` 164 | 165 | ##### totalItems 166 | 167 | Get the total number of items in the cart. 168 | 169 | ```php 170 | $cart->totalItems(); 171 | ``` 172 | 173 | ##### total 174 | 175 | Get the total price of all the cart items including tax. 176 | 177 | ```php 178 | $cart->total(); 179 | ``` 180 | 181 | You can get the total excluding tax by using the `totalExcludingTax` method. 182 | 183 | ```php 184 | $cart->totalExcludingTax(); 185 | ``` 186 | 187 | ##### tax 188 | 189 | Get the total tax of all the cart items. 190 | 191 | ```php 192 | $cart->tax(); 193 | ``` 194 | 195 | ##### toArray 196 | 197 | Export the cart to an array. 198 | 199 | ```php 200 | $cartData = $cart->toArray(); 201 | ``` 202 | 203 | Array will be structured like: 204 | 205 | ```php 206 | [ 207 | 'id' => 'cart-01', // cart id 208 | 'items' => [ 209 | // cart items as array 210 | ] 211 | ] 212 | ``` 213 | 214 | ##### getId 215 | 216 | Get the id of the cart. 217 | 218 | ```php 219 | $cart->getId(); 220 | ``` 221 | 222 | ##### getStore 223 | 224 | Get the cart storage implementation. 225 | 226 | ```php 227 | $cart->getStore(); 228 | ``` 229 | 230 | ### Cart Item 231 | 232 | #### Create a new Cart Item 233 | 234 | ```php 235 | use Cart\CartItem; 236 | 237 | $item = new CartItem; 238 | 239 | $item->name = 'Macbook Pro'; 240 | $item->sku = 'MBP8GB'; 241 | $item->price = 1200; 242 | $item->tax = 200; 243 | $item->options = [ 244 | 'ram' => '8 GB', 245 | 'ssd' => '256 GB' 246 | ]; 247 | ``` 248 | 249 | `Cart\CartItem` implements `ArrayAccess` so properties can be assigned to the cart item as if accessing an array: 250 | 251 | ```php 252 | $item = new CartItem; 253 | 254 | $item['name'] = 'Macbook Pro'; 255 | $item['sku'] = 'MBP8GB'; 256 | $item['price'] = 1200; 257 | $item['tax'] = 200; 258 | $item['options'] = [ 259 | 'ram' => '8 GB', 260 | 'ssd' => '256 GB' 261 | ]; 262 | ``` 263 | 264 | An array of data can also be passed to the cart item constructor to set the cart item properties: 265 | 266 | ```php 267 | $itemData = [ 268 | 'name' => 'Macbook Pro'; 269 | 'sku' => 'MBP8GB'; 270 | 'price' => 1200; 271 | 'tax' => 200; 272 | 'options' => [ 273 | 'ram' => '8 GB', 274 | 'ssd' => '256 GB' 275 | ] 276 | ]; 277 | 278 | $item = new CartItem($itemData); 279 | ``` 280 | 281 | If no quantity is passed to the cart item constructor, the quantity is set to `1` by default. 282 | 283 | If no price is passed to the cart item constructor, the price is set to `0.00` by default. 284 | 285 | If no tax is passed to the cart item constructor, the tax is set to `0.00` by default. 286 | 287 | #### Cart Item ID 288 | 289 | Each cart has a unique ID. This ID is generated using the properties set on the cart item. You can get the cart item ID using the method `getId` or by accessing the property `id`. 290 | 291 | ```php 292 | $id = $item->getId(); 293 | ``` 294 | 295 | ```php 296 | $id = $item->id; 297 | ``` 298 | 299 | ```php 300 | $id = $item['id']; 301 | ``` 302 | 303 | **Changing a property on the cart item will change its ID.** 304 | 305 | #### Cart Item Methods 306 | 307 | #### get 308 | 309 | Get a piece of data set on the cart item. 310 | 311 | ```php 312 | $name = $item->get('name'); 313 | ``` 314 | 315 | This is the same as doing: 316 | 317 | ```php 318 | $name = $item['name']; 319 | ``` 320 | 321 | ```php 322 | $name = $item->name; 323 | ``` 324 | 325 | #### set 326 | 327 | Set a piece of data on the cart item. 328 | 329 | ```php 330 | $item->set('name', 'Macbook Pro'); 331 | ``` 332 | 333 | This is the same as doing: 334 | 335 | ```php 336 | $item['name'] = 'Macbook Pro'; 337 | ``` 338 | 339 | ```php 340 | $item->name = 'Macbook Pro'; 341 | ``` 342 | 343 | If you are setting the item quantity, the value must be an integer otherwise an `InvalidArgumentException` is thrown. 344 | 345 | ```php 346 | $item->quantity = 1; // ok 347 | 348 | $item->quantity = '1' // will throw exception 349 | ``` 350 | 351 | If you are setting the item price or tax, the value must be numeric otherwise an `InvalidArgumentException` is thrown. 352 | 353 | ```php 354 | $item->price = 10.00; // ok 355 | 356 | $item->price = '10' // ok 357 | 358 | $item->price = 'ten' // will throw exception 359 | ``` 360 | 361 | ##### getTotalPrice 362 | 363 | Get the total price of the cart item including tax `((item price + item tax) * quantity)`. 364 | 365 | ```php 366 | $item->getTotalPrice(); 367 | ``` 368 | 369 | You can also get the total price excluding tax `(item price * quantity)` using the `getTotalPriceExcludingTax` method. 370 | 371 | ```php 372 | $item->getTotalPriceExcludingTax(); 373 | ``` 374 | 375 | ##### getSinglePrice 376 | 377 | Get the single price of the cart item including tax `(item price + item tax)` 378 | 379 | ```php 380 | $item->getSinglePrice(); 381 | ``` 382 | 383 | You can also get the single price excluding tax by using the `getSinglePriceExcludingTax` method. 384 | 385 | ```php 386 | $item->getSinglePriceExcludingTax(); 387 | ``` 388 | 389 | ##### getTotalTax 390 | 391 | Get the total tax of the cart item `(item tax * quantity)`. 392 | 393 | ```php 394 | $item->getTotalTax(); 395 | ``` 396 | 397 | ##### getSingleTax 398 | 399 | Get the single tax value of the cart item. 400 | 401 | ```php 402 | $item->getSingleTax(); 403 | ``` 404 | 405 | ##### toArray 406 | 407 | Export the item to an array. 408 | 409 | ```php 410 | $itemArr = $item->toArray(); 411 | ``` 412 | 413 | Array will be structured like: 414 | 415 | ```php 416 | [ 417 | 'id' => 'e4df90d236966195b49b0f01f5ce360a356bc76b', // cart item unique id 418 | 'data' => [ 419 | 'name' => 'Macbook Pro', 420 | 'sku' => 'MBP8GB', 421 | 'price' => 1200, 422 | 423 | // ... other cart item properties 424 | ] 425 | ] 426 | ``` 427 | 428 | ### Cart Storage Implementation 429 | 430 | A cart storage implementation must implement `Cart\Storage\Store`. 431 | 432 | This package provides 2 basic storage implementations: `Cart\Storage\SessionStore` and `Cart\Storage\CookieStore`. 433 | 434 | When the `save` method of the cart is called, the cart id and serialized cart data is passed to the `put` method of the storage implementation. 435 | 436 | When the `restore` method of the cart is called, the cart id is passed to the `get` method of the storage implementation. 437 | 438 | When the `clear` method of the cart is called, the cart id is passed to the `flush` method of the storage implementation. 439 | 440 | An example session storage implementation may look like: 441 | 442 | ```php 443 | use Cart\Store; 444 | 445 | class SessionStore implements Store 446 | { 447 | /** 448 | * {@inheritdoc} 449 | */ 450 | public function get($cartId) 451 | { 452 | return isset($_SESSION[$cartId]) ? $_SESSION[$cartId] : serialize([]); 453 | } 454 | 455 | /** 456 | * {@inheritdoc} 457 | */ 458 | public function put($cartId, $data) 459 | { 460 | $_SESSION[$cartId] = $data; 461 | } 462 | 463 | /** 464 | * {@inheritdoc} 465 | */ 466 | public function flush($cartId) 467 | { 468 | unset($_SESSION[$cartId]); 469 | } 470 | } 471 | ``` 472 | -------------------------------------------------------------------------------- /vendor/composer/ClassLoader.php: -------------------------------------------------------------------------------- 1 | 7 | * Jordi Boggiano 8 | * 9 | * For the full copyright and license information, please view the LICENSE 10 | * file that was distributed with this source code. 11 | */ 12 | 13 | namespace Composer\Autoload; 14 | 15 | /** 16 | * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. 17 | * 18 | * $loader = new \Composer\Autoload\ClassLoader(); 19 | * 20 | * // register classes with namespaces 21 | * $loader->add('Symfony\Component', __DIR__.'/component'); 22 | * $loader->add('Symfony', __DIR__.'/framework'); 23 | * 24 | * // activate the autoloader 25 | * $loader->register(); 26 | * 27 | * // to enable searching the include path (eg. for PEAR packages) 28 | * $loader->setUseIncludePath(true); 29 | * 30 | * In this example, if you try to use a class in the Symfony\Component 31 | * namespace or one of its children (Symfony\Component\Console for instance), 32 | * the autoloader will first look for the class under the component/ 33 | * directory, and it will then fallback to the framework/ directory if not 34 | * found before giving up. 35 | * 36 | * This class is loosely based on the Symfony UniversalClassLoader. 37 | * 38 | * @author Fabien Potencier 39 | * @author Jordi Boggiano 40 | * @see http://www.php-fig.org/psr/psr-0/ 41 | * @see http://www.php-fig.org/psr/psr-4/ 42 | */ 43 | class ClassLoader 44 | { 45 | // PSR-4 46 | private $prefixLengthsPsr4 = array(); 47 | private $prefixDirsPsr4 = array(); 48 | private $fallbackDirsPsr4 = array(); 49 | 50 | // PSR-0 51 | private $prefixesPsr0 = array(); 52 | private $fallbackDirsPsr0 = array(); 53 | 54 | private $useIncludePath = false; 55 | private $classMap = array(); 56 | private $classMapAuthoritative = false; 57 | private $missingClasses = array(); 58 | private $apcuPrefix; 59 | 60 | public function getPrefixes() 61 | { 62 | if (!empty($this->prefixesPsr0)) { 63 | return call_user_func_array('array_merge', $this->prefixesPsr0); 64 | } 65 | 66 | return array(); 67 | } 68 | 69 | public function getPrefixesPsr4() 70 | { 71 | return $this->prefixDirsPsr4; 72 | } 73 | 74 | public function getFallbackDirs() 75 | { 76 | return $this->fallbackDirsPsr0; 77 | } 78 | 79 | public function getFallbackDirsPsr4() 80 | { 81 | return $this->fallbackDirsPsr4; 82 | } 83 | 84 | public function getClassMap() 85 | { 86 | return $this->classMap; 87 | } 88 | 89 | /** 90 | * @param array $classMap Class to filename map 91 | */ 92 | public function addClassMap(array $classMap) 93 | { 94 | if ($this->classMap) { 95 | $this->classMap = array_merge($this->classMap, $classMap); 96 | } else { 97 | $this->classMap = $classMap; 98 | } 99 | } 100 | 101 | /** 102 | * Registers a set of PSR-0 directories for a given prefix, either 103 | * appending or prepending to the ones previously set for this prefix. 104 | * 105 | * @param string $prefix The prefix 106 | * @param array|string $paths The PSR-0 root directories 107 | * @param bool $prepend Whether to prepend the directories 108 | */ 109 | public function add($prefix, $paths, $prepend = false) 110 | { 111 | if (!$prefix) { 112 | if ($prepend) { 113 | $this->fallbackDirsPsr0 = array_merge( 114 | (array) $paths, 115 | $this->fallbackDirsPsr0 116 | ); 117 | } else { 118 | $this->fallbackDirsPsr0 = array_merge( 119 | $this->fallbackDirsPsr0, 120 | (array) $paths 121 | ); 122 | } 123 | 124 | return; 125 | } 126 | 127 | $first = $prefix[0]; 128 | if (!isset($this->prefixesPsr0[$first][$prefix])) { 129 | $this->prefixesPsr0[$first][$prefix] = (array) $paths; 130 | 131 | return; 132 | } 133 | if ($prepend) { 134 | $this->prefixesPsr0[$first][$prefix] = array_merge( 135 | (array) $paths, 136 | $this->prefixesPsr0[$first][$prefix] 137 | ); 138 | } else { 139 | $this->prefixesPsr0[$first][$prefix] = array_merge( 140 | $this->prefixesPsr0[$first][$prefix], 141 | (array) $paths 142 | ); 143 | } 144 | } 145 | 146 | /** 147 | * Registers a set of PSR-4 directories for a given namespace, either 148 | * appending or prepending to the ones previously set for this namespace. 149 | * 150 | * @param string $prefix The prefix/namespace, with trailing '\\' 151 | * @param array|string $paths The PSR-4 base directories 152 | * @param bool $prepend Whether to prepend the directories 153 | * 154 | * @throws \InvalidArgumentException 155 | */ 156 | public function addPsr4($prefix, $paths, $prepend = false) 157 | { 158 | if (!$prefix) { 159 | // Register directories for the root namespace. 160 | if ($prepend) { 161 | $this->fallbackDirsPsr4 = array_merge( 162 | (array) $paths, 163 | $this->fallbackDirsPsr4 164 | ); 165 | } else { 166 | $this->fallbackDirsPsr4 = array_merge( 167 | $this->fallbackDirsPsr4, 168 | (array) $paths 169 | ); 170 | } 171 | } elseif (!isset($this->prefixDirsPsr4[$prefix])) { 172 | // Register directories for a new namespace. 173 | $length = strlen($prefix); 174 | if ('\\' !== $prefix[$length - 1]) { 175 | throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); 176 | } 177 | $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; 178 | $this->prefixDirsPsr4[$prefix] = (array) $paths; 179 | } elseif ($prepend) { 180 | // Prepend directories for an already registered namespace. 181 | $this->prefixDirsPsr4[$prefix] = array_merge( 182 | (array) $paths, 183 | $this->prefixDirsPsr4[$prefix] 184 | ); 185 | } else { 186 | // Append directories for an already registered namespace. 187 | $this->prefixDirsPsr4[$prefix] = array_merge( 188 | $this->prefixDirsPsr4[$prefix], 189 | (array) $paths 190 | ); 191 | } 192 | } 193 | 194 | /** 195 | * Registers a set of PSR-0 directories for a given prefix, 196 | * replacing any others previously set for this prefix. 197 | * 198 | * @param string $prefix The prefix 199 | * @param array|string $paths The PSR-0 base directories 200 | */ 201 | public function set($prefix, $paths) 202 | { 203 | if (!$prefix) { 204 | $this->fallbackDirsPsr0 = (array) $paths; 205 | } else { 206 | $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; 207 | } 208 | } 209 | 210 | /** 211 | * Registers a set of PSR-4 directories for a given namespace, 212 | * replacing any others previously set for this namespace. 213 | * 214 | * @param string $prefix The prefix/namespace, with trailing '\\' 215 | * @param array|string $paths The PSR-4 base directories 216 | * 217 | * @throws \InvalidArgumentException 218 | */ 219 | public function setPsr4($prefix, $paths) 220 | { 221 | if (!$prefix) { 222 | $this->fallbackDirsPsr4 = (array) $paths; 223 | } else { 224 | $length = strlen($prefix); 225 | if ('\\' !== $prefix[$length - 1]) { 226 | throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); 227 | } 228 | $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; 229 | $this->prefixDirsPsr4[$prefix] = (array) $paths; 230 | } 231 | } 232 | 233 | /** 234 | * Turns on searching the include path for class files. 235 | * 236 | * @param bool $useIncludePath 237 | */ 238 | public function setUseIncludePath($useIncludePath) 239 | { 240 | $this->useIncludePath = $useIncludePath; 241 | } 242 | 243 | /** 244 | * Can be used to check if the autoloader uses the include path to check 245 | * for classes. 246 | * 247 | * @return bool 248 | */ 249 | public function getUseIncludePath() 250 | { 251 | return $this->useIncludePath; 252 | } 253 | 254 | /** 255 | * Turns off searching the prefix and fallback directories for classes 256 | * that have not been registered with the class map. 257 | * 258 | * @param bool $classMapAuthoritative 259 | */ 260 | public function setClassMapAuthoritative($classMapAuthoritative) 261 | { 262 | $this->classMapAuthoritative = $classMapAuthoritative; 263 | } 264 | 265 | /** 266 | * Should class lookup fail if not found in the current class map? 267 | * 268 | * @return bool 269 | */ 270 | public function isClassMapAuthoritative() 271 | { 272 | return $this->classMapAuthoritative; 273 | } 274 | 275 | /** 276 | * APCu prefix to use to cache found/not-found classes, if the extension is enabled. 277 | * 278 | * @param string|null $apcuPrefix 279 | */ 280 | public function setApcuPrefix($apcuPrefix) 281 | { 282 | $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null; 283 | } 284 | 285 | /** 286 | * The APCu prefix in use, or null if APCu caching is not enabled. 287 | * 288 | * @return string|null 289 | */ 290 | public function getApcuPrefix() 291 | { 292 | return $this->apcuPrefix; 293 | } 294 | 295 | /** 296 | * Registers this instance as an autoloader. 297 | * 298 | * @param bool $prepend Whether to prepend the autoloader or not 299 | */ 300 | public function register($prepend = false) 301 | { 302 | spl_autoload_register(array($this, 'loadClass'), true, $prepend); 303 | } 304 | 305 | /** 306 | * Unregisters this instance as an autoloader. 307 | */ 308 | public function unregister() 309 | { 310 | spl_autoload_unregister(array($this, 'loadClass')); 311 | } 312 | 313 | /** 314 | * Loads the given class or interface. 315 | * 316 | * @param string $class The name of the class 317 | * @return bool|null True if loaded, null otherwise 318 | */ 319 | public function loadClass($class) 320 | { 321 | if ($file = $this->findFile($class)) { 322 | includeFile($file); 323 | 324 | return true; 325 | } 326 | } 327 | 328 | /** 329 | * Finds the path to the file where the class is defined. 330 | * 331 | * @param string $class The name of the class 332 | * 333 | * @return string|false The path if found, false otherwise 334 | */ 335 | public function findFile($class) 336 | { 337 | // class map lookup 338 | if (isset($this->classMap[$class])) { 339 | return $this->classMap[$class]; 340 | } 341 | if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { 342 | return false; 343 | } 344 | if (null !== $this->apcuPrefix) { 345 | $file = apcu_fetch($this->apcuPrefix.$class, $hit); 346 | if ($hit) { 347 | return $file; 348 | } 349 | } 350 | 351 | $file = $this->findFileWithExtension($class, '.php'); 352 | 353 | // Search for Hack files if we are running on HHVM 354 | if (false === $file && defined('HHVM_VERSION')) { 355 | $file = $this->findFileWithExtension($class, '.hh'); 356 | } 357 | 358 | if (null !== $this->apcuPrefix) { 359 | apcu_add($this->apcuPrefix.$class, $file); 360 | } 361 | 362 | if (false === $file) { 363 | // Remember that this class does not exist. 364 | $this->missingClasses[$class] = true; 365 | } 366 | 367 | return $file; 368 | } 369 | 370 | private function findFileWithExtension($class, $ext) 371 | { 372 | // PSR-4 lookup 373 | $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; 374 | 375 | $first = $class[0]; 376 | if (isset($this->prefixLengthsPsr4[$first])) { 377 | foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) { 378 | if (0 === strpos($class, $prefix)) { 379 | foreach ($this->prefixDirsPsr4[$prefix] as $dir) { 380 | if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) { 381 | return $file; 382 | } 383 | } 384 | } 385 | } 386 | } 387 | 388 | // PSR-4 fallback dirs 389 | foreach ($this->fallbackDirsPsr4 as $dir) { 390 | if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { 391 | return $file; 392 | } 393 | } 394 | 395 | // PSR-0 lookup 396 | if (false !== $pos = strrpos($class, '\\')) { 397 | // namespaced class name 398 | $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) 399 | . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); 400 | } else { 401 | // PEAR-like class name 402 | $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; 403 | } 404 | 405 | if (isset($this->prefixesPsr0[$first])) { 406 | foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { 407 | if (0 === strpos($class, $prefix)) { 408 | foreach ($dirs as $dir) { 409 | if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { 410 | return $file; 411 | } 412 | } 413 | } 414 | } 415 | } 416 | 417 | // PSR-0 fallback dirs 418 | foreach ($this->fallbackDirsPsr0 as $dir) { 419 | if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { 420 | return $file; 421 | } 422 | } 423 | 424 | // PSR-0 include paths. 425 | if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { 426 | return $file; 427 | } 428 | 429 | return false; 430 | } 431 | } 432 | 433 | /** 434 | * Scope isolated include. 435 | * 436 | * Prevents access to $this/self from included files. 437 | */ 438 | function includeFile($file) 439 | { 440 | include $file; 441 | } 442 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ShoppingCart - REDAXO Warenkorb AddOn 2 | 3 | Ein flexibles, modernes Warenkorb-Framework (ohne Bezahlprozess) 4 | 5 | ## Voraussetzungen 6 | 7 | - REDAXO >= 5.1.0 8 | - PHP >= 5.6.0 9 | 10 | ## Installation 11 | 12 | * Release herunterladen und entpacken. 13 | * Ordner umbenennen in `shoppingcart`. 14 | * In den Addons-Ordner legen: /redaxo/src/addons. 15 | 16 | Oder den REDAXO-Installer / ZIP-Upload AddOn nutzen! 17 | 18 | ## Navigation 19 | 20 | - [Warenkorb](#cart) 21 | - [Artikel](#cart-item) 22 | - [Warenkorb Storage Implementation](#cart-store) 23 | 24 | ### Warenkorb 25 | 26 | #### Einen neuen Warenkorb erstellen 27 | 28 | Um eine neue Warenkorb-Instanz zu erstellen, musst du eine ID und eine Storage Implementation übermitteln. 29 | Wie man eigene Storage Implementationen zur Verfügung stellt, erfährst du am Ende der README. 30 | 31 | ```php 32 | /* 33 | die beiden Parameter sind optional, per Default wird die SessionID und die SessionStore Implementation genutzt. 34 | möchtest du mehrere Warenkörbe pro User gleichzeitig zur Verfügung stellen, solltest du immer eine eigene ID übergeben. 35 | public static function factory($cartId = null, $storageImplementation = 'Cart\Storage\SessionStore') 36 | Möchtest du den CookieStore nutzen, bitte "Cart\Storage\CookieStore" nutzen. Der CookieStore überlebt auch neue Sessions. 37 | */ 38 | $cart = ShoppingCart::factory($id, $cartSessionStore); 39 | ``` 40 | 41 | Die Storage Implementation muss `Cart\Storage\Store` implementieren. 42 | Die Id wird zum Speichern / Wiederherstellen der Warenkorb-Storage Implementation genutzt. 43 | 44 | Aktuell gibt es 45 | * Cart\Storage\SessionStore 46 | * Cart\Storage\CookieStore 47 | * Cart\Storage\MemcachedStore 48 | * Cart\Storage\MemcacheStore 49 | * Cart\Storage\RedisStore 50 | 51 | Unter [Warenkorb Storage Implementation](#cart-store) wird noch mal genauer erklärt, wie Memcache(d) und Redis konfiguriert werden können. 52 | 53 | #### Einen Artikel zum Warenkorb hinzufügen 54 | 55 | Benutze die `add` Methode um einen Artikel zum Warenkorb hinzuzufügen. Ein gültiges `Cart\CartItem` muss der Methode übergeben werden. Der Namespace wird bereits automatisch von ShoppingCartItem gesetzt, nur interessant, falls du den Wrapper nicht nutzen möchtest. (siehe vendor-lib) 56 | 57 | ```php 58 | $item = new ShoppingCartItem; 59 | $item->name = 'Macbook Pro'; 60 | $item->sku = 'MBP8GB'; 61 | $item->price = 1200; 62 | $item->tax = 200; 63 | // du kannst unbegrenzt eigene Keys mit eigenen Werten hinzufügen, z.B 64 | // $item->description = "Meine Beschreibung zu diesem Artikel"; 65 | // bitte beachte, das Price und Tax nur gültige Zahlen erwarten 66 | 67 | // hier die Warenkorb Instanz nutzen um den Artikel hinzuzufügen 68 | $cart->add($item); 69 | ``` 70 | Wenn der Artikel bereits im Warenkorb existiert, wird die Menge um 1 erhöht. 71 | 72 | #### Einen Artikel aus dem Warenkorb entfernen 73 | 74 | Um einen Artikel aus dem Warenkorb zu entfernen, musst du die interne, vom AddOn generierte Item-Id nutzen und die `remove` Methode aufrufen. 75 | 76 | ```php 77 | $cart->remove('e4df90d236966195b49b0f01f5ce360a356bc76b'); 78 | // diese ID ist nicht deine Datenbank-ID oder Artikel-Id, sondern die Warenkorb-Item-Id. 79 | // du kommst an diesen Wert über $item->getId() (z.B. in deiner Warenkorb-Ausgabe, als hidden input-feld oder auf einen "Mülleimer-Icon" 80 | ``` 81 | 82 | #### Artikel im Warenkorb aktualisieren 83 | 84 | Um eine Eigenschaft eines Artikels im Warenkorb zu ändern, muss die `update` Methode genutzt werden. Du musst die Warenkorb-Artikel-Id, den Namen der Eigenschaft (der "Key", z.B. `price`) und den neuen Wert übermitteln. Die Methode wird dir die neue Warenkorb-Artikel-ID als Rückgabe übermitteln (falls es sich durch das Update verändert hat) 85 | 86 | ```php 87 | $newId = $cart->update('e4df90d236966195b49b0f01f5ce360a356bc76b', 'price', 959.99); 88 | ``` 89 | 90 | Wenn du versuchst einen Artikel im Warenkorb zu verändern, welcher nicht existiert, wird ein `InvalidArgumentException` geworfen. 91 | 92 | #### Einen Artikel-Objekt aus dem Warenkorb holen 93 | 94 | Hol dir ein Artikel-Objekt aus dem Warenkorb mit der Warenkorb-Artikel-ID und der `get` Methode. Wenn der Artikel nicht existiert, wird `null` zurückgegeben. 95 | 96 | ```php 97 | $item = $cart->get('e4df90d236966195b49b0f01f5ce360a356bc76b'); 98 | 99 | if ($item) { 100 | // ... 101 | } 102 | ``` 103 | 104 | #### Alle Artikel aus dem Warenkorb holen 105 | 106 | Hole alle Artikel aus dem Warenkorb mit der `all` Methode. Es wird ein `array` aller Artikel aus dem Warenkorb zurückgegeben. 107 | 108 | ```php 109 | $cartItems = $cart->all(); 110 | 111 | if (count($cartItems) > 0) { 112 | foreach ($cartItems as $item) { 113 | // ... 114 | } 115 | } 116 | ``` 117 | 118 | #### Prüfen, ob ein Artikel im Warenkorb existiert 119 | 120 | Prüft ob ein Artikel im Warenkorb existiert. Nutze dazu die `has` Methode. Liefert `true` or `false` zurück. 121 | 122 | ```php 123 | if ($cart->has('e4df90d236966195b49b0f01f5ce360a356bc76b')) { 124 | // ... 125 | } 126 | ``` 127 | 128 | #### Den Warenkorb leeren 129 | 130 | Leere den Warenkorb mit der `clear` Methode. 131 | 132 | ```php 133 | $cart->clear(); 134 | ``` 135 | Diese Methode leert auch den gespeicherten State für den ausgewählten Warenkorb. 136 | 137 | #### Warenkorb State speichern / wiederherstellen 138 | 139 | Du kannst den aktuellen Warenkorb mit der `save` Methode speichern. 140 | 141 | ```php 142 | $cart->save(); 143 | ``` 144 | 145 | Die Methode wird die aktuellen Warenkorb-Artikel und Warenkorb-ID in den Store speichern. 146 | Du kannst den Warenkorb wiederherstellen, indem du die `restore` Methode verwendest. 147 | 148 | ```php 149 | $cart->restore(); 150 | ``` 151 | Diese Methode wird alle zwischengespeicherten Artikel wieder zum Warenkorb hinzufügen und die Warenkorb-Id setzen. Falls es ein Problem geben sollte, wird ein `Cart\CartRestoreException` geworfen. Dies passiert nur, wenn: 152 | 153 | - Die gespeicherten Daten nicht serialisiert werden können 154 | - Die nicht-serialisierten Daten ungülig sind (kein array) 155 | - Die Warenkorb-Id nicht in den unserialisierten Daten vorhanden ist 156 | - Die Warenkorb-Artikel nicht in den unserialisierten Daten vorhanden sind 157 | - Die Warenkorb-ID ungültig ist (kein String) 158 | - Die Warenkorb-Artikel ungültig sind (kein Array) 159 | 160 | #### Weitere Warenkorb-Methoden 161 | 162 | ##### Alle einzigartiken Artikel (totalUniqueItems) 163 | 164 | Liefert die gesamte Anzahl der eindeutigen Artikel (ohne Mengen einzelner Artikel) im Warenkorb. 165 | 166 | ```php 167 | $cart->totalUniqueItems(); 168 | ``` 169 | 170 | ##### Alle Artikel (totalItems) 171 | 172 | Liefert die Anzahl aller Artikel (inkl. Mengen) aus dem Warenkorb 173 | 174 | ```php 175 | $cart->totalItems(); 176 | ``` 177 | 178 | ##### Gesamtsumme (total) 179 | 180 | Die Gesamtsumme aller Artikel aus dem Warenkorb inkl. Steuern. (Brutto) 181 | 182 | ```php 183 | $cart->total(); 184 | ``` 185 | 186 | Du kannst die Gesamtsumme auch Netto (ohne Steuern) aus dem Warenkorb holen. Dazu nutzt du einfach die `totalExcludingTax` Methode. 187 | 188 | ```php 189 | $cart->totalExcludingTax(); 190 | ``` 191 | 192 | ##### Steuern (tax) 193 | 194 | Die Gesamtsumme der Steuern für alle Artikel im Warenkorb. 195 | 196 | ```php 197 | $cart->tax(); 198 | ``` 199 | 200 | ##### toArray 201 | 202 | Liefert den Warenkorb-Inhalt als `array` 203 | 204 | ```php 205 | $cartData = $cart->toArray(); 206 | ``` 207 | 208 | Das Array wird folgendermaßen strukturiert sein: 209 | 210 | ```php 211 | [ 212 | 'id' => 'xxyfwq3235werw23wer...', // Warenkorb-ID 213 | 'items' => [ 214 | // Warenkorb-Artikel als Array 215 | ] 216 | ] 217 | ``` 218 | 219 | ##### getId 220 | 221 | Liefert die ID des Warenkorbs (Default: session_id(), wenn kein eigener Wert übergeben wurde) 222 | 223 | ```php 224 | $cart->getId(); 225 | ``` 226 | 227 | ##### getStore 228 | 229 | Zeigt an, welche Storage Implementation genutzt wurde (Default: SessionStore) 230 | 231 | ```php 232 | $cart->getStore(); 233 | ``` 234 | 235 | ### Warenkorb Artikel 236 | 237 | #### Füge einen Artikel zum Warenkorb hinzu 238 | 239 | ```php 240 | $item = new ShoppingCartItem; 241 | 242 | $item->name = 'Macbook Pro'; 243 | $item->sku = 'MBP8GB'; 244 | $item->price = 1200; 245 | $item->tax = 200; 246 | // oder jeder eigene Key, z.B: 247 | // $item->description = "Meine Beschreibung"; 248 | $item->options = [ 249 | 'ram' => '8 GB', 250 | 'ssd' => '256 GB' 251 | ]; 252 | 253 | // hier wird erst hinzugefügt, bitte $cart Objekt nutzen. 254 | $cart->add($item); 255 | ``` 256 | 257 | `Cart\CartItem` implementiert `ArrayAccess` so dass die Eigenschaften des Artikels auch wie ein Array behandelt werden können: 258 | 259 | ```php 260 | $item = new ShoppingCartItem; 261 | 262 | $item['name'] = 'Macbook Pro'; 263 | $item['sku'] = 'MBP8GB'; 264 | $item['price'] = 1200; 265 | $item['tax'] = 200; 266 | // oder $item['description'] oder $item['wasauchimmer'] 267 | $item['options'] = [ 268 | 'ram' => '8 GB', 269 | 'ssd' => '256 GB' 270 | ]; 271 | 272 | // hier wird erst hinzugefügt, bitte $cart Objekt nutzen. 273 | $cart->add($item); 274 | ``` 275 | 276 | Die Daten können auch direkt als Array an den Warenkorb-Artikel Konstruktor übergeben werden: 277 | 278 | ```php 279 | $itemData = [ 280 | 'name' => 'Macbook Pro', 281 | 'sku' => 'MBP8GB', 282 | 'price' => 1200, 283 | 'tax' => 200, 284 | 'whatever' => 'Mein Wert', 285 | 'options' => [ 286 | 'ram' => '8 GB', 287 | 'ssd' => '256 GB' 288 | ] 289 | ]; 290 | 291 | $item = new ShoppingCartItem($itemData); 292 | 293 | // hier wird erst hinzugefügt, bitte $cart Objekt nutzen. 294 | $cart->add($item); 295 | ``` 296 | 297 | * Wird keine Menge (`quantity`) an den Konstruktor übergeben, wird `quantity` per default auf `1` gesetzt. Die Menge kann also auch gleich beeinflusst werden. 298 | * Wird kein Preis (`price`) übergeben, wird per default `0.00` für den Artikel gesetzt. 299 | * Wird keine Steuer (`tax`) übergeben wird per default `0.00` für den Artikel gesetzt. Bitte beachte, dass du die Steuer pro Artikel selbst berechnen musst. Dadurch bist du für jedes Land, jede Steuerart etc. flexibel. Eine einfache, eigene 19 % Berechnung ist auch schnell umgesetzt. Falls du nicht weisst wie, schreib ein Issue. 300 | 301 | #### Warenkorb-Artikel ID 302 | 303 | Jeder Artikel hat eine einzigartige ID. Diese ID wird anhand der Artikeleigenschaften automatisch generiert. Du kannst die ID mit der `getId` Methode oder der Eigenschaft `id` aufrufen. 304 | Die interne ID kann nicht selbst gesetzt werden. Falls du eine Relation zu deiner Datenbank benötigst, kannst du eine eigene Eigenschaft mittels `$item->meinIdKey = 'foobar'` setzen. 305 | 306 | ```php 307 | $id = $item->getId(); 308 | ``` 309 | 310 | ```php 311 | $id = $item->id; 312 | ``` 313 | 314 | ```php 315 | $id = $item['id']; 316 | ``` 317 | 318 | **Wird eine Eigenschaft (also ein Artikel-Key) geändert, verändert sich auch die interne Artikel-ID.** 319 | 320 | #### Warenkorb-Artikel Methoden 321 | 322 | #### get 323 | 324 | Hol dir den Wert einer Artikel Eigeschaft über seinen Keynamen. 325 | 326 | ```php 327 | $name = $item->get('name'); 328 | ``` 329 | 330 | Ist nur eine Abkürzung für: 331 | 332 | ```php 333 | $name = $item['name']; 334 | ``` 335 | 336 | ```php 337 | $name = $item->name; 338 | ``` 339 | 340 | #### set 341 | 342 | Setze einen Wert für einen Artikel: 343 | 344 | ```php 345 | $item->set('name', 'Macbook Pro'); 346 | ``` 347 | 348 | Ist nur eine Abkürzung für: 349 | 350 | ```php 351 | $item['name'] = 'Macbook Pro'; 352 | ``` 353 | 354 | ```php 355 | $item->name = 'Macbook Pro'; 356 | ``` 357 | 358 | Wenn du die Menge (`quantity`) setzt, muss der Wert ein `integer` sein, ansonsten wird ein `InvalidArgumentException` geworfen. 359 | 360 | ```php 361 | $item->quantity = 1; // ok 362 | $item->quantity = '1' // wird einen Fehler werfen 363 | ``` 364 | 365 | Wenn du für einen Artikel den Preis oder die Steuer setzt, muss der Wert numerisch (`numeric`) sein, ansonsten wird ein `InvalidArgumentException` geworfen. 366 | 367 | ```php 368 | $item->price = 10.00; // ok 369 | $item->price = '10' // ok 370 | $item->price = 'ten' // wird einen Fehler werfen 371 | ``` 372 | 373 | ##### getTotalPrice 374 | 375 | Liefert den gesamten Preis eines Artikels mit Steuern (Brutto). `((artikel preis + artikel steuer) * menge)` [`((item price + item tax) * quantity)] 376 | 377 | ```php 378 | $item->getTotalPrice(); 379 | ``` 380 | 381 | Du kannst die Gesamtsumme des Artikels auch ohne Steuern ermitteln (Netto). Nutze dazu einfach die Methode `getTotalPriceExcludingTax`. `(item price * quantity)` 382 | 383 | ```php 384 | $item->getTotalPriceExcludingTax(); 385 | ``` 386 | 387 | ##### getSinglePrice 388 | 389 | Ermittle den Einzelpreis des Artikels im Warenkorb inkl. Steuern `(item price + item tax)` 390 | 391 | ```php 392 | $item->getSinglePrice(); 393 | ``` 394 | 395 | Ohne Steuern nutzt du einfach die `getSinglePriceExcludingTax` Methode. 396 | 397 | ```php 398 | $item->getSinglePriceExcludingTax(); 399 | ``` 400 | 401 | ##### getTotalTax 402 | 403 | Liefert die Gesammtsumme der Steuern für den gewählten Artikel, abhängig zur Menge `(item tax * quantity)`. 404 | 405 | ```php 406 | $item->getTotalTax(); 407 | ``` 408 | 409 | ##### getSingleTax 410 | 411 | Liefert die Gesamtsumme der Steuern für den gewählten Artikel unabhängig von der Menge. 412 | 413 | ```php 414 | $item->getSingleTax(); 415 | ``` 416 | 417 | ##### toArray 418 | 419 | Liefert den Artikel als Array. 420 | 421 | ```php 422 | $itemArr = $item->toArray(); 423 | ``` 424 | 425 | Array wird folgendermaßen strukturiert sein: 426 | 427 | ```php 428 | [ 429 | 'id' => 'e4df90d236966195b49b0f01f5ce360a356bc76b', // einzigartike Warenkorb-Artikel-Id 430 | 'data' => [ 431 | 'name' => 'Macbook Pro', 432 | 'sku' => 'MBP8GB', 433 | 'price' => 1200, 434 | 435 | // ... weitere Artikel Eigenschaften 436 | ] 437 | ] 438 | ``` 439 | 440 | ### Warenkorb Storage Implementation 441 | 442 | Ein Warenkorb Storage muss `Cart\Storage\Store` implementieren. 443 | 444 | Das AddOn liefern einige Basis Sicherungs-Implementations: `Cart\Storage\SessionStore`, `Cart\Storage\CookieStore`, `Cart\Storage\MemcachedStore`, `Cart\Storage\MemcacheStore`, `Cart\Storage\RedisStore`. 445 | 446 | Memcache(d) und Redis laufen Out-of-the-box, wenn die Einstellungen per Default eingestellt sind. Authentifizierung wird nicht unterstützt. Sollte das gewünscht sein, kannst du die Classes unter eigenem Namen duplizieren (zu finden unter lib/Storage). Es kann der Port und der Server eingestellt werden. 447 | 448 | ```php 449 | $cart = ShoppingCart::factory($id = null, (new Cart\Storage\MemcachedStore($server, $port, $expireInMillisekunden))) 450 | $cart = ShoppingCart::factory($id = null, (new Cart\Storage\MemcacheStore($server, $port, $expireInMillisekunden))) 451 | $cart = ShoppingCart::factory($id = null, (new Cart\Storage\RedisStor($server, $port, $expireInSekunden))) 452 | ``` 453 | 454 | Wenn die `save` Methode des Warenkorbs aufgerufen wird, übermittelt das AddOn die Warenkorb-ID und die serialisierten Daten an die `put` Methode der Storage Implementation. 455 | 456 | Wenn die `restore` Methode des Warenkorbs aufgerufen wird, übermittelt das AddOn die Warenkorb-ID an die `get` Methode der Storage Implementation. 457 | 458 | Wenn die `clear` Methode des Warenkorbs aufgerufen wird, übermittelt das AddOn die Warenkorb-ID an die `flush` Methode der Storage Implementation. 459 | 460 | Eine Beispiel-Implementation könnte so aussehen (kannst du mit Redis, Memcached, MySQL oder wie auch immer umsetzen. Erstelle einfach eine Klasse dazu und leg diese in deinem project AddOn unter "lib" ab) 461 | 462 | ```php 463 | use Cart\Store; 464 | 465 | class SessionStore implements Store 466 | { 467 | /** 468 | * {@inheritdoc} 469 | */ 470 | public function get($cartId) 471 | { 472 | return isset($_SESSION[$cartId]) ? $_SESSION[$cartId] : serialize([]); 473 | } 474 | 475 | /** 476 | * {@inheritdoc} 477 | */ 478 | public function put($cartId, $data) 479 | { 480 | $_SESSION[$cartId] = $data; 481 | } 482 | 483 | /** 484 | * {@inheritdoc} 485 | */ 486 | public function flush($cartId) 487 | { 488 | unset($_SESSION[$cartId]); 489 | } 490 | } 491 | ``` 492 | 493 | # Beispiel Modulausgabe 494 | 495 | ```php 496 | 'Macbook Pro', 501 | 'sku' => 'MBP8GB', 502 | 'price' => 1200, 503 | 'tax' => 200, 504 | 'options' => [ 505 | 'ram' => '8 GB', 506 | 'ssd' => '256 GB' 507 | ] 508 | ]; 509 | $item = new ShoppingCartItem($itemData); 510 | $cart->add($item); 511 | 512 | dump($item); 513 | 514 | $item = new ShoppingCartItem; 515 | $item->name = 'Macbook Pro'; 516 | $item->sku = 'MBP8GB'; 517 | $item->price = 1200; 518 | $item->tax = 200; 519 | $item->meinkey = 'is cool'; 520 | $cart->add($item); 521 | 522 | $cart->update($item->getId(), 'price', 959.99); 523 | 524 | dump($item); 525 | dump($item->getId()); 526 | dump($cart); 527 | dump($cart->getStore()); 528 | dump($cart->getId()); 529 | dump($cart->toArray()); 530 | ``` 531 | 532 | # Credits 533 | - Addon, deutsche Doku und Anpassungen für Redaxo by @Hirbod 534 | - @mike182uk, für das Herz dieses AddOns https://github.com/mike182uk/cart 535 | -------------------------------------------------------------------------------- /vendor/mike182uk/cart/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 | "content-hash": "7e548b49065b4bf63469bbe8acf37308", 8 | "packages": [], 9 | "packages-dev": [ 10 | { 11 | "name": "doctrine/instantiator", 12 | "version": "1.0.5", 13 | "source": { 14 | "type": "git", 15 | "url": "https://github.com/doctrine/instantiator.git", 16 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" 17 | }, 18 | "dist": { 19 | "type": "zip", 20 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", 21 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", 22 | "shasum": "" 23 | }, 24 | "require": { 25 | "php": ">=5.3,<8.0-DEV" 26 | }, 27 | "require-dev": { 28 | "athletic/athletic": "~0.1.8", 29 | "ext-pdo": "*", 30 | "ext-phar": "*", 31 | "phpunit/phpunit": "~4.0", 32 | "squizlabs/php_codesniffer": "~2.0" 33 | }, 34 | "type": "library", 35 | "extra": { 36 | "branch-alias": { 37 | "dev-master": "1.0.x-dev" 38 | } 39 | }, 40 | "autoload": { 41 | "psr-4": { 42 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" 43 | } 44 | }, 45 | "notification-url": "https://packagist.org/downloads/", 46 | "license": [ 47 | "MIT" 48 | ], 49 | "authors": [ 50 | { 51 | "name": "Marco Pivetta", 52 | "email": "ocramius@gmail.com", 53 | "homepage": "http://ocramius.github.com/" 54 | } 55 | ], 56 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", 57 | "homepage": "https://github.com/doctrine/instantiator", 58 | "keywords": [ 59 | "constructor", 60 | "instantiate" 61 | ], 62 | "time": "2015-06-14T21:17:01+00:00" 63 | }, 64 | { 65 | "name": "friendsofphp/php-cs-fixer", 66 | "version": "v2.0.0", 67 | "source": { 68 | "type": "git", 69 | "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", 70 | "reference": "f3baf72eb2f58bf275b372540f5b47d25aed910f" 71 | }, 72 | "dist": { 73 | "type": "zip", 74 | "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/f3baf72eb2f58bf275b372540f5b47d25aed910f", 75 | "reference": "f3baf72eb2f58bf275b372540f5b47d25aed910f", 76 | "shasum": "" 77 | }, 78 | "require": { 79 | "ext-tokenizer": "*", 80 | "php": "^5.3.6 || >=7.0 <7.2", 81 | "sebastian/diff": "^1.1", 82 | "symfony/console": "^2.3 || ^3.0", 83 | "symfony/event-dispatcher": "^2.1 || ^3.0", 84 | "symfony/filesystem": "^2.4 || ^3.0", 85 | "symfony/finder": "^2.2 || ^3.0", 86 | "symfony/polyfill-php54": "^1.0", 87 | "symfony/process": "^2.3 || ^3.0", 88 | "symfony/stopwatch": "^2.5 || ^3.0" 89 | }, 90 | "conflict": { 91 | "hhvm": "<3.9" 92 | }, 93 | "require-dev": { 94 | "gecko-packages/gecko-php-unit": "^2.0", 95 | "phpunit/phpunit": "^4.5|^5", 96 | "satooshi/php-coveralls": "^1.0" 97 | }, 98 | "bin": [ 99 | "php-cs-fixer" 100 | ], 101 | "type": "application", 102 | "extra": { 103 | "branch-alias": { 104 | "dev-master": "2.0-dev" 105 | } 106 | }, 107 | "autoload": { 108 | "psr-4": { 109 | "PhpCsFixer\\": "src/" 110 | } 111 | }, 112 | "notification-url": "https://packagist.org/downloads/", 113 | "license": [ 114 | "MIT" 115 | ], 116 | "authors": [ 117 | { 118 | "name": "Dariusz Rumiński", 119 | "email": "dariusz.ruminski@gmail.com" 120 | }, 121 | { 122 | "name": "Fabien Potencier", 123 | "email": "fabien@symfony.com" 124 | } 125 | ], 126 | "description": "A tool to automatically fix PHP code style", 127 | "time": "2016-12-01T06:18:06+00:00" 128 | }, 129 | { 130 | "name": "hamcrest/hamcrest-php", 131 | "version": "v1.2.2", 132 | "source": { 133 | "type": "git", 134 | "url": "https://github.com/hamcrest/hamcrest-php.git", 135 | "reference": "b37020aa976fa52d3de9aa904aa2522dc518f79c" 136 | }, 137 | "dist": { 138 | "type": "zip", 139 | "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/b37020aa976fa52d3de9aa904aa2522dc518f79c", 140 | "reference": "b37020aa976fa52d3de9aa904aa2522dc518f79c", 141 | "shasum": "" 142 | }, 143 | "require": { 144 | "php": ">=5.3.2" 145 | }, 146 | "replace": { 147 | "cordoval/hamcrest-php": "*", 148 | "davedevelopment/hamcrest-php": "*", 149 | "kodova/hamcrest-php": "*" 150 | }, 151 | "require-dev": { 152 | "phpunit/php-file-iterator": "1.3.3", 153 | "satooshi/php-coveralls": "dev-master" 154 | }, 155 | "type": "library", 156 | "autoload": { 157 | "classmap": [ 158 | "hamcrest" 159 | ], 160 | "files": [ 161 | "hamcrest/Hamcrest.php" 162 | ] 163 | }, 164 | "notification-url": "https://packagist.org/downloads/", 165 | "license": [ 166 | "BSD" 167 | ], 168 | "description": "This is the PHP port of Hamcrest Matchers", 169 | "keywords": [ 170 | "test" 171 | ], 172 | "time": "2015-05-11T14:41:42+00:00" 173 | }, 174 | { 175 | "name": "mockery/mockery", 176 | "version": "0.9.7", 177 | "source": { 178 | "type": "git", 179 | "url": "https://github.com/padraic/mockery.git", 180 | "reference": "4de7969f4664da3cef1ccd83866c9f59378c3371" 181 | }, 182 | "dist": { 183 | "type": "zip", 184 | "url": "https://api.github.com/repos/padraic/mockery/zipball/4de7969f4664da3cef1ccd83866c9f59378c3371", 185 | "reference": "4de7969f4664da3cef1ccd83866c9f59378c3371", 186 | "shasum": "" 187 | }, 188 | "require": { 189 | "hamcrest/hamcrest-php": "~1.1", 190 | "lib-pcre": ">=7.0", 191 | "php": ">=5.3.2" 192 | }, 193 | "require-dev": { 194 | "phpunit/phpunit": "~4.0" 195 | }, 196 | "type": "library", 197 | "extra": { 198 | "branch-alias": { 199 | "dev-master": "0.9.x-dev" 200 | } 201 | }, 202 | "autoload": { 203 | "psr-0": { 204 | "Mockery": "library/" 205 | } 206 | }, 207 | "notification-url": "https://packagist.org/downloads/", 208 | "license": [ 209 | "BSD-3-Clause" 210 | ], 211 | "authors": [ 212 | { 213 | "name": "Pádraic Brady", 214 | "email": "padraic.brady@gmail.com", 215 | "homepage": "http://blog.astrumfutura.com" 216 | }, 217 | { 218 | "name": "Dave Marshall", 219 | "email": "dave.marshall@atstsolutions.co.uk", 220 | "homepage": "http://davedevelopment.co.uk" 221 | } 222 | ], 223 | "description": "Mockery is a simple yet flexible PHP mock object framework for use in unit testing with PHPUnit, PHPSpec or any other testing framework. Its core goal is to offer a test double framework with a succinct API capable of clearly defining all possible object operations and interactions using a human readable Domain Specific Language (DSL). Designed as a drop in alternative to PHPUnit's phpunit-mock-objects library, Mockery is easy to integrate with PHPUnit and can operate alongside phpunit-mock-objects without the World ending.", 224 | "homepage": "http://github.com/padraic/mockery", 225 | "keywords": [ 226 | "BDD", 227 | "TDD", 228 | "library", 229 | "mock", 230 | "mock objects", 231 | "mockery", 232 | "stub", 233 | "test", 234 | "test double", 235 | "testing" 236 | ], 237 | "time": "2016-12-19T14:50:55+00:00" 238 | }, 239 | { 240 | "name": "myclabs/deep-copy", 241 | "version": "1.5.5", 242 | "source": { 243 | "type": "git", 244 | "url": "https://github.com/myclabs/DeepCopy.git", 245 | "reference": "399c1f9781e222f6eb6cc238796f5200d1b7f108" 246 | }, 247 | "dist": { 248 | "type": "zip", 249 | "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/399c1f9781e222f6eb6cc238796f5200d1b7f108", 250 | "reference": "399c1f9781e222f6eb6cc238796f5200d1b7f108", 251 | "shasum": "" 252 | }, 253 | "require": { 254 | "php": ">=5.4.0" 255 | }, 256 | "require-dev": { 257 | "doctrine/collections": "1.*", 258 | "phpunit/phpunit": "~4.1" 259 | }, 260 | "type": "library", 261 | "autoload": { 262 | "psr-4": { 263 | "DeepCopy\\": "src/DeepCopy/" 264 | } 265 | }, 266 | "notification-url": "https://packagist.org/downloads/", 267 | "license": [ 268 | "MIT" 269 | ], 270 | "description": "Create deep copies (clones) of your objects", 271 | "homepage": "https://github.com/myclabs/DeepCopy", 272 | "keywords": [ 273 | "clone", 274 | "copy", 275 | "duplicate", 276 | "object", 277 | "object graph" 278 | ], 279 | "time": "2016-10-31T17:19:45+00:00" 280 | }, 281 | { 282 | "name": "phpdocumentor/reflection-common", 283 | "version": "1.0", 284 | "source": { 285 | "type": "git", 286 | "url": "https://github.com/phpDocumentor/ReflectionCommon.git", 287 | "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c" 288 | }, 289 | "dist": { 290 | "type": "zip", 291 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c", 292 | "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c", 293 | "shasum": "" 294 | }, 295 | "require": { 296 | "php": ">=5.5" 297 | }, 298 | "require-dev": { 299 | "phpunit/phpunit": "^4.6" 300 | }, 301 | "type": "library", 302 | "extra": { 303 | "branch-alias": { 304 | "dev-master": "1.0.x-dev" 305 | } 306 | }, 307 | "autoload": { 308 | "psr-4": { 309 | "phpDocumentor\\Reflection\\": [ 310 | "src" 311 | ] 312 | } 313 | }, 314 | "notification-url": "https://packagist.org/downloads/", 315 | "license": [ 316 | "MIT" 317 | ], 318 | "authors": [ 319 | { 320 | "name": "Jaap van Otterdijk", 321 | "email": "opensource@ijaap.nl" 322 | } 323 | ], 324 | "description": "Common reflection classes used by phpdocumentor to reflect the code structure", 325 | "homepage": "http://www.phpdoc.org", 326 | "keywords": [ 327 | "FQSEN", 328 | "phpDocumentor", 329 | "phpdoc", 330 | "reflection", 331 | "static analysis" 332 | ], 333 | "time": "2015-12-27T11:43:31+00:00" 334 | }, 335 | { 336 | "name": "phpdocumentor/reflection-docblock", 337 | "version": "3.1.1", 338 | "source": { 339 | "type": "git", 340 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", 341 | "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e" 342 | }, 343 | "dist": { 344 | "type": "zip", 345 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/8331b5efe816ae05461b7ca1e721c01b46bafb3e", 346 | "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e", 347 | "shasum": "" 348 | }, 349 | "require": { 350 | "php": ">=5.5", 351 | "phpdocumentor/reflection-common": "^1.0@dev", 352 | "phpdocumentor/type-resolver": "^0.2.0", 353 | "webmozart/assert": "^1.0" 354 | }, 355 | "require-dev": { 356 | "mockery/mockery": "^0.9.4", 357 | "phpunit/phpunit": "^4.4" 358 | }, 359 | "type": "library", 360 | "autoload": { 361 | "psr-4": { 362 | "phpDocumentor\\Reflection\\": [ 363 | "src/" 364 | ] 365 | } 366 | }, 367 | "notification-url": "https://packagist.org/downloads/", 368 | "license": [ 369 | "MIT" 370 | ], 371 | "authors": [ 372 | { 373 | "name": "Mike van Riel", 374 | "email": "me@mikevanriel.com" 375 | } 376 | ], 377 | "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", 378 | "time": "2016-09-30T07:12:33+00:00" 379 | }, 380 | { 381 | "name": "phpdocumentor/type-resolver", 382 | "version": "0.2.1", 383 | "source": { 384 | "type": "git", 385 | "url": "https://github.com/phpDocumentor/TypeResolver.git", 386 | "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb" 387 | }, 388 | "dist": { 389 | "type": "zip", 390 | "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb", 391 | "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb", 392 | "shasum": "" 393 | }, 394 | "require": { 395 | "php": ">=5.5", 396 | "phpdocumentor/reflection-common": "^1.0" 397 | }, 398 | "require-dev": { 399 | "mockery/mockery": "^0.9.4", 400 | "phpunit/phpunit": "^5.2||^4.8.24" 401 | }, 402 | "type": "library", 403 | "extra": { 404 | "branch-alias": { 405 | "dev-master": "1.0.x-dev" 406 | } 407 | }, 408 | "autoload": { 409 | "psr-4": { 410 | "phpDocumentor\\Reflection\\": [ 411 | "src/" 412 | ] 413 | } 414 | }, 415 | "notification-url": "https://packagist.org/downloads/", 416 | "license": [ 417 | "MIT" 418 | ], 419 | "authors": [ 420 | { 421 | "name": "Mike van Riel", 422 | "email": "me@mikevanriel.com" 423 | } 424 | ], 425 | "time": "2016-11-25T06:54:22+00:00" 426 | }, 427 | { 428 | "name": "phpspec/prophecy", 429 | "version": "v1.6.2", 430 | "source": { 431 | "type": "git", 432 | "url": "https://github.com/phpspec/prophecy.git", 433 | "reference": "6c52c2722f8460122f96f86346600e1077ce22cb" 434 | }, 435 | "dist": { 436 | "type": "zip", 437 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/6c52c2722f8460122f96f86346600e1077ce22cb", 438 | "reference": "6c52c2722f8460122f96f86346600e1077ce22cb", 439 | "shasum": "" 440 | }, 441 | "require": { 442 | "doctrine/instantiator": "^1.0.2", 443 | "php": "^5.3|^7.0", 444 | "phpdocumentor/reflection-docblock": "^2.0|^3.0.2", 445 | "sebastian/comparator": "^1.1", 446 | "sebastian/recursion-context": "^1.0|^2.0" 447 | }, 448 | "require-dev": { 449 | "phpspec/phpspec": "^2.0", 450 | "phpunit/phpunit": "^4.8 || ^5.6.5" 451 | }, 452 | "type": "library", 453 | "extra": { 454 | "branch-alias": { 455 | "dev-master": "1.6.x-dev" 456 | } 457 | }, 458 | "autoload": { 459 | "psr-0": { 460 | "Prophecy\\": "src/" 461 | } 462 | }, 463 | "notification-url": "https://packagist.org/downloads/", 464 | "license": [ 465 | "MIT" 466 | ], 467 | "authors": [ 468 | { 469 | "name": "Konstantin Kudryashov", 470 | "email": "ever.zet@gmail.com", 471 | "homepage": "http://everzet.com" 472 | }, 473 | { 474 | "name": "Marcello Duarte", 475 | "email": "marcello.duarte@gmail.com" 476 | } 477 | ], 478 | "description": "Highly opinionated mocking framework for PHP 5.3+", 479 | "homepage": "https://github.com/phpspec/prophecy", 480 | "keywords": [ 481 | "Double", 482 | "Dummy", 483 | "fake", 484 | "mock", 485 | "spy", 486 | "stub" 487 | ], 488 | "time": "2016-11-21T14:58:47+00:00" 489 | }, 490 | { 491 | "name": "phpunit/php-code-coverage", 492 | "version": "4.0.4", 493 | "source": { 494 | "type": "git", 495 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git", 496 | "reference": "c14196e64a78570034afd0b7a9f3757ba71c2a0a" 497 | }, 498 | "dist": { 499 | "type": "zip", 500 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c14196e64a78570034afd0b7a9f3757ba71c2a0a", 501 | "reference": "c14196e64a78570034afd0b7a9f3757ba71c2a0a", 502 | "shasum": "" 503 | }, 504 | "require": { 505 | "php": "^5.6 || ^7.0", 506 | "phpunit/php-file-iterator": "~1.3", 507 | "phpunit/php-text-template": "~1.2", 508 | "phpunit/php-token-stream": "^1.4.2", 509 | "sebastian/code-unit-reverse-lookup": "~1.0", 510 | "sebastian/environment": "^1.3.2 || ^2.0", 511 | "sebastian/version": "~1.0|~2.0" 512 | }, 513 | "require-dev": { 514 | "ext-xdebug": ">=2.1.4", 515 | "phpunit/phpunit": "^5.4" 516 | }, 517 | "suggest": { 518 | "ext-dom": "*", 519 | "ext-xdebug": ">=2.4.0", 520 | "ext-xmlwriter": "*" 521 | }, 522 | "type": "library", 523 | "extra": { 524 | "branch-alias": { 525 | "dev-master": "4.0.x-dev" 526 | } 527 | }, 528 | "autoload": { 529 | "classmap": [ 530 | "src/" 531 | ] 532 | }, 533 | "notification-url": "https://packagist.org/downloads/", 534 | "license": [ 535 | "BSD-3-Clause" 536 | ], 537 | "authors": [ 538 | { 539 | "name": "Sebastian Bergmann", 540 | "email": "sb@sebastian-bergmann.de", 541 | "role": "lead" 542 | } 543 | ], 544 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", 545 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage", 546 | "keywords": [ 547 | "coverage", 548 | "testing", 549 | "xunit" 550 | ], 551 | "time": "2016-12-20T15:22:42+00:00" 552 | }, 553 | { 554 | "name": "phpunit/php-file-iterator", 555 | "version": "1.4.2", 556 | "source": { 557 | "type": "git", 558 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git", 559 | "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5" 560 | }, 561 | "dist": { 562 | "type": "zip", 563 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5", 564 | "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5", 565 | "shasum": "" 566 | }, 567 | "require": { 568 | "php": ">=5.3.3" 569 | }, 570 | "type": "library", 571 | "extra": { 572 | "branch-alias": { 573 | "dev-master": "1.4.x-dev" 574 | } 575 | }, 576 | "autoload": { 577 | "classmap": [ 578 | "src/" 579 | ] 580 | }, 581 | "notification-url": "https://packagist.org/downloads/", 582 | "license": [ 583 | "BSD-3-Clause" 584 | ], 585 | "authors": [ 586 | { 587 | "name": "Sebastian Bergmann", 588 | "email": "sb@sebastian-bergmann.de", 589 | "role": "lead" 590 | } 591 | ], 592 | "description": "FilterIterator implementation that filters files based on a list of suffixes.", 593 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", 594 | "keywords": [ 595 | "filesystem", 596 | "iterator" 597 | ], 598 | "time": "2016-10-03T07:40:28+00:00" 599 | }, 600 | { 601 | "name": "phpunit/php-text-template", 602 | "version": "1.2.1", 603 | "source": { 604 | "type": "git", 605 | "url": "https://github.com/sebastianbergmann/php-text-template.git", 606 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" 607 | }, 608 | "dist": { 609 | "type": "zip", 610 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 611 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 612 | "shasum": "" 613 | }, 614 | "require": { 615 | "php": ">=5.3.3" 616 | }, 617 | "type": "library", 618 | "autoload": { 619 | "classmap": [ 620 | "src/" 621 | ] 622 | }, 623 | "notification-url": "https://packagist.org/downloads/", 624 | "license": [ 625 | "BSD-3-Clause" 626 | ], 627 | "authors": [ 628 | { 629 | "name": "Sebastian Bergmann", 630 | "email": "sebastian@phpunit.de", 631 | "role": "lead" 632 | } 633 | ], 634 | "description": "Simple template engine.", 635 | "homepage": "https://github.com/sebastianbergmann/php-text-template/", 636 | "keywords": [ 637 | "template" 638 | ], 639 | "time": "2015-06-21T13:50:34+00:00" 640 | }, 641 | { 642 | "name": "phpunit/php-timer", 643 | "version": "1.0.8", 644 | "source": { 645 | "type": "git", 646 | "url": "https://github.com/sebastianbergmann/php-timer.git", 647 | "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260" 648 | }, 649 | "dist": { 650 | "type": "zip", 651 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260", 652 | "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260", 653 | "shasum": "" 654 | }, 655 | "require": { 656 | "php": ">=5.3.3" 657 | }, 658 | "require-dev": { 659 | "phpunit/phpunit": "~4|~5" 660 | }, 661 | "type": "library", 662 | "autoload": { 663 | "classmap": [ 664 | "src/" 665 | ] 666 | }, 667 | "notification-url": "https://packagist.org/downloads/", 668 | "license": [ 669 | "BSD-3-Clause" 670 | ], 671 | "authors": [ 672 | { 673 | "name": "Sebastian Bergmann", 674 | "email": "sb@sebastian-bergmann.de", 675 | "role": "lead" 676 | } 677 | ], 678 | "description": "Utility class for timing", 679 | "homepage": "https://github.com/sebastianbergmann/php-timer/", 680 | "keywords": [ 681 | "timer" 682 | ], 683 | "time": "2016-05-12T18:03:57+00:00" 684 | }, 685 | { 686 | "name": "phpunit/php-token-stream", 687 | "version": "1.4.9", 688 | "source": { 689 | "type": "git", 690 | "url": "https://github.com/sebastianbergmann/php-token-stream.git", 691 | "reference": "3b402f65a4cc90abf6e1104e388b896ce209631b" 692 | }, 693 | "dist": { 694 | "type": "zip", 695 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3b402f65a4cc90abf6e1104e388b896ce209631b", 696 | "reference": "3b402f65a4cc90abf6e1104e388b896ce209631b", 697 | "shasum": "" 698 | }, 699 | "require": { 700 | "ext-tokenizer": "*", 701 | "php": ">=5.3.3" 702 | }, 703 | "require-dev": { 704 | "phpunit/phpunit": "~4.2" 705 | }, 706 | "type": "library", 707 | "extra": { 708 | "branch-alias": { 709 | "dev-master": "1.4-dev" 710 | } 711 | }, 712 | "autoload": { 713 | "classmap": [ 714 | "src/" 715 | ] 716 | }, 717 | "notification-url": "https://packagist.org/downloads/", 718 | "license": [ 719 | "BSD-3-Clause" 720 | ], 721 | "authors": [ 722 | { 723 | "name": "Sebastian Bergmann", 724 | "email": "sebastian@phpunit.de" 725 | } 726 | ], 727 | "description": "Wrapper around PHP's tokenizer extension.", 728 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/", 729 | "keywords": [ 730 | "tokenizer" 731 | ], 732 | "time": "2016-11-15T14:06:22+00:00" 733 | }, 734 | { 735 | "name": "phpunit/phpunit", 736 | "version": "5.7.5", 737 | "source": { 738 | "type": "git", 739 | "url": "https://github.com/sebastianbergmann/phpunit.git", 740 | "reference": "50fd2be8f3e23e91da825f36f08e5f9633076ffe" 741 | }, 742 | "dist": { 743 | "type": "zip", 744 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/50fd2be8f3e23e91da825f36f08e5f9633076ffe", 745 | "reference": "50fd2be8f3e23e91da825f36f08e5f9633076ffe", 746 | "shasum": "" 747 | }, 748 | "require": { 749 | "ext-dom": "*", 750 | "ext-json": "*", 751 | "ext-libxml": "*", 752 | "ext-mbstring": "*", 753 | "ext-xml": "*", 754 | "myclabs/deep-copy": "~1.3", 755 | "php": "^5.6 || ^7.0", 756 | "phpspec/prophecy": "^1.6.2", 757 | "phpunit/php-code-coverage": "^4.0.3", 758 | "phpunit/php-file-iterator": "~1.4", 759 | "phpunit/php-text-template": "~1.2", 760 | "phpunit/php-timer": "^1.0.6", 761 | "phpunit/phpunit-mock-objects": "^3.2", 762 | "sebastian/comparator": "~1.2.2", 763 | "sebastian/diff": "~1.2", 764 | "sebastian/environment": "^1.3.4 || ^2.0", 765 | "sebastian/exporter": "~2.0", 766 | "sebastian/global-state": "^1.0 || ^2.0", 767 | "sebastian/object-enumerator": "~2.0", 768 | "sebastian/resource-operations": "~1.0", 769 | "sebastian/version": "~1.0|~2.0", 770 | "symfony/yaml": "~2.1|~3.0" 771 | }, 772 | "conflict": { 773 | "phpdocumentor/reflection-docblock": "3.0.2" 774 | }, 775 | "require-dev": { 776 | "ext-pdo": "*" 777 | }, 778 | "suggest": { 779 | "ext-xdebug": "*", 780 | "phpunit/php-invoker": "~1.1" 781 | }, 782 | "bin": [ 783 | "phpunit" 784 | ], 785 | "type": "library", 786 | "extra": { 787 | "branch-alias": { 788 | "dev-master": "5.7.x-dev" 789 | } 790 | }, 791 | "autoload": { 792 | "classmap": [ 793 | "src/" 794 | ] 795 | }, 796 | "notification-url": "https://packagist.org/downloads/", 797 | "license": [ 798 | "BSD-3-Clause" 799 | ], 800 | "authors": [ 801 | { 802 | "name": "Sebastian Bergmann", 803 | "email": "sebastian@phpunit.de", 804 | "role": "lead" 805 | } 806 | ], 807 | "description": "The PHP Unit Testing framework.", 808 | "homepage": "https://phpunit.de/", 809 | "keywords": [ 810 | "phpunit", 811 | "testing", 812 | "xunit" 813 | ], 814 | "time": "2016-12-28T07:18:51+00:00" 815 | }, 816 | { 817 | "name": "phpunit/phpunit-mock-objects", 818 | "version": "3.4.3", 819 | "source": { 820 | "type": "git", 821 | "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", 822 | "reference": "3ab72b65b39b491e0c011e2e09bb2206c2aa8e24" 823 | }, 824 | "dist": { 825 | "type": "zip", 826 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/3ab72b65b39b491e0c011e2e09bb2206c2aa8e24", 827 | "reference": "3ab72b65b39b491e0c011e2e09bb2206c2aa8e24", 828 | "shasum": "" 829 | }, 830 | "require": { 831 | "doctrine/instantiator": "^1.0.2", 832 | "php": "^5.6 || ^7.0", 833 | "phpunit/php-text-template": "^1.2", 834 | "sebastian/exporter": "^1.2 || ^2.0" 835 | }, 836 | "conflict": { 837 | "phpunit/phpunit": "<5.4.0" 838 | }, 839 | "require-dev": { 840 | "phpunit/phpunit": "^5.4" 841 | }, 842 | "suggest": { 843 | "ext-soap": "*" 844 | }, 845 | "type": "library", 846 | "extra": { 847 | "branch-alias": { 848 | "dev-master": "3.2.x-dev" 849 | } 850 | }, 851 | "autoload": { 852 | "classmap": [ 853 | "src/" 854 | ] 855 | }, 856 | "notification-url": "https://packagist.org/downloads/", 857 | "license": [ 858 | "BSD-3-Clause" 859 | ], 860 | "authors": [ 861 | { 862 | "name": "Sebastian Bergmann", 863 | "email": "sb@sebastian-bergmann.de", 864 | "role": "lead" 865 | } 866 | ], 867 | "description": "Mock Object library for PHPUnit", 868 | "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", 869 | "keywords": [ 870 | "mock", 871 | "xunit" 872 | ], 873 | "time": "2016-12-08T20:27:08+00:00" 874 | }, 875 | { 876 | "name": "psr/log", 877 | "version": "1.0.2", 878 | "source": { 879 | "type": "git", 880 | "url": "https://github.com/php-fig/log.git", 881 | "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" 882 | }, 883 | "dist": { 884 | "type": "zip", 885 | "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", 886 | "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", 887 | "shasum": "" 888 | }, 889 | "require": { 890 | "php": ">=5.3.0" 891 | }, 892 | "type": "library", 893 | "extra": { 894 | "branch-alias": { 895 | "dev-master": "1.0.x-dev" 896 | } 897 | }, 898 | "autoload": { 899 | "psr-4": { 900 | "Psr\\Log\\": "Psr/Log/" 901 | } 902 | }, 903 | "notification-url": "https://packagist.org/downloads/", 904 | "license": [ 905 | "MIT" 906 | ], 907 | "authors": [ 908 | { 909 | "name": "PHP-FIG", 910 | "homepage": "http://www.php-fig.org/" 911 | } 912 | ], 913 | "description": "Common interface for logging libraries", 914 | "homepage": "https://github.com/php-fig/log", 915 | "keywords": [ 916 | "log", 917 | "psr", 918 | "psr-3" 919 | ], 920 | "time": "2016-10-10T12:19:37+00:00" 921 | }, 922 | { 923 | "name": "sebastian/code-unit-reverse-lookup", 924 | "version": "1.0.0", 925 | "source": { 926 | "type": "git", 927 | "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", 928 | "reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe" 929 | }, 930 | "dist": { 931 | "type": "zip", 932 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/c36f5e7cfce482fde5bf8d10d41a53591e0198fe", 933 | "reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe", 934 | "shasum": "" 935 | }, 936 | "require": { 937 | "php": ">=5.6" 938 | }, 939 | "require-dev": { 940 | "phpunit/phpunit": "~5" 941 | }, 942 | "type": "library", 943 | "extra": { 944 | "branch-alias": { 945 | "dev-master": "1.0.x-dev" 946 | } 947 | }, 948 | "autoload": { 949 | "classmap": [ 950 | "src/" 951 | ] 952 | }, 953 | "notification-url": "https://packagist.org/downloads/", 954 | "license": [ 955 | "BSD-3-Clause" 956 | ], 957 | "authors": [ 958 | { 959 | "name": "Sebastian Bergmann", 960 | "email": "sebastian@phpunit.de" 961 | } 962 | ], 963 | "description": "Looks up which function or method a line of code belongs to", 964 | "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", 965 | "time": "2016-02-13T06:45:14+00:00" 966 | }, 967 | { 968 | "name": "sebastian/comparator", 969 | "version": "1.2.2", 970 | "source": { 971 | "type": "git", 972 | "url": "https://github.com/sebastianbergmann/comparator.git", 973 | "reference": "6a1ed12e8b2409076ab22e3897126211ff8b1f7f" 974 | }, 975 | "dist": { 976 | "type": "zip", 977 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/6a1ed12e8b2409076ab22e3897126211ff8b1f7f", 978 | "reference": "6a1ed12e8b2409076ab22e3897126211ff8b1f7f", 979 | "shasum": "" 980 | }, 981 | "require": { 982 | "php": ">=5.3.3", 983 | "sebastian/diff": "~1.2", 984 | "sebastian/exporter": "~1.2 || ~2.0" 985 | }, 986 | "require-dev": { 987 | "phpunit/phpunit": "~4.4" 988 | }, 989 | "type": "library", 990 | "extra": { 991 | "branch-alias": { 992 | "dev-master": "1.2.x-dev" 993 | } 994 | }, 995 | "autoload": { 996 | "classmap": [ 997 | "src/" 998 | ] 999 | }, 1000 | "notification-url": "https://packagist.org/downloads/", 1001 | "license": [ 1002 | "BSD-3-Clause" 1003 | ], 1004 | "authors": [ 1005 | { 1006 | "name": "Jeff Welch", 1007 | "email": "whatthejeff@gmail.com" 1008 | }, 1009 | { 1010 | "name": "Volker Dusch", 1011 | "email": "github@wallbash.com" 1012 | }, 1013 | { 1014 | "name": "Bernhard Schussek", 1015 | "email": "bschussek@2bepublished.at" 1016 | }, 1017 | { 1018 | "name": "Sebastian Bergmann", 1019 | "email": "sebastian@phpunit.de" 1020 | } 1021 | ], 1022 | "description": "Provides the functionality to compare PHP values for equality", 1023 | "homepage": "http://www.github.com/sebastianbergmann/comparator", 1024 | "keywords": [ 1025 | "comparator", 1026 | "compare", 1027 | "equality" 1028 | ], 1029 | "time": "2016-11-19T09:18:40+00:00" 1030 | }, 1031 | { 1032 | "name": "sebastian/diff", 1033 | "version": "1.4.1", 1034 | "source": { 1035 | "type": "git", 1036 | "url": "https://github.com/sebastianbergmann/diff.git", 1037 | "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e" 1038 | }, 1039 | "dist": { 1040 | "type": "zip", 1041 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e", 1042 | "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e", 1043 | "shasum": "" 1044 | }, 1045 | "require": { 1046 | "php": ">=5.3.3" 1047 | }, 1048 | "require-dev": { 1049 | "phpunit/phpunit": "~4.8" 1050 | }, 1051 | "type": "library", 1052 | "extra": { 1053 | "branch-alias": { 1054 | "dev-master": "1.4-dev" 1055 | } 1056 | }, 1057 | "autoload": { 1058 | "classmap": [ 1059 | "src/" 1060 | ] 1061 | }, 1062 | "notification-url": "https://packagist.org/downloads/", 1063 | "license": [ 1064 | "BSD-3-Clause" 1065 | ], 1066 | "authors": [ 1067 | { 1068 | "name": "Kore Nordmann", 1069 | "email": "mail@kore-nordmann.de" 1070 | }, 1071 | { 1072 | "name": "Sebastian Bergmann", 1073 | "email": "sebastian@phpunit.de" 1074 | } 1075 | ], 1076 | "description": "Diff implementation", 1077 | "homepage": "https://github.com/sebastianbergmann/diff", 1078 | "keywords": [ 1079 | "diff" 1080 | ], 1081 | "time": "2015-12-08T07:14:41+00:00" 1082 | }, 1083 | { 1084 | "name": "sebastian/environment", 1085 | "version": "2.0.0", 1086 | "source": { 1087 | "type": "git", 1088 | "url": "https://github.com/sebastianbergmann/environment.git", 1089 | "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac" 1090 | }, 1091 | "dist": { 1092 | "type": "zip", 1093 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5795ffe5dc5b02460c3e34222fee8cbe245d8fac", 1094 | "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac", 1095 | "shasum": "" 1096 | }, 1097 | "require": { 1098 | "php": "^5.6 || ^7.0" 1099 | }, 1100 | "require-dev": { 1101 | "phpunit/phpunit": "^5.0" 1102 | }, 1103 | "type": "library", 1104 | "extra": { 1105 | "branch-alias": { 1106 | "dev-master": "2.0.x-dev" 1107 | } 1108 | }, 1109 | "autoload": { 1110 | "classmap": [ 1111 | "src/" 1112 | ] 1113 | }, 1114 | "notification-url": "https://packagist.org/downloads/", 1115 | "license": [ 1116 | "BSD-3-Clause" 1117 | ], 1118 | "authors": [ 1119 | { 1120 | "name": "Sebastian Bergmann", 1121 | "email": "sebastian@phpunit.de" 1122 | } 1123 | ], 1124 | "description": "Provides functionality to handle HHVM/PHP environments", 1125 | "homepage": "http://www.github.com/sebastianbergmann/environment", 1126 | "keywords": [ 1127 | "Xdebug", 1128 | "environment", 1129 | "hhvm" 1130 | ], 1131 | "time": "2016-11-26T07:53:53+00:00" 1132 | }, 1133 | { 1134 | "name": "sebastian/exporter", 1135 | "version": "2.0.0", 1136 | "source": { 1137 | "type": "git", 1138 | "url": "https://github.com/sebastianbergmann/exporter.git", 1139 | "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4" 1140 | }, 1141 | "dist": { 1142 | "type": "zip", 1143 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", 1144 | "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", 1145 | "shasum": "" 1146 | }, 1147 | "require": { 1148 | "php": ">=5.3.3", 1149 | "sebastian/recursion-context": "~2.0" 1150 | }, 1151 | "require-dev": { 1152 | "ext-mbstring": "*", 1153 | "phpunit/phpunit": "~4.4" 1154 | }, 1155 | "type": "library", 1156 | "extra": { 1157 | "branch-alias": { 1158 | "dev-master": "2.0.x-dev" 1159 | } 1160 | }, 1161 | "autoload": { 1162 | "classmap": [ 1163 | "src/" 1164 | ] 1165 | }, 1166 | "notification-url": "https://packagist.org/downloads/", 1167 | "license": [ 1168 | "BSD-3-Clause" 1169 | ], 1170 | "authors": [ 1171 | { 1172 | "name": "Jeff Welch", 1173 | "email": "whatthejeff@gmail.com" 1174 | }, 1175 | { 1176 | "name": "Volker Dusch", 1177 | "email": "github@wallbash.com" 1178 | }, 1179 | { 1180 | "name": "Bernhard Schussek", 1181 | "email": "bschussek@2bepublished.at" 1182 | }, 1183 | { 1184 | "name": "Sebastian Bergmann", 1185 | "email": "sebastian@phpunit.de" 1186 | }, 1187 | { 1188 | "name": "Adam Harvey", 1189 | "email": "aharvey@php.net" 1190 | } 1191 | ], 1192 | "description": "Provides the functionality to export PHP variables for visualization", 1193 | "homepage": "http://www.github.com/sebastianbergmann/exporter", 1194 | "keywords": [ 1195 | "export", 1196 | "exporter" 1197 | ], 1198 | "time": "2016-11-19T08:54:04+00:00" 1199 | }, 1200 | { 1201 | "name": "sebastian/global-state", 1202 | "version": "1.1.1", 1203 | "source": { 1204 | "type": "git", 1205 | "url": "https://github.com/sebastianbergmann/global-state.git", 1206 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" 1207 | }, 1208 | "dist": { 1209 | "type": "zip", 1210 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", 1211 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", 1212 | "shasum": "" 1213 | }, 1214 | "require": { 1215 | "php": ">=5.3.3" 1216 | }, 1217 | "require-dev": { 1218 | "phpunit/phpunit": "~4.2" 1219 | }, 1220 | "suggest": { 1221 | "ext-uopz": "*" 1222 | }, 1223 | "type": "library", 1224 | "extra": { 1225 | "branch-alias": { 1226 | "dev-master": "1.0-dev" 1227 | } 1228 | }, 1229 | "autoload": { 1230 | "classmap": [ 1231 | "src/" 1232 | ] 1233 | }, 1234 | "notification-url": "https://packagist.org/downloads/", 1235 | "license": [ 1236 | "BSD-3-Clause" 1237 | ], 1238 | "authors": [ 1239 | { 1240 | "name": "Sebastian Bergmann", 1241 | "email": "sebastian@phpunit.de" 1242 | } 1243 | ], 1244 | "description": "Snapshotting of global state", 1245 | "homepage": "http://www.github.com/sebastianbergmann/global-state", 1246 | "keywords": [ 1247 | "global state" 1248 | ], 1249 | "time": "2015-10-12T03:26:01+00:00" 1250 | }, 1251 | { 1252 | "name": "sebastian/object-enumerator", 1253 | "version": "2.0.0", 1254 | "source": { 1255 | "type": "git", 1256 | "url": "https://github.com/sebastianbergmann/object-enumerator.git", 1257 | "reference": "96f8a3f257b69e8128ad74d3a7fd464bcbaa3b35" 1258 | }, 1259 | "dist": { 1260 | "type": "zip", 1261 | "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/96f8a3f257b69e8128ad74d3a7fd464bcbaa3b35", 1262 | "reference": "96f8a3f257b69e8128ad74d3a7fd464bcbaa3b35", 1263 | "shasum": "" 1264 | }, 1265 | "require": { 1266 | "php": ">=5.6", 1267 | "sebastian/recursion-context": "~2.0" 1268 | }, 1269 | "require-dev": { 1270 | "phpunit/phpunit": "~5" 1271 | }, 1272 | "type": "library", 1273 | "extra": { 1274 | "branch-alias": { 1275 | "dev-master": "2.0.x-dev" 1276 | } 1277 | }, 1278 | "autoload": { 1279 | "classmap": [ 1280 | "src/" 1281 | ] 1282 | }, 1283 | "notification-url": "https://packagist.org/downloads/", 1284 | "license": [ 1285 | "BSD-3-Clause" 1286 | ], 1287 | "authors": [ 1288 | { 1289 | "name": "Sebastian Bergmann", 1290 | "email": "sebastian@phpunit.de" 1291 | } 1292 | ], 1293 | "description": "Traverses array structures and object graphs to enumerate all referenced objects", 1294 | "homepage": "https://github.com/sebastianbergmann/object-enumerator/", 1295 | "time": "2016-11-19T07:35:10+00:00" 1296 | }, 1297 | { 1298 | "name": "sebastian/recursion-context", 1299 | "version": "2.0.0", 1300 | "source": { 1301 | "type": "git", 1302 | "url": "https://github.com/sebastianbergmann/recursion-context.git", 1303 | "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a" 1304 | }, 1305 | "dist": { 1306 | "type": "zip", 1307 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/2c3ba150cbec723aa057506e73a8d33bdb286c9a", 1308 | "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a", 1309 | "shasum": "" 1310 | }, 1311 | "require": { 1312 | "php": ">=5.3.3" 1313 | }, 1314 | "require-dev": { 1315 | "phpunit/phpunit": "~4.4" 1316 | }, 1317 | "type": "library", 1318 | "extra": { 1319 | "branch-alias": { 1320 | "dev-master": "2.0.x-dev" 1321 | } 1322 | }, 1323 | "autoload": { 1324 | "classmap": [ 1325 | "src/" 1326 | ] 1327 | }, 1328 | "notification-url": "https://packagist.org/downloads/", 1329 | "license": [ 1330 | "BSD-3-Clause" 1331 | ], 1332 | "authors": [ 1333 | { 1334 | "name": "Jeff Welch", 1335 | "email": "whatthejeff@gmail.com" 1336 | }, 1337 | { 1338 | "name": "Sebastian Bergmann", 1339 | "email": "sebastian@phpunit.de" 1340 | }, 1341 | { 1342 | "name": "Adam Harvey", 1343 | "email": "aharvey@php.net" 1344 | } 1345 | ], 1346 | "description": "Provides functionality to recursively process PHP variables", 1347 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context", 1348 | "time": "2016-11-19T07:33:16+00:00" 1349 | }, 1350 | { 1351 | "name": "sebastian/resource-operations", 1352 | "version": "1.0.0", 1353 | "source": { 1354 | "type": "git", 1355 | "url": "https://github.com/sebastianbergmann/resource-operations.git", 1356 | "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" 1357 | }, 1358 | "dist": { 1359 | "type": "zip", 1360 | "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", 1361 | "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", 1362 | "shasum": "" 1363 | }, 1364 | "require": { 1365 | "php": ">=5.6.0" 1366 | }, 1367 | "type": "library", 1368 | "extra": { 1369 | "branch-alias": { 1370 | "dev-master": "1.0.x-dev" 1371 | } 1372 | }, 1373 | "autoload": { 1374 | "classmap": [ 1375 | "src/" 1376 | ] 1377 | }, 1378 | "notification-url": "https://packagist.org/downloads/", 1379 | "license": [ 1380 | "BSD-3-Clause" 1381 | ], 1382 | "authors": [ 1383 | { 1384 | "name": "Sebastian Bergmann", 1385 | "email": "sebastian@phpunit.de" 1386 | } 1387 | ], 1388 | "description": "Provides a list of PHP built-in functions that operate on resources", 1389 | "homepage": "https://www.github.com/sebastianbergmann/resource-operations", 1390 | "time": "2015-07-28T20:34:47+00:00" 1391 | }, 1392 | { 1393 | "name": "sebastian/version", 1394 | "version": "2.0.1", 1395 | "source": { 1396 | "type": "git", 1397 | "url": "https://github.com/sebastianbergmann/version.git", 1398 | "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" 1399 | }, 1400 | "dist": { 1401 | "type": "zip", 1402 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", 1403 | "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", 1404 | "shasum": "" 1405 | }, 1406 | "require": { 1407 | "php": ">=5.6" 1408 | }, 1409 | "type": "library", 1410 | "extra": { 1411 | "branch-alias": { 1412 | "dev-master": "2.0.x-dev" 1413 | } 1414 | }, 1415 | "autoload": { 1416 | "classmap": [ 1417 | "src/" 1418 | ] 1419 | }, 1420 | "notification-url": "https://packagist.org/downloads/", 1421 | "license": [ 1422 | "BSD-3-Clause" 1423 | ], 1424 | "authors": [ 1425 | { 1426 | "name": "Sebastian Bergmann", 1427 | "email": "sebastian@phpunit.de", 1428 | "role": "lead" 1429 | } 1430 | ], 1431 | "description": "Library that helps with managing the version number of Git-hosted PHP projects", 1432 | "homepage": "https://github.com/sebastianbergmann/version", 1433 | "time": "2016-10-03T07:35:21+00:00" 1434 | }, 1435 | { 1436 | "name": "symfony/console", 1437 | "version": "v3.2.1", 1438 | "source": { 1439 | "type": "git", 1440 | "url": "https://github.com/symfony/console.git", 1441 | "reference": "d12aa9ca20f4db83ec58410978dab6afcb9d6aaa" 1442 | }, 1443 | "dist": { 1444 | "type": "zip", 1445 | "url": "https://api.github.com/repos/symfony/console/zipball/d12aa9ca20f4db83ec58410978dab6afcb9d6aaa", 1446 | "reference": "d12aa9ca20f4db83ec58410978dab6afcb9d6aaa", 1447 | "shasum": "" 1448 | }, 1449 | "require": { 1450 | "php": ">=5.5.9", 1451 | "symfony/debug": "~2.8|~3.0", 1452 | "symfony/polyfill-mbstring": "~1.0" 1453 | }, 1454 | "require-dev": { 1455 | "psr/log": "~1.0", 1456 | "symfony/event-dispatcher": "~2.8|~3.0", 1457 | "symfony/filesystem": "~2.8|~3.0", 1458 | "symfony/process": "~2.8|~3.0" 1459 | }, 1460 | "suggest": { 1461 | "psr/log": "For using the console logger", 1462 | "symfony/event-dispatcher": "", 1463 | "symfony/filesystem": "", 1464 | "symfony/process": "" 1465 | }, 1466 | "type": "library", 1467 | "extra": { 1468 | "branch-alias": { 1469 | "dev-master": "3.2-dev" 1470 | } 1471 | }, 1472 | "autoload": { 1473 | "psr-4": { 1474 | "Symfony\\Component\\Console\\": "" 1475 | }, 1476 | "exclude-from-classmap": [ 1477 | "/Tests/" 1478 | ] 1479 | }, 1480 | "notification-url": "https://packagist.org/downloads/", 1481 | "license": [ 1482 | "MIT" 1483 | ], 1484 | "authors": [ 1485 | { 1486 | "name": "Fabien Potencier", 1487 | "email": "fabien@symfony.com" 1488 | }, 1489 | { 1490 | "name": "Symfony Community", 1491 | "homepage": "https://symfony.com/contributors" 1492 | } 1493 | ], 1494 | "description": "Symfony Console Component", 1495 | "homepage": "https://symfony.com", 1496 | "time": "2016-12-11T14:34:22+00:00" 1497 | }, 1498 | { 1499 | "name": "symfony/debug", 1500 | "version": "v3.2.1", 1501 | "source": { 1502 | "type": "git", 1503 | "url": "https://github.com/symfony/debug.git", 1504 | "reference": "9f923e68d524a3095c5a2ae5fc7220c7cbc12231" 1505 | }, 1506 | "dist": { 1507 | "type": "zip", 1508 | "url": "https://api.github.com/repos/symfony/debug/zipball/9f923e68d524a3095c5a2ae5fc7220c7cbc12231", 1509 | "reference": "9f923e68d524a3095c5a2ae5fc7220c7cbc12231", 1510 | "shasum": "" 1511 | }, 1512 | "require": { 1513 | "php": ">=5.5.9", 1514 | "psr/log": "~1.0" 1515 | }, 1516 | "conflict": { 1517 | "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" 1518 | }, 1519 | "require-dev": { 1520 | "symfony/class-loader": "~2.8|~3.0", 1521 | "symfony/http-kernel": "~2.8|~3.0" 1522 | }, 1523 | "type": "library", 1524 | "extra": { 1525 | "branch-alias": { 1526 | "dev-master": "3.2-dev" 1527 | } 1528 | }, 1529 | "autoload": { 1530 | "psr-4": { 1531 | "Symfony\\Component\\Debug\\": "" 1532 | }, 1533 | "exclude-from-classmap": [ 1534 | "/Tests/" 1535 | ] 1536 | }, 1537 | "notification-url": "https://packagist.org/downloads/", 1538 | "license": [ 1539 | "MIT" 1540 | ], 1541 | "authors": [ 1542 | { 1543 | "name": "Fabien Potencier", 1544 | "email": "fabien@symfony.com" 1545 | }, 1546 | { 1547 | "name": "Symfony Community", 1548 | "homepage": "https://symfony.com/contributors" 1549 | } 1550 | ], 1551 | "description": "Symfony Debug Component", 1552 | "homepage": "https://symfony.com", 1553 | "time": "2016-11-16T22:18:16+00:00" 1554 | }, 1555 | { 1556 | "name": "symfony/event-dispatcher", 1557 | "version": "v3.2.1", 1558 | "source": { 1559 | "type": "git", 1560 | "url": "https://github.com/symfony/event-dispatcher.git", 1561 | "reference": "e8f47a327c2f0fd5aa04fa60af2b693006ed7283" 1562 | }, 1563 | "dist": { 1564 | "type": "zip", 1565 | "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/e8f47a327c2f0fd5aa04fa60af2b693006ed7283", 1566 | "reference": "e8f47a327c2f0fd5aa04fa60af2b693006ed7283", 1567 | "shasum": "" 1568 | }, 1569 | "require": { 1570 | "php": ">=5.5.9" 1571 | }, 1572 | "require-dev": { 1573 | "psr/log": "~1.0", 1574 | "symfony/config": "~2.8|~3.0", 1575 | "symfony/dependency-injection": "~2.8|~3.0", 1576 | "symfony/expression-language": "~2.8|~3.0", 1577 | "symfony/stopwatch": "~2.8|~3.0" 1578 | }, 1579 | "suggest": { 1580 | "symfony/dependency-injection": "", 1581 | "symfony/http-kernel": "" 1582 | }, 1583 | "type": "library", 1584 | "extra": { 1585 | "branch-alias": { 1586 | "dev-master": "3.2-dev" 1587 | } 1588 | }, 1589 | "autoload": { 1590 | "psr-4": { 1591 | "Symfony\\Component\\EventDispatcher\\": "" 1592 | }, 1593 | "exclude-from-classmap": [ 1594 | "/Tests/" 1595 | ] 1596 | }, 1597 | "notification-url": "https://packagist.org/downloads/", 1598 | "license": [ 1599 | "MIT" 1600 | ], 1601 | "authors": [ 1602 | { 1603 | "name": "Fabien Potencier", 1604 | "email": "fabien@symfony.com" 1605 | }, 1606 | { 1607 | "name": "Symfony Community", 1608 | "homepage": "https://symfony.com/contributors" 1609 | } 1610 | ], 1611 | "description": "Symfony EventDispatcher Component", 1612 | "homepage": "https://symfony.com", 1613 | "time": "2016-10-13T06:29:04+00:00" 1614 | }, 1615 | { 1616 | "name": "symfony/filesystem", 1617 | "version": "v3.2.1", 1618 | "source": { 1619 | "type": "git", 1620 | "url": "https://github.com/symfony/filesystem.git", 1621 | "reference": "8d4cf7561a5b17e5eb7a02b80d0b8f014a3796d4" 1622 | }, 1623 | "dist": { 1624 | "type": "zip", 1625 | "url": "https://api.github.com/repos/symfony/filesystem/zipball/8d4cf7561a5b17e5eb7a02b80d0b8f014a3796d4", 1626 | "reference": "8d4cf7561a5b17e5eb7a02b80d0b8f014a3796d4", 1627 | "shasum": "" 1628 | }, 1629 | "require": { 1630 | "php": ">=5.5.9" 1631 | }, 1632 | "type": "library", 1633 | "extra": { 1634 | "branch-alias": { 1635 | "dev-master": "3.2-dev" 1636 | } 1637 | }, 1638 | "autoload": { 1639 | "psr-4": { 1640 | "Symfony\\Component\\Filesystem\\": "" 1641 | }, 1642 | "exclude-from-classmap": [ 1643 | "/Tests/" 1644 | ] 1645 | }, 1646 | "notification-url": "https://packagist.org/downloads/", 1647 | "license": [ 1648 | "MIT" 1649 | ], 1650 | "authors": [ 1651 | { 1652 | "name": "Fabien Potencier", 1653 | "email": "fabien@symfony.com" 1654 | }, 1655 | { 1656 | "name": "Symfony Community", 1657 | "homepage": "https://symfony.com/contributors" 1658 | } 1659 | ], 1660 | "description": "Symfony Filesystem Component", 1661 | "homepage": "https://symfony.com", 1662 | "time": "2016-11-24T00:46:43+00:00" 1663 | }, 1664 | { 1665 | "name": "symfony/finder", 1666 | "version": "v3.2.1", 1667 | "source": { 1668 | "type": "git", 1669 | "url": "https://github.com/symfony/finder.git", 1670 | "reference": "a69cb5d455b4885ca376dc5bb3e1155cc8c08c4b" 1671 | }, 1672 | "dist": { 1673 | "type": "zip", 1674 | "url": "https://api.github.com/repos/symfony/finder/zipball/a69cb5d455b4885ca376dc5bb3e1155cc8c08c4b", 1675 | "reference": "a69cb5d455b4885ca376dc5bb3e1155cc8c08c4b", 1676 | "shasum": "" 1677 | }, 1678 | "require": { 1679 | "php": ">=5.5.9" 1680 | }, 1681 | "type": "library", 1682 | "extra": { 1683 | "branch-alias": { 1684 | "dev-master": "3.2-dev" 1685 | } 1686 | }, 1687 | "autoload": { 1688 | "psr-4": { 1689 | "Symfony\\Component\\Finder\\": "" 1690 | }, 1691 | "exclude-from-classmap": [ 1692 | "/Tests/" 1693 | ] 1694 | }, 1695 | "notification-url": "https://packagist.org/downloads/", 1696 | "license": [ 1697 | "MIT" 1698 | ], 1699 | "authors": [ 1700 | { 1701 | "name": "Fabien Potencier", 1702 | "email": "fabien@symfony.com" 1703 | }, 1704 | { 1705 | "name": "Symfony Community", 1706 | "homepage": "https://symfony.com/contributors" 1707 | } 1708 | ], 1709 | "description": "Symfony Finder Component", 1710 | "homepage": "https://symfony.com", 1711 | "time": "2016-12-13T09:39:43+00:00" 1712 | }, 1713 | { 1714 | "name": "symfony/polyfill-mbstring", 1715 | "version": "v1.3.0", 1716 | "source": { 1717 | "type": "git", 1718 | "url": "https://github.com/symfony/polyfill-mbstring.git", 1719 | "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4" 1720 | }, 1721 | "dist": { 1722 | "type": "zip", 1723 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/e79d363049d1c2128f133a2667e4f4190904f7f4", 1724 | "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4", 1725 | "shasum": "" 1726 | }, 1727 | "require": { 1728 | "php": ">=5.3.3" 1729 | }, 1730 | "suggest": { 1731 | "ext-mbstring": "For best performance" 1732 | }, 1733 | "type": "library", 1734 | "extra": { 1735 | "branch-alias": { 1736 | "dev-master": "1.3-dev" 1737 | } 1738 | }, 1739 | "autoload": { 1740 | "psr-4": { 1741 | "Symfony\\Polyfill\\Mbstring\\": "" 1742 | }, 1743 | "files": [ 1744 | "bootstrap.php" 1745 | ] 1746 | }, 1747 | "notification-url": "https://packagist.org/downloads/", 1748 | "license": [ 1749 | "MIT" 1750 | ], 1751 | "authors": [ 1752 | { 1753 | "name": "Nicolas Grekas", 1754 | "email": "p@tchwork.com" 1755 | }, 1756 | { 1757 | "name": "Symfony Community", 1758 | "homepage": "https://symfony.com/contributors" 1759 | } 1760 | ], 1761 | "description": "Symfony polyfill for the Mbstring extension", 1762 | "homepage": "https://symfony.com", 1763 | "keywords": [ 1764 | "compatibility", 1765 | "mbstring", 1766 | "polyfill", 1767 | "portable", 1768 | "shim" 1769 | ], 1770 | "time": "2016-11-14T01:06:16+00:00" 1771 | }, 1772 | { 1773 | "name": "symfony/polyfill-php54", 1774 | "version": "v1.3.0", 1775 | "source": { 1776 | "type": "git", 1777 | "url": "https://github.com/symfony/polyfill-php54.git", 1778 | "reference": "90e085822963fdcc9d1c5b73deb3d2e5783b16a0" 1779 | }, 1780 | "dist": { 1781 | "type": "zip", 1782 | "url": "https://api.github.com/repos/symfony/polyfill-php54/zipball/90e085822963fdcc9d1c5b73deb3d2e5783b16a0", 1783 | "reference": "90e085822963fdcc9d1c5b73deb3d2e5783b16a0", 1784 | "shasum": "" 1785 | }, 1786 | "require": { 1787 | "php": ">=5.3.3" 1788 | }, 1789 | "type": "library", 1790 | "extra": { 1791 | "branch-alias": { 1792 | "dev-master": "1.3-dev" 1793 | } 1794 | }, 1795 | "autoload": { 1796 | "psr-4": { 1797 | "Symfony\\Polyfill\\Php54\\": "" 1798 | }, 1799 | "files": [ 1800 | "bootstrap.php" 1801 | ], 1802 | "classmap": [ 1803 | "Resources/stubs" 1804 | ] 1805 | }, 1806 | "notification-url": "https://packagist.org/downloads/", 1807 | "license": [ 1808 | "MIT" 1809 | ], 1810 | "authors": [ 1811 | { 1812 | "name": "Nicolas Grekas", 1813 | "email": "p@tchwork.com" 1814 | }, 1815 | { 1816 | "name": "Symfony Community", 1817 | "homepage": "https://symfony.com/contributors" 1818 | } 1819 | ], 1820 | "description": "Symfony polyfill backporting some PHP 5.4+ features to lower PHP versions", 1821 | "homepage": "https://symfony.com", 1822 | "keywords": [ 1823 | "compatibility", 1824 | "polyfill", 1825 | "portable", 1826 | "shim" 1827 | ], 1828 | "time": "2016-11-14T01:06:16+00:00" 1829 | }, 1830 | { 1831 | "name": "symfony/process", 1832 | "version": "v3.2.1", 1833 | "source": { 1834 | "type": "git", 1835 | "url": "https://github.com/symfony/process.git", 1836 | "reference": "02ea84847aad71be7e32056408bb19f3a616cdd3" 1837 | }, 1838 | "dist": { 1839 | "type": "zip", 1840 | "url": "https://api.github.com/repos/symfony/process/zipball/02ea84847aad71be7e32056408bb19f3a616cdd3", 1841 | "reference": "02ea84847aad71be7e32056408bb19f3a616cdd3", 1842 | "shasum": "" 1843 | }, 1844 | "require": { 1845 | "php": ">=5.5.9" 1846 | }, 1847 | "type": "library", 1848 | "extra": { 1849 | "branch-alias": { 1850 | "dev-master": "3.2-dev" 1851 | } 1852 | }, 1853 | "autoload": { 1854 | "psr-4": { 1855 | "Symfony\\Component\\Process\\": "" 1856 | }, 1857 | "exclude-from-classmap": [ 1858 | "/Tests/" 1859 | ] 1860 | }, 1861 | "notification-url": "https://packagist.org/downloads/", 1862 | "license": [ 1863 | "MIT" 1864 | ], 1865 | "authors": [ 1866 | { 1867 | "name": "Fabien Potencier", 1868 | "email": "fabien@symfony.com" 1869 | }, 1870 | { 1871 | "name": "Symfony Community", 1872 | "homepage": "https://symfony.com/contributors" 1873 | } 1874 | ], 1875 | "description": "Symfony Process Component", 1876 | "homepage": "https://symfony.com", 1877 | "time": "2016-11-24T10:40:28+00:00" 1878 | }, 1879 | { 1880 | "name": "symfony/stopwatch", 1881 | "version": "v3.2.1", 1882 | "source": { 1883 | "type": "git", 1884 | "url": "https://github.com/symfony/stopwatch.git", 1885 | "reference": "5b139e1c4290e6c7640ba80d9c9b5e49ef22b841" 1886 | }, 1887 | "dist": { 1888 | "type": "zip", 1889 | "url": "https://api.github.com/repos/symfony/stopwatch/zipball/5b139e1c4290e6c7640ba80d9c9b5e49ef22b841", 1890 | "reference": "5b139e1c4290e6c7640ba80d9c9b5e49ef22b841", 1891 | "shasum": "" 1892 | }, 1893 | "require": { 1894 | "php": ">=5.5.9" 1895 | }, 1896 | "type": "library", 1897 | "extra": { 1898 | "branch-alias": { 1899 | "dev-master": "3.2-dev" 1900 | } 1901 | }, 1902 | "autoload": { 1903 | "psr-4": { 1904 | "Symfony\\Component\\Stopwatch\\": "" 1905 | }, 1906 | "exclude-from-classmap": [ 1907 | "/Tests/" 1908 | ] 1909 | }, 1910 | "notification-url": "https://packagist.org/downloads/", 1911 | "license": [ 1912 | "MIT" 1913 | ], 1914 | "authors": [ 1915 | { 1916 | "name": "Fabien Potencier", 1917 | "email": "fabien@symfony.com" 1918 | }, 1919 | { 1920 | "name": "Symfony Community", 1921 | "homepage": "https://symfony.com/contributors" 1922 | } 1923 | ], 1924 | "description": "Symfony Stopwatch Component", 1925 | "homepage": "https://symfony.com", 1926 | "time": "2016-06-29T05:43:10+00:00" 1927 | }, 1928 | { 1929 | "name": "symfony/yaml", 1930 | "version": "v3.2.1", 1931 | "source": { 1932 | "type": "git", 1933 | "url": "https://github.com/symfony/yaml.git", 1934 | "reference": "a7095af4b97a0955f85c8989106c249fa649011f" 1935 | }, 1936 | "dist": { 1937 | "type": "zip", 1938 | "url": "https://api.github.com/repos/symfony/yaml/zipball/a7095af4b97a0955f85c8989106c249fa649011f", 1939 | "reference": "a7095af4b97a0955f85c8989106c249fa649011f", 1940 | "shasum": "" 1941 | }, 1942 | "require": { 1943 | "php": ">=5.5.9" 1944 | }, 1945 | "require-dev": { 1946 | "symfony/console": "~2.8|~3.0" 1947 | }, 1948 | "suggest": { 1949 | "symfony/console": "For validating YAML files using the lint command" 1950 | }, 1951 | "type": "library", 1952 | "extra": { 1953 | "branch-alias": { 1954 | "dev-master": "3.2-dev" 1955 | } 1956 | }, 1957 | "autoload": { 1958 | "psr-4": { 1959 | "Symfony\\Component\\Yaml\\": "" 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 Yaml Component", 1980 | "homepage": "https://symfony.com", 1981 | "time": "2016-12-10T10:07:06+00:00" 1982 | }, 1983 | { 1984 | "name": "webmozart/assert", 1985 | "version": "1.2.0", 1986 | "source": { 1987 | "type": "git", 1988 | "url": "https://github.com/webmozart/assert.git", 1989 | "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f" 1990 | }, 1991 | "dist": { 1992 | "type": "zip", 1993 | "url": "https://api.github.com/repos/webmozart/assert/zipball/2db61e59ff05fe5126d152bd0655c9ea113e550f", 1994 | "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f", 1995 | "shasum": "" 1996 | }, 1997 | "require": { 1998 | "php": "^5.3.3 || ^7.0" 1999 | }, 2000 | "require-dev": { 2001 | "phpunit/phpunit": "^4.6", 2002 | "sebastian/version": "^1.0.1" 2003 | }, 2004 | "type": "library", 2005 | "extra": { 2006 | "branch-alias": { 2007 | "dev-master": "1.3-dev" 2008 | } 2009 | }, 2010 | "autoload": { 2011 | "psr-4": { 2012 | "Webmozart\\Assert\\": "src/" 2013 | } 2014 | }, 2015 | "notification-url": "https://packagist.org/downloads/", 2016 | "license": [ 2017 | "MIT" 2018 | ], 2019 | "authors": [ 2020 | { 2021 | "name": "Bernhard Schussek", 2022 | "email": "bschussek@gmail.com" 2023 | } 2024 | ], 2025 | "description": "Assertions to validate method input/output with nice error messages.", 2026 | "keywords": [ 2027 | "assert", 2028 | "check", 2029 | "validate" 2030 | ], 2031 | "time": "2016-11-23T20:04:58+00:00" 2032 | } 2033 | ], 2034 | "aliases": [], 2035 | "minimum-stability": "stable", 2036 | "stability-flags": [], 2037 | "prefer-stable": false, 2038 | "prefer-lowest": false, 2039 | "platform": { 2040 | "php": ">=5.6.0" 2041 | }, 2042 | "platform-dev": [] 2043 | } 2044 | --------------------------------------------------------------------------------